commit 4b55de3e425ee89f8d944a5c7ce2c86d7163a188 Author: Brian McBee Date: Sun Aug 19 18:27:09 2007 +0000 Creating branch for Physics development diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt new file mode 100644 index 0000000000..a8f5c66f81 --- /dev/null +++ b/CONTRIBUTORS.txt @@ -0,0 +1,44 @@ + +The following people have contributed to OpenSim (Thankyou for your effort!) +Add your name in here if you have committed to OpenSim + +OpenSim Developers + +* MW +* Adam Frisby (DeepThink Pty Ltd) +* MingChen (DeepThink Pty Ltd) +* lbsa71 +* sdague (International Business Machines Corp.) +* Andy- +* Gareth +* MorphW +* CW +* Babblefrog +* Tedd + +Patches + +* BigFootAg +* Danx0r +* Dalien +* Darok + +Testers + +* Ckrinke + + +This software uses components from the following developers: +* Sleepycat Software (Berkeley DB) +* DB4objects, Inc. (DB4o) +* SQLite (Public Domain) +* XmlRpcCS (http://xmlrpccs.sf.net/) +* MySQL, Inc. (MySQL Connector/NET) +* AGEIA Inc. (PhysX) +* Russel L. Smith (ODE) +* Prebuild ( http://sourceforge.net/projects/dnpb/ ) + +In addition, we would like to thank: +* The Mono Project +* The NANT Developers +* Microsoft (.NET, MSSQL-Adapters) \ No newline at end of file diff --git a/OpenSim.FxCop b/OpenSim.FxCop new file mode 100644 index 0000000000..1e2ea2d798 --- /dev/null +++ b/OpenSim.FxCop @@ -0,0 +1,7241 @@ + + + + True + http://www.gotdotnet.com/team/fxcop//xsl/1.35/FxCopReport.xsl + + + + + + True + True + True + 10 + 1 + + False + False + + False + 120 + + + + $(ProjectDir)/lib/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sim + OpenSim + + + + + + + + + Sim + OpenSim.Assets + + + + + + + + + OpenSim.CAPS + + + + + Sim + OpenSim.CAPS + + + + + OpenSim.CAPS + + + + + + + + + Sim + OpenSim.Config.SimConfigDb4o + + + Sim + OpenSim.Config.SimConfigDb4o + + + + + + + + + OpenSim.Framework.Assets + + + + + Sim + OpenSim.Framework.Assets + + + + + + + + + Sim + OpenSim.Framework.Console + + + + + + + + + OpenSim.Framework.Grid + + + + + Sim + OpenSim.Framework.Grid + + + + + + + + + Sim + OpenSim.Framework.Interfaces + + + + + + + + + OpenSim.Framework.Inventory + + + + + Sim + OpenSim.Framework.Inventory + + + + + + + + + OpenSim.Framework.Sims + + + + + Sim + OpenSim.Framework.Sims + + + + + + + + + OpenSim.Framework.Terrain + + + + + Sim + OpenSim.Framework.Terrain + + + + + + + + + OpenSim.Framework.User + + + + + Sim + OpenSim.Framework.User + + + + + + + + + OpenSim.Framework.Utilities + + + + + Sim + OpenSim.Framework.Utilities + + + + + + + + + Sim + OpenSim.GridInterfaces.Local + + + + + + + + + OpenSim.GridInterfaces.Remote + + + + + Sim + OpenSim.GridInterfaces.Remote + + + + + + + + + Plugin + OpenSim.Physics.BasicPhysicsPlugin + + + + + Sim + OpenSim.Physics.BasicPhysicsPlugin + + + + + + + + + Sim + OpenSim.Physics.Manager + + + + + + + + + OpenSim.Physics.OdePlugin + + + + + Plugin + OpenSim.Physics.OdePlugin + + + + + Sim + OpenSim.Physics.OdePlugin + + + + + + + + + OpenSim.Physics.PhysXPlugin + + + + + Plugin + OpenSim.Physics.PhysXPlugin + + + + + Sim + OpenSim.Physics.PhysXPlugin + + + + + + + + + Sim + OpenSim.Storage.LocalStorageDb4o + + + + + + + + + OpenSim.types + + + + + OpenSim.types + + + + + Sim + OpenSim.types + + + + + + + + + OpenSim.UserServer + + + + + Sim + OpenSim.UserServer + + + + + + + + + OpenSim.world + + + + + Sim + OpenSim.world + + + + + + + + + OpenSim.world.scripting + + + + + OpenSim.world.scripting + + + OpenSim.world.scripting + + + + + Sim + OpenSim.world.scripting + + + + + + + + + + + + + OpenGridServices.ServerConsole + + + + + OpenGridServices.ServerConsole + + + + + OpenGridServices.ServerConsole + + + + + + + + + + + conscmd_callback + + + + + conscmd + ServerConsole.conscmd_callback + + + + + conscmd_callback + + + + + + + + + conscmd_callback.RunCmd(String, String[]):Void + cmdparams + cmdparams + + + + + + + + + ShowWhat + + + + + + + + + + + + + ConsoleBase.CmdPrompt(String, String):String + defaultresponse + defaultresponse + + + + + + + + + OptionA + + + + + OptionB + + + + + ConsoleBase.CmdPrompt(String, String, String, String):String + defaultresponse + defaultresponse + + + + + + + + + Passwd + ConsoleBase.PasswdPrompt(String):String + + + + + + + + + Cmd + + + + + ConsoleBase.RunCmd(String, String[]):Object + cmdparams + cmdparams + + + + + + + + + ShowWhat + + + + + + + + + Line + + + + + + + + + Line + + + + + + + + + + + + + Sim + ConsoleType.SimChat + + + + + + + + + ConsoleType.TCP + + + + + + + + + + + MainConsole + + + + + + + + + + + + + + + + + OpenSim.Config.SimConfigDb4o + + + + + OpenSim.Config.SimConfigDb4o + + + + + OpenSim.Config.SimConfigDb4o + + + + + + + + + + + Plugin + OpenSim.Config.SimConfigDb4o.Db40ConfigPlugin + + + + + + + + + Sim + OpenSim.Config.SimConfigDb4o.DbSimConfig + + + + + Db + OpenSim.Config.SimConfigDb4o.DbSimConfig + + + + + + + + + DbSimConfig.InitConfig(Boolean):Void + System.Exception + + + + + DbSimConfig.InitConfig(Boolean):Void + System.UInt32.ToString + System.UInt32.ToString(System.IFormatProvider) + + + + + DbSimConfig.InitConfig(Boolean):Void + System.UInt64.ToString + System.UInt64.ToString(System.IFormatProvider) + + + + + + + + + DbSimConfig.LoadDefaults():Void + System.Convert.ToInt32(System.String) + System.Convert.ToInt32(System.String,System.IFormatProvider) + + + DbSimConfig.LoadDefaults():Void + System.Convert.ToInt32(System.String) + System.Convert.ToInt32(System.String,System.IFormatProvider) + + + DbSimConfig.LoadDefaults():Void + System.Convert.ToInt32(System.String) + System.Convert.ToInt32(System.String,System.IFormatProvider) + + + + + + + + + + + + + Map + + + + + + + + + + + + + + + + + + + OpenSim + + + + + OpenSim + + + + + OpenSim + + + + + OpenSim + + + + + OpenSim + + + + + + + + + + + + + 'args' + RegionServer.Main(String[]):Void + + + 'args' + RegionServer.Main(String[]):Void + + + + + + + + + + + + + + + + + + + OpenSim.Framework.Console + + + + + OpenSim.Framework.Console + + + + + OpenSim.Framework.Console + + + + + + + + + + + + + ConsoleBase.CmdPrompt(String, String):String + defaultresponse + defaultresponse + + + + + + + + + OptionA + + + + + OptionB + + + + + ConsoleBase.CmdPrompt(String, String, String, String):String + defaultresponse + defaultresponse + + + + + + + + + Cmd + + + + + ConsoleBase.RunCmd(String, String[]):Object + cmdparams + cmdparams + + + + + + + + + ShowWhat + + + + + + + + + + + + + Sim + ConsoleType.SimChat + + + + + + + + + ConsoleType.TCP + + + + + + + + + + + MainConsole + + + + + + + + + + + + + + + + + OpenSim.Framework + + + + + OpenSim.Framework + + + + + OpenSim.Framework + + + + + + + + + + + + + Data + + + + + + + + + Description + + + + + + + + + FullID + + + + + + + + + InvType + + + + + + + + + Name + + + + + + + + + Type + + + + + + + + + + + + + PrimData.PrimData() + ParentID + System.UInt32 + 0 + + + + + + + + + FullID + + + + + + + + + LocalID + + + + + + + + + OwnerID + + + + + + + + + ParentID + + + + + + + + + PathBegin + + + + + + + + + PathCurve + + + + + + + + + PathEnd + + + + + + + + + PathRadiusOffset + + + + + + + + + PathRevolutions + + + + + + + + + PathScaleX + + + + + + + + + PathScaleY + + + + + + + + + PathShearX + + + + + + + + + PathShearY + + + + + + + + + PathSkew + + + + + + + + + PathTaperX + + + + + + + + + PathTaperY + + + + + + + + + PathTwist + + + + + + + + + PathTwistBegin + + + + + + + + + PCode + + + + + + + + + Position + + + + + + + + + ProfileBegin + + + + + + + + + ProfileCurve + + + + + + + + + ProfileEnd + + + + + + + + + ProfileHollow + + + + + + + + + Rotation + + + + + + + + + Scale + + + + + + + + + Texture + + + + + + + + + + + + + + + Login + LoginService + LogOn + + + + + + + + + + + + + + + AgentID + + + + + + + + + circuitcode + + + + + circuitcode + AgentCircuitData.circuitcode + + + + + + + + + firstname + + + + + firstname + AgentCircuitData.firstname + + + + + + + + + lastname + + + + + lastname + AgentCircuitData.lastname + + + + + + + + + SecureSessionID + + + + + + + + + SessionID + + + + + + + + + + + OpenSim.Framework.Interfaces.ARequest + + + OpenSim.Framework.Interfaces.ARequest + + + + + + + + + AssetID + + + + + + + + + IsTexture + + + + + + + + + + + + + Authorised + + + + + Authorised + AuthenticateResponse.Authorised + + + + + + + + + LoginInfo + + + + + Login + LoginInfo + LogOn + + + + + + + + + + + Plugin + OpenSim.Framework.Interfaces.IAssetPlugin + + + + + + + + + GetAssetServer + + + + + + + + + + + + + IsTexture + + + + + + + + + + + + + ID + assetID + Id + + + + + + + + + ServerUrl + + + + + ServerKey + + + + + ServerUrl + IAssetServer.SetServerInfo(String, String):Void + + + + + + + + + + + Plugin + OpenSim.Framework.Interfaces.IGridPlugin + + + + + + + + + GetGridServer + + + + + + + + + + + + + ID + sessionID + Id + + + + + ID + agentID + Id + + + + + + + + + GetName + + + + + + + + + ID + sessionID + Id + + + + + ID + agentID + Id + + + + + Logout + LogoutSession + LogOff + + + + + + + + + Neighbours + IGridServer.RequestNeighbours():NeighbourInfo[] + + + + + + + + + IGridServer.RequestUUIDBlock():UUIDBlock + + + + + + + + + ServerUrl + + + + + SendKey + + + + + RecvKey + + + + + IGridServer.SetServerInfo(String, String, String):Void + Recv + RecvKey + + + + + ServerUrl + IGridServer.SetServerInfo(String, String, String):Void + + + + + + + + + + + + + ID + primID + Id + + + + + + + + + ShutDown + method + ShutDown + Shutdown + + + + + + + + + + + Sim + OpenSim.Framework.Interfaces.ISimConfig + + + + + + + + + GetConfigObject + + + + + + + + + + + + + ID + agentID + Id + + + + + + + + + ServerUrl + + + + + SendKey + + + + + RecvKey + + + + + IUserServer.SetServerInfo(String, String, String):Void + Recv + RecvKey + + + + + ServerUrl + IUserServer.SetServerInfo(String, String, String):Void + + + + + + + + + + + + + Logout + LogoutSession + LogOff + + + + + + + + + + + Login + Login + LogOn + + + + + + + + + Agent + + + + + + + + + BaseFolder + + + + + + + + + First + + + + + + + + + InventoryFolder + + + + + + + + + Last + + + + + + + + + SecureSession + + + + + + + + + Session + + + + + + + + + + + Neighbour + OpenSim.Framework.Interfaces.NeighbourInfo + + + + + + + + + regionhandle + + + + + regionhandle + NeighbourInfo.regionhandle + + + + + + + + + RegionLocX + + + + + + + + + RegionLocY + + + + + + + + + sim_ip + + + + + sim + NeighbourInfo.sim_ip + + + + + sim_ip + + + + + + + + + sim_port + + + + + sim + NeighbourInfo.sim_port + + + + + sim_port + + + + + + + + + + + + + agentcircuits + + + + + agentcircuits + + + + + agentcircuits + RemoteGridBase.agentcircuits:Dictionary`2<System.UInt32,OpenSim.Framework.Interfaces.AgentCircuitData> + + + + + + + + + Logout + LogoutSession + LogOff + + + + + + + + + + + Sim + OpenSim.Framework.Interfaces.SimConfig + + + + + + + + + AssetSendKey + + + + + + + + + AssetURL + + + + + + + + + GridRecvKey + + + + + Recv + SimConfig.GridRecvKey + + + + + + + + + GridSendKey + + + + + + + + + GridURL + + + + + + + + + IPListenAddr + + + + + Addr + SimConfig.IPListenAddr + + + + + + + + + IPListenPort + + + + + + + + + RegionHandle + + + + + + + + + RegionLocX + + + + + + + + + RegionLocY + + + + + + + + + RegionName + + + + + + + + + SimConfig.SaveMap(Single[]):Void + heightmap + heightmap + + + + + + + + + UserRecvKey + + + + + Recv + SimConfig.UserRecvKey + + + + + + + + + UserSendKey + + + + + + + + + UserURL + + + + + + + + + + + UUIDBlock + + + + + OpenSim.Framework.Interfaces.UUIDBlock + + + OpenSim.Framework.Interfaces.UUIDBlock + + + + + + + + + BlockEnd + + + + + + + + + BlockStart + + + + + + + + + + + + + + + + + AgentInventory.AgentInventory() + AgentInventory.AgentInventory() AgentInventory.Initialise():Void + + + + + + + + + ID + folderID + Id + + + + + + + + + AgentID + + + + + + + + + ID + folderID + Id + + + + + + + + + Initialise + AgentInventory.Initialise():Void + + + + + + + + + InventoryFolders + + + + + + + + + InventoryItems + + + + + + + + + InventoryRoot + + + + + + + + + LastCached + + + + + + + + + ID + itemID + Id + + + + + + + + + Wearables + + + + + Wearables + AgentInventory.Wearables + + + + + + + + + + + + + AssetID + + + + + + + + + ItemID + + + + + + + + + + + + + DefaultType + + + + + + + + + FolderID + + + + + + + + + FolderName + + + + + + + + + Items + + + + + System.Collections.Generic.List`1<OpenSim.Framework.Inventory.InventoryItem> + InventoryFolder.Items + + + + + + + + + OwnerID + + + + + + + + + ParentID + + + + + + + + + Version + + + + + + + + + + + + + AssetID + + + + + + + + + CreatorID + + + + + + + + + Description + + + + + + + + + FolderID + + + + + + + + + InvType + + + + + + + + + ItemID + + + + + + + + + Name + + + + + + + + + OwnerID + + + + + + + + + Type + + + + + + + + + + + + + + + Sim + OpenSim.Framework.Sims.SimProfile + + + + + + + + + SimProfile.LoadFromGrid(UInt64, String, String, String):SimProfile + System.Exception + + + + + GridURL + + + + + SendKey + + + + + RecvKey + + + + + SimProfile.LoadFromGrid(UInt64, String, String, String):SimProfile + Recv + RecvKey + + + + + region_handle + + + + + GridURL + + + + + RecvKey + SimProfile.LoadFromGrid(UInt64, String, String, String):SimProfile + + + + + SimProfile.LoadFromGrid(UInt64, String, String, String):SimProfile + System.Convert.ToUInt16(System.Object) + System.Convert.ToUInt16(System.Object,System.IFormatProvider) + + + + + SimProfile.LoadFromGrid(UInt64, String, String, String):SimProfile + System.Convert.ToUInt32(System.Object) + System.Convert.ToUInt32(System.Object,System.IFormatProvider) + + + SimProfile.LoadFromGrid(UInt64, String, String, String):SimProfile + System.Convert.ToUInt32(System.Object) + System.Convert.ToUInt32(System.Object,System.IFormatProvider) + + + + + SimProfile.LoadFromGrid(UInt64, String, String, String):SimProfile + System.Convert.ToUInt64(System.Object) + System.Convert.ToUInt64(System.Object,System.IFormatProvider) + + + + + SimProfile.LoadFromGrid(UInt64, String, String, String):SimProfile + System.UInt64.ToString + System.UInt64.ToString(System.IFormatProvider) + + + + + + + + + + + Sim + OpenSim.Framework.Sims.SimProfileBase + + + + + + + + + caps_url + + + + + caps_url + + + + + + + + + recvkey + + + + + recvkey + SimProfileBase.recvkey + + + + + + + + + regionhandle + + + + + regionhandle + SimProfileBase.regionhandle + + + + + + + + + RegionLocX + + + + + + + + + RegionLocY + + + + + + + + + regionname + + + + + regionname + SimProfileBase.regionname + + + + + + + + + sendkey + + + + + sendkey + SimProfileBase.sendkey + + + + + + + + + sim_ip + + + + + sim + SimProfileBase.sim_ip + + + + + sim_ip + + + + + + + + + sim_port + + + + + sim + SimProfileBase.sim_port + + + + + sim_port + + + + + + + + + UUID + + + + + + + + + + + + + + + Heightmap + OpenSim.Framework.Terrain.HeightmapGenHills + + + + + + + + + HeightmapGenHills.GenerateHeightmap(Int32, Single, Single, Boolean):Single[] + num + numHills + + + + + Heightmap + HeightmapGenHills.GenerateHeightmap(Int32, Single, Single, Boolean):Single[] + + + + + + + + + HeightmapGenHills.NumHills + + + + + + + + + + + + + + + + + UserProfile.UserProfile() + IsGridGod + System.Boolean + false + + + + + + + + + Sim + UserProfile.AddSimCircuit(UInt32, LLUUID):Void + + + + + regionUUID + + + + + + + + + AssetURL + + + + + + + + + Circuits + + + + + + + + + CurrentSecureSessionID + + + + + + + + + CurrentSessionID + + + + + + + + + firstname + + + + + firstname + UserProfile.firstname + + + + + + + + + homelookat + + + + + homelookat + UserProfile.homelookat + + + + + + + + + homepos + + + + + homepos + UserProfile.homepos + + + + + + + + + homeregionhandle + + + + + homeregionhandle + UserProfile.homeregionhandle + + + + + + + + + Inventory + + + + + + + + + IsGridGod + + + + + + + + + IsLocal + + + + + + + + + lastname + + + + + lastname + UserProfile.lastname + + + + + + + + + MD5passwd + + + + + + + + + UUID + + + + + + + + + + + + + response + + + + + Customise + UserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void + + + + + UserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void + GridResp + Nwc.XmlRpc.XmlRpcResponse + + + + + UserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void + System.Single.ToString + System.Single.ToString(System.IFormatProvider) + + + UserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void + System.Single.ToString + System.Single.ToString(System.IFormatProvider) + + + UserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void + System.Single.ToString + System.Single.ToString(System.IFormatProvider) + + + UserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void + System.Single.ToString + System.Single.ToString(System.IFormatProvider) + + + UserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void + System.Single.ToString + System.Single.ToString(System.IFormatProvider) + + + UserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void + System.Single.ToString + System.Single.ToString(System.IFormatProvider) + + + + + UserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void + System.UInt32.ToString + System.UInt32.ToString(System.IFormatProvider) + + + UserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void + System.UInt32.ToString + System.UInt32.ToString(System.IFormatProvider) + + + + + + + + + DefaultStartupMsg + + + + + + + + + GridRecvKey + + + + + Recv + UserProfileManager.GridRecvKey + + + + + + + + + GridSendKey + + + + + + + + + GridURL + + + + + + + + + UserProfileManager.ParseXMLRPC(String):String + System.Exception + + + + + UserProfileManager.ParseXMLRPC(String):String + + + + + UserProfileManager.ParseXMLRPC(String):String + System.Int32.ToString + System.Int32.ToString(System.IFormatProvider) + + + UserProfileManager.ParseXMLRPC(String):String + System.Int32.ToString + System.Int32.ToString(System.IFormatProvider) + + + + + UserProfileManager.ParseXMLRPC(String):String + System.Single.ToString + System.Single.ToString(System.IFormatProvider) + + + UserProfileManager.ParseXMLRPC(String):String + System.Single.ToString + System.Single.ToString(System.IFormatProvider) + + + UserProfileManager.ParseXMLRPC(String):String + System.Single.ToString + System.Single.ToString(System.IFormatProvider) + + + UserProfileManager.ParseXMLRPC(String):String + System.Single.ToString + System.Single.ToString(System.IFormatProvider) + + + UserProfileManager.ParseXMLRPC(String):String + System.Single.ToString + System.Single.ToString(System.IFormatProvider) + + + UserProfileManager.ParseXMLRPC(String):String + System.Single.ToString + System.Single.ToString(System.IFormatProvider) + + + UserProfileManager.ParseXMLRPC(String):String + System.Single.ToString + System.Single.ToString(System.IFormatProvider) + + + UserProfileManager.ParseXMLRPC(String):String + System.Single.ToString + System.Single.ToString(System.IFormatProvider) + + + UserProfileManager.ParseXMLRPC(String):String + System.Single.ToString + System.Single.ToString(System.IFormatProvider) + + + + + + + + + UserProfileManager.SetKeys(String, String, String, String):Void + recv + recvKey + + + + + url + UserProfileManager.SetKeys(String, String, String, String):Void + + + + + + + + + + + + + UserProfileManagerBase.AuthenticateUser(String, String, String):Boolean + firstname + firstname + + + + + UserProfileManagerBase.AuthenticateUser(String, String, String):Boolean + lastname + lastname + + + + + UserProfileManagerBase.AuthenticateUser(String, String, String):Boolean + passwd + passwd + + + + + + + + + MD5passwd + + + + + UserProfileManagerBase.CreateNewProfile(String, String, String):UserProfile + firstname + firstname + + + + + UserProfileManagerBase.CreateNewProfile(String, String, String):UserProfile + lastname + lastname + + + + + UserProfileManagerBase.CreateNewProfile(String, String, String):UserProfile + M + MD5passwd + + + + + + + + + ProfileLLUUID + + + + + ProfileLLUUID + + + + + UserProfileManagerBase.GetProfileByLLUUID(LLUUID):UserProfile + + + + + + + + + UserProfileManagerBase.GetProfileByName(String, String):UserProfile + firstname + firstname + + + + + UserProfileManagerBase.GetProfileByName(String, String):UserProfile + lastname + lastname + + + + + + + + + ID + agentID + Id + + + + + + + + + GodID + + + + + ID + GodID + Id + + + + + + + + + UserProfiles + + + + + + + + + + + + + + + OpenSim.Framework.Utilities.BlockingQueue`1 + Queue + + + + + + + + + Util + OpenSim.Framework.Utilities.Util + + + + + Util + + + + + Util + System.Web.Util + + + + + + + + + Xfer + Util.GetNextXferID():UInt32 + + + + + Util.GetNextXferID():UInt32 + + + + + GetNextXferID + + + + + + + + + X + + + + + Y + + + + + Util.UIntsToLong(UInt32, UInt32):UInt64 + X + + + + + Util.UIntsToLong(UInt32, UInt32):UInt64 + Y + + + + + Ints + Util.UIntsToLong(UInt32, UInt32):UInt64 + + + + + + + + + + + + + + + + + + + OpenSim.GridInterfaces.Local + + + + + OpenSim.GridInterfaces.Local + + + + + OpenSim.GridInterfaces.Local + + + + + + + + + + + + + Data + + + + + + + + + Name + + + + + + + + + Type + + + + + + + + + UUID + + + + + + + + + + + AssetUUIDQuery + + + + + + + + + 'asset' + AssetUUIDQuery.Match(AssetStorage):Boolean + + + + + + + + + + + Plugin + OpenSim.GridInterfaces.Local.LocalAssetPlugin + + + + + + + + + + + LocalAssetServer.LocalAssetServer() + System.Exception + + + + + + + + + LocalAssetServer.LoadAsset(AssetBase, Boolean, String):Void + + + + + image + LocalAssetServer.LoadAsset(AssetBase, Boolean, String):Void + + + + + + + + + 'asset' + LocalAssetServer.UploadNewAsset(AssetBase):Void + + + + + + + + + + + Plugin + OpenSim.GridInterfaces.Local.LocalGridPlugin + + + + + + + + + + + Logout + LogoutSession + LogOff + + + + + + + + + Sessions + + + + + System.Collections.Generic.List`1<OpenSim.Framework.Interfaces.Login> + LocalGridServer.Sessions + + + + + + + + + + + + + + + + + + + OpenSim.GridInterfaces.Remote + + + + + OpenSim.GridInterfaces.Remote + + + + + OpenSim.GridInterfaces.Remote + + + + + + + + + + + Plugin + OpenSim.GridInterfaces.Remote.RemoteAssetPlugin + + + + + + + + + Plugin + OpenSim.GridInterfaces.Remote.RemoteGridPlugin + + + + + + + + + + + agentcircuits + + + + + + + + + circuitcode + RemoteGridServer.AuthenticateSession(LLUUID, LLUUID, UInt32):AuthenticateResponse + circuitCode + IGridServer.AuthenticateSession(LLUUID, LLUUID, UInt32):AuthenticateResponse + + + + + + + + + RemoteGridServer.GridRecvKey + + + + + + + + + RemoteGridServer.GridSendKey + + + + + + + + + RemoteGridServer.LogoutSession(LLUUID, LLUUID, UInt32):Boolean + WebRequest.Create(Uri):WebRequest + WebRequest.Create(String):WebRequest + + + + + RemoteGridServer.LogoutSession(LLUUID, LLUUID, UInt32):Boolean + GridResponse + System.String + + + + + Logout + LogoutSession + LogOff + + + + + 'sessionID' + RemoteGridServer.LogoutSession(LLUUID, LLUUID, UInt32):Boolean + + + + + + + + + + + + + + + + + + + OpenSim.Physics.Manager + + + + + OpenSim.Physics.Manager + + + + + OpenSim.Physics.Manager + + + + + + + + + + + Plugin + OpenSim.Physics.Manager.IPhysicsPlugin + + + + + + + + + GetName + + + + + + + + + GetScene + + + + + + + + + + + + + 'heightMap' + NullPhysicsScene.SetTerrain(Single[]):Void + + + + + + + + + NullPhysicsScene.Simulate(Single):Void + System.Int32.ToString + System.Int32.ToString(System.IFormatProvider) + + + + + + + + + + + + + Kinematic + PhysicsActor.Kinematic:Boolean + + + + + + + + + + + + + PhysicsManager.GetPhysicsScene(String):PhysicsScene + System.String.Format(System.String,System.Object) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + Plugins + PhysicsManager.LoadPlugins():Void + + + + + + + + + + + + + PhysicsVector.PhysicsVector(Single, Single, Single) + x + + + + + PhysicsVector.PhysicsVector(Single, Single, Single) + y + + + + + PhysicsVector.PhysicsVector(Single, Single, Single) + z + + + + + + + + + X + + + + + X + PhysicsVector.X + + + + + + + + + Y + + + + + Y + PhysicsVector.Y + + + + + + + + + Z + + + + + Z + PhysicsVector.Z + + + + + + + + + PhysicsVector.Zero + OpenSim.Physics.Manager.PhysicsVector + + + + + + + + + + + + + + + + + + + OpenSim.RegionServer + + + + + OpenSim.RegionServer + + + + + OpenSim.RegionServer + + + + + OpenSim.RegionServer + + + + + OpenSim.RegionServer + + + + + + + + + + + + + ID + transactionID + Id + + + + + + + + + ID + transactionID + Id + + + + + + + + + ID + transactionID + Id + + + + + + + + + ID + assetID + Id + + + + + AgentAssetUpload.HandleUploadPacket(AssetUploadRequestPacket, LLUUID):Void + System.Int32.ToString(System.String) + System.Int32.ToString(System.String,System.IFormatProvider) + + + AgentAssetUpload.HandleUploadPacket(AssetUploadRequestPacket, LLUUID):Void + System.Int32.ToString(System.String) + System.Int32.ToString(System.String,System.IFormatProvider) + + + + + 'assetID' + AgentAssetUpload.HandleUploadPacket(AssetUploadRequestPacket, LLUUID):Void + + + 'pack' + AgentAssetUpload.HandleUploadPacket(AssetUploadRequestPacket, LLUUID):Void + + + + + + + + + AgentAssetUpload.HandleXferPacket(SendXferPacketPacket):Void + xfer + xferPacket + + + + + Xfer + AgentAssetUpload.HandleXferPacket(SendXferPacketPacket):Void + + + + + + + + + + + + + AssetTransaction.AssetTransaction() + UploadComplete + System.Boolean + false + + + + + + + + + AddToInventory + + + + + + + + + Asset + + + + + + + + + InventFolder + + + + + + + + + TransactionID + + + + + + + + + UploadComplete + + + + + + + + + XferID + + + + + Xfer + AssetTransaction.XferID + + + + + + + + + + + Grid + OpenSim.Framework.Grid + + + + + + + + + AssetDll + + + + + + + + + AssetServer + + + + + + + + + GridDll + + + + + + + + + GridServer + + + + + + + + + Initialise + Grid.Initialise():Void + + + + + + + + + Grid.LoadAssetDll(String):IAssetServer + + + + + + + + + Grid.LoadGridDll(String):IGridServer + + + + + + + + + + + Sim + OpenSim.OpenSimApplication + + + + + + + + + OpenSimApplication.RemoveClientCircuit(UInt32):Void + circuitcode + circuitcode + + + + + + + + + OpenSimApplication.SendPacketTo(Byte[], Int32, SocketFlags, UInt32):Void + circuitcode + circuitcode + + + + + + + + + StartUp + method + StartUp + Startup + + + + + + + + + + + Sim + OpenSim.OpenSimMain + + + + + OpenSim.OpenSimMain + System.Timers.Timer, System.Net.Sockets.Socket + + + + + + + + + OpenSimMain.OpenSimMain() + loginserver + System.Boolean + false + + + OpenSimMain.OpenSimMain() + sandbox + System.Boolean + false + + + + + + + + + _physicsEngine + + + + + _physicsEngine + + + + + + + + + OpenSimMain.LoadConfigDll(String):SimConfig + + + + + + + + + loginserver + + + + + loginserver + OpenSimMain.loginserver + + + + + + + + + sandbox + + + + + + + + + Server + + + + + + + + + Timer.set_Interval(Double):Void + OpenSimMain.StartUp():Void + + + + + OpenSimMain.StartUp():Void + System.UInt32.ToString + System.UInt32.ToString(System.IFormatProvider) + + + OpenSimMain.StartUp():Void + System.UInt32.ToString + System.UInt32.ToString(System.IFormatProvider) + + + + + + + + + + + Sim + OpenSim.OpenSimRoot + + + + + + + + + OpenSimRoot.OpenSimRoot() + Sandbox + System.Boolean + false + + + + + + + + + Application + + + + + + + + + AssetCache + + + + + + + + + Cfg + + + + + Cfg + OpenSimRoot.Cfg + + + + + + + + + ClientThreads + + + + + + + + + GridServers + + + + + + + + + HttpServer + + + + + + + + + InventoryCache + + + + + + + + + LocalWorld + + + + + + + + + Sandbox + + + + + + + + + StartUp + method + StartUp + Startup + + + + + + + + + startuptime + + + + + startuptime + OpenSimRoot.startuptime + + + + + + + + + + + Que + OpenSim.QueItem + + + + + + + + + Incoming + + + + + + + + + Packet + + + + + + + + + + + Sim + OpenSim.SimClient + + + + + OpenSim.SimClient + System.Timers.Timer + + + + + + + + + SimClient.SimClient(EndPoint, UseCircuitCodePacket) + Sequence + System.UInt32 + 0 + + + SimClient.SimClient(EndPoint, UseCircuitCodePacket) + debug + System.Boolean + false + + + + + Timer.Timer(Double) + SimClient.SimClient(EndPoint, UseCircuitCodePacket) + + + + + SimClient.SimClient(EndPoint, UseCircuitCodePacket) + initialcirpack + initialcirpack + + + + + + + + + AgentID + + + + + + + + + CircuitCode + + + + + + + + + ClientAvatar + + + + + + + + + NewPack + + + + + + + + + SimClient.newAssetFolder + + + + + + + + + NewPack + + + + + + + + + Pack + + + + + SimClient.ProcessInPacket(Packet):Void + wear + libsecondlife.Packets.AgentIsNowWearingPacket + + + + + op_Equality + "" + SimClient.ProcessInPacket(Packet):Void + + + + + + + + + SimClient.ProcessOutPacket(Packet):Void + System.Exception + + + + + Pack + + + + + + + + + SecureSessionID + + + + + + + + + SessionID + + + + + + + + + userEP + + + + + + + + + + + OpenSim.SimConsole + OpenSim.Framework.Console.ConsoleBase + + + + + Sim + OpenSim.SimConsole + + + + + + + + + SimConsole.SimConsole(ConsoleType, String, Int32) + constype + constype + + + + + SimConsole.SimConsole(ConsoleType, String, Int32) + sparam + sparam + + + + + SimConsole.SimConsole(ConsoleType, String, Int32) + iparam + iparam + + + + + iparam + SimConsole.SimConsole(ConsoleType, String, Int32) + + + + + sparam + SimConsole.SimConsole(ConsoleType, String, Int32) + + + + + + + + + op_Equality + "" + SimConsole.CmdPrompt(String, String):String + + + + + + + + + SimConsole.ConsType + + + + + + + + + SimConsole.MainConsolePrompt():Void + System.UInt64.ToString + System.UInt64.ToString(System.IFormatProvider) + + + + + + + + + 'cmdparams' + SimConsole.RunCmd(String, String[]):Object + + + + + + + + + SimConsole.ShowCommands(String):Void + System.String.Format(System.String,System.Object[]) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + SimConsole.ShowCommands(String):Void + System.String.Format(System.String,System.Object[]) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + + + + + Version + + + + + + + + + + + + + + + + + ID + imageID + Id + + + + + + + + + AssetRequests + + + + + System.Collections.Generic.List`1<OpenSim.Assets.AssetRequest> + AssetCache.AssetRequests + + + + + + + + + Assets + + + + + + + + + sourceAsset + AssetCache.CloneAsset(LLUUID, AssetInfo):AssetInfo + OpenSim.Assets.AssetInfo + OpenSim.Framework.Assets.AssetBase + + + + + AssetCache.CloneAsset(LLUUID, AssetInfo):AssetInfo + + + + + newOwner + AssetCache.CloneAsset(LLUUID, AssetInfo):AssetInfo + + + + + 'sourceAsset' + AssetCache.CloneAsset(LLUUID, AssetInfo):AssetInfo + + + + + + + + + source + AssetCache.CloneImage(LLUUID, TextureImage):TextureImage + OpenSim.Assets.TextureImage + OpenSim.Framework.Assets.AssetBase + + + + + AssetCache.CloneImage(LLUUID, TextureImage):TextureImage + + + + + newOwner + AssetCache.CloneImage(LLUUID, TextureImage):TextureImage + + + + + 'source' + AssetCache.CloneImage(LLUUID, TextureImage):TextureImage + + + + + + + + + ID + agentID + Id + + + + + + + + + ID + assetID + Id + + + + + + + + + RequestedAssets + + + + + + + + + RequestedTextures + + + + + + + + + AssetCache.RunAssetManager():Void + System.Exception + + + + + + + + + TextureRequests + + + + + System.Collections.Generic.List`1<OpenSim.Assets.AssetRequest> + AssetCache.TextureRequests + + + + + + + + + Textures + + + + + + + + + + + OpenSim.Assets.AssetInfo + OpenSim.Framework.Assets.AssetBase + + + + + + + + + AssetInfo.AssetInfo(AssetBase) + a + aBase + + + + + 'aBase' + AssetInfo.AssetInfo(AssetBase) + + + + + + + + + + + + + AssetRequest.AssetRequest() + DataPointer + System.Int64 + 0 + + + AssetRequest.AssetRequest() + NumPackets + System.Int32 + 0 + + + AssetRequest.AssetRequest() + PacketCounter + System.Int32 + 0 + + + + + + + + + AssetInf + + + + + + + + + DataPointer + + + + + + + + + ImageInfo + + + + + + + + + IsTextureRequest + + + + + + + + + NumPackets + + + + + Num + AssetRequest.NumPackets + + + + + + + + + PacketCounter + + + + + + + + + RequestAssetID + + + + + + + + + RequestUser + + + + + + + + + TransferRequestID + + + + + + + + + + + + + ID + folderID + Id + + + + + + + + + ID + clientID + Id + + + + + + + + + ID + folderID + Id + + + + + + + + + ID + folderID + Id + + + + + + + + + FetchItems + + + + + + + + + FetchDescend + + + + + + + + + ID + agentID + Id + + + + + + + + + ID + itemID + Id + + + + + + + + + + + OpenSim.Assets.TextureImage + OpenSim.Framework.Assets.AssetBase + + + + + + + + + TextureImage.TextureImage(AssetBase) + a + aBase + + + + + 'aBase' + TextureImage.TextureImage(AssetBase) + + + + + + + + + + + + + + + Sim + OpenSim.CAPS.SimCAPSHTTPServer + + + + + SimCAPSHTTPServer + + + + + OpenSim.CAPS.SimCAPSHTTPServer + System.Net.HttpListener + + + + + + + + + SimCAPSHTTPServer.HandleRequest(Object):Void + stateinfo + stateinfo + + + + + + + + + HTTPD + + + + + + + + + Listener + + + + + + + + + SimCAPSHTTPServer.LoadAdminPage():Void + System.Exception + + + + + + + + + SimCAPSHTTPServer.ParseLLSDXML(String):String + + + + + requestBody + SimCAPSHTTPServer.ParseLLSDXML(String):String + + + + + + + + + SimCAPSHTTPServer.ParseREST(String, String, String):String + System.Exception + + + + + SimCAPSHTTPServer.ParseREST(String, String, String):String + System.String.Format(System.String,System.Object[]) + System.String.Format(System.IFormatProvider,System.String,System.Object[]) + + + + + + + + + SimCAPSHTTPServer.ParseXMLRPC(String):String + System.Exception + + + + + SimCAPSHTTPServer.ParseXMLRPC(String):String + + + + + SimCAPSHTTPServer.ParseXMLRPC(String):String + System.Convert.ToUInt32(System.Object) + System.Convert.ToUInt32(System.Object,System.IFormatProvider) + + + + + + + + + SimCAPSHTTPServer.StartHTTP():Void + System.Exception + + + + + SimCAPSHTTPServer.StartHTTP():Void + + + + + + + + + + + + + + + + + mesh + + + + + System.Collections.Generic.List`1<OpenSim.types.Triangle> + Mesh.mesh + + + + + + + + + Mesh.op_Addition(Mesh, Mesh):Mesh + a + + + + + Mesh.op_Addition(Mesh, Mesh):Mesh + b + + + + + Add + Mesh.op_Addition(Mesh, Mesh):Mesh + + + + + Mesh + Mesh.op_Addition(Mesh, Mesh):Mesh + + + + + + + + + + + + + A + + + + + B + + + + + C + + + + + Triangle.Triangle(Vector3, Vector3, Vector3) + A + + + + + Triangle.Triangle(Vector3, Vector3, Vector3) + B + + + + + Triangle.Triangle(Vector3, Vector3, Vector3) + C + + + + + + + + + + + + + + + + + LocalUserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void + System.Int32.ToString + System.Int32.ToString(System.IFormatProvider) + + + LocalUserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void + System.Int32.ToString + System.Int32.ToString(System.IFormatProvider) + + + + + LocalUserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void + System.Single.ToString + System.Single.ToString(System.IFormatProvider) + + + LocalUserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void + System.Single.ToString + System.Single.ToString(System.IFormatProvider) + + + LocalUserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void + System.Single.ToString + System.Single.ToString(System.IFormatProvider) + + + LocalUserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void + System.Single.ToString + System.Single.ToString(System.IFormatProvider) + + + LocalUserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void + System.Single.ToString + System.Single.ToString(System.IFormatProvider) + + + LocalUserProfileManager.CustomiseResponse(Hashtable&, UserProfile):Void + System.Single.ToString + System.Single.ToString(System.IFormatProvider) + + + + + + + + + + + OpenSim.UserServer.LoginServer + OpenSim.Framework.Grid.LoginService + + + + + OpenSim.UserServer.LoginServer + System.Net.Sockets.Socket + + + + + Login + LoginServer + LogOn + + + + + + + + + LoginServer.LoginServer(IGridServer) + _needPasswd + System.Boolean + false + + + LoginServer.LoginServer(IGridServer) + userAccounts + System.Boolean + false + + + + + + + + + LoginServer.Authenticate(String, String, String):Boolean + passwd + passwd + + + + + + + + + clientAddress + + + + + + + + + Customise + LoginServer.CustomiseLoginResponse(Hashtable, String, String):Void + + + + + Login + CustomiseLoginResponse + LogOn + + + + + + + + + LoginServer.EncodePassword(String):String + System.String.ToLower + System.String.ToLower(System.Globalization.CultureInfo) + + + + + + + + + LoginServer.GetAgentId(String, String):LLUUID + System.Int32.ToString(System.String) + System.Int32.ToString(System.String,System.IFormatProvider) + + + + + + + + + LoginServer.InitializeLogin():Void + 4 + UserProfileManager.SetKeys(String, String, String, String):Void + Welcome to OpenSim + + + + + Sim + OpenSim + + + + + + + + + LoginServer.LoginRequest(StreamReader, StreamWriter):Void + System.Exception + + + + + LoginServer.LoginRequest(StreamReader, StreamWriter):Void + System.Convert.ToInt32(System.String) + System.Convert.ToInt32(System.String,System.IFormatProvider) + + + + + op_Inequality + "" + LoginServer.LoginRequest(StreamReader, StreamWriter):Void + + + + + + + + + writer + LoginServer.ProcessXmlRequest(XmlRpcRequest, StreamWriter):Boolean + System.IO.StreamWriter + System.IO.TextWriter + + + + + LoginServer.ProcessXmlRequest(XmlRpcRequest, StreamWriter):Boolean + System.Int32.ToString + System.Int32.ToString(System.IFormatProvider) + + + + + LoginServer.ProcessXmlRequest(XmlRpcRequest, StreamWriter):Boolean + System.Int32.ToString(System.String) + System.Int32.ToString(System.String,System.IFormatProvider) + + + + + 'request' + LoginServer.ProcessXmlRequest(XmlRpcRequest, StreamWriter):Boolean + + + 'writer' + LoginServer.ProcessXmlRequest(XmlRpcRequest, StreamWriter):Boolean + + + 'writer' + LoginServer.ProcessXmlRequest(XmlRpcRequest, StreamWriter):Boolean + + + + + + + + + remoteAddress + + + + + + + + + LoginServer.RunLogin():Void + System.Exception + + + LoginServer.RunLogin():Void + System.Exception + + + + + LoginServer.RunLogin():Void + clientEndPoint + System.Net.IPEndPoint + + + + + + + + + + + + + + + + + Avatar.Avatar() + PhysicsEngineFlying + System.Boolean + false + + + + + + + + + Avatar.Avatar(SimClient) + _updateCount + System.Int16 + 0 + + + Avatar.Avatar(SimClient) + avatarAppearanceTexture + libsecondlife.LLObject+TextureEntry + null + + + Avatar.Avatar(SimClient) + movementflag + System.Byte + 0 + + + Avatar.Avatar(SimClient) + updateflag + System.Boolean + false + + + + + TheClient + + + + + + + + + anim_seq + + + + + anim + Avatar.anim_seq + + + + + anim_seq + + + + + + + + + Animations + + + + + + + + + RegionInfo + + + + + RegionInfo + Avatar.CompleteMovement(World):Void + + + + + + + + + ControllingClient + + + + + + + + + current_anim + + + + + anim + Avatar.current_anim + + + + + current_anim + + + + + + + + + firstname + + + + + firstname + Avatar.firstname + + + + + + + + + lastname + + + + + lastname + Avatar.lastname + + + + + + + + + Anims + Avatar.LoadAnims():Void + + + + + + + + + PhysActor + + + + + + + + + PhysicsEngineFlying + + + + + + + + + Anim + Avatar.SendAnimPack():Void + + + + + + + + + 'userInfo' + Avatar.SendAppearanceToOtherAgent(SimClient):Void + + + + + + + + + RegionInfo + + + + + RegionInfo + Avatar.SendRegionHandshake(World):Void + + + + + + + + + + + + + AnimsLLUUID + + + + + Anims + AvatarAnimations.AnimsLLUUID + + + + + + + + + AnimsNames + + + + + Anims + AvatarAnimations.AnimsNames + + + + + + + + + Anims + AvatarAnimations.LoadAnims():Void + + + + + + + + + + + + + Entity.Entity() + localid + System.UInt32 + 0 + + + + + + + + + addForces + + + + + + + + + BackUp + method + BackUp + Backup + + + + + + + + + children + + + + + System.Collections.Generic.List`1<OpenSim.world.Entity> + Entity.children + + + + + + + + + getMesh + + + + + + + + + getName + + + + + + + + + localid + + + + + localid + Entity.localid + + + + + + + + + name + + + + + + + + + position + + + + + + + + + rotation + + + + + + + + + update + + + + + + + + + uuid + + + + + uuid + Entity.uuid + + + + + + + + + velocity + + + + + + + + + + + + + X + + + + + X + NewForce.X + + + + + + + + + Y + + + + + Y + NewForce.Y + + + + + + + + + Z + + + + + Z + NewForce.Z + + + + + + + + + + + 'UpdateFlag' + updateFlag + + + + + + + + + Primitive.Primitive() + dirtyFlag + System.Boolean + false + + + Primitive.Primitive() + mesh_cutbegin + System.Single + 0.0 + + + Primitive.Primitive() + newPrimFlag + System.Boolean + false + + + Primitive.Primitive() + physicsEnabled + System.Boolean + false + + + Primitive.Primitive() + physicstest + System.Boolean + false + + + Primitive.Primitive() + updateFlag + System.Boolean + false + + + + + + + + + localID-702000 + Primitive.CreateFromPacket(ObjectAddPacket, LLUUID, UInt32):Void + + + + + ID + agentID + Id + + + + + ID + localID + Id + + + + + Primitive.CreateFromPacket(ObjectAddPacket, LLUUID, UInt32):Void + System.UInt32.ToString(System.String) + System.UInt32.ToString(System.String,System.IFormatProvider) + + + + + 'addPacket' + Primitive.CreateFromPacket(ObjectAddPacket, LLUUID, UInt32):Void + + + + + + + + + 'store' + Primitive.CreateFromStorage(PrimData):Void + + + + + + + + + dirtyFlag + + + + + + + + + mesh_cutbegin + + + + + cutbegin + Primitive.mesh_cutbegin + + + + + mesh_cutbegin + + + + + + + + + mesh_cutend + + + + + cutend + Primitive.mesh_cutend + + + + + mesh_cutend + + + + + + + + + newPrimFlag + + + + + + + + + PhysActor + + + + + + + + + primData + + + + + + + + + RemoteClient + + + + + 'RemoteClient' + Primitive.UpdateClient(SimClient):Void + + + + + + + + + updateFlag + + + + + + + + + 'pack' + Primitive.UpdateObjectFlags(ObjectFlagUpdatePacket):Void + + + + + + + + + 'addPacket' + Primitive.UpdateShape(ObjectDataBlock):Void + + + + + + + + + + + + + ScriptEngine.ScriptEngine(World) + env + env + + + + + env + ScriptEngine.ScriptEngine(World) + + + + + + + + + ScriptEngine.LoadScript():Void + + + + + + + + + + + + + HeightMap + + + + + + + + + + + World + OpenSim.world + + + + + + + + + World.World() + _localNumber + System.UInt32 + 0 + + + + + + + + + _localNumber + + + + + _localNumber + + + + + + + + + AgentClient + + + + + + + + + AgentClient + + + + + + + + + DeRezPacket + + + + + AgentClient + + + + + World.DeRezObject(DeRezObjectPacket, SimClient):Void + Rez + DeRezPacket + + + + + Rez + World.DeRezObject(DeRezObjectPacket, SimClient):Void + + + + + AgentClient + World.DeRezObject(DeRezObjectPacket, SimClient):Void + + + + + De + World.DeRezObject(DeRezObjectPacket, SimClient):Void + + + + + + + + + Entities + + + + + + + + + RemoteClient + + + + + Prims + World.GetInitialPrims(SimClient):Void + + + + + + + + + LandMap + + + + + + + + + Prims + World.LoadPrimsFromStorage():Void + + + + + + + + + World.LoadStorageDLL(String):Boolean + + + + + + + + + localStorage + + + + + + + + + World.Rand + + + + + + + + + Scripts + + + + + + + + + RemoteClient + + + + + 'RemoteClient' + World.SendLayerData(SimClient):Void + + + 'RemoteClient' + World.SendLayerData(SimClient):Void + + + 'RemoteClient' + World.SendLayerData(SimClient):Void + + + + + + + + + + + + + + + + + IScriptHost.Register(IScript):Boolean + iscript + iscript + + + + + + + + + + + + + + + + + + + OpenSim.Storage.LocalStorageDb4o + + + + + OpenSim.Storage.LocalStorageDb4o + + + + + OpenSim.Storage.LocalStorageDb4o + + + + + + + + + + + + + Db4LocalStorage.Db4LocalStorage() + System.Exception + + + + + + + + + 'receiver' + Db4LocalStorage.LoadPrimitives(ILocalStorageReceiver):Void + + + + + + + + + 'prim' + Db4LocalStorage.StorePrim(PrimData):Void + + + + + + + + + + + UUIDQuery + + + + + + + + + 'prim' + UUIDQuery.Match(PrimData):Boolean + + + + + + + + + + + + + + + + + + + OpenSim.Physics.BasicPhysicsPlugin + + + + + + + + + + OpenSim.Physics.BasicPhysicsPlugin + + + + + + + + + + OpenSim.Physics.BasicPhysicsPlugin + + + + + + + + + + + + + + + + + + BasicActor.flying + + + + + + + + + BasicActor.SetAcceleration(PhysicsVector):Void + accel + accel + + + + + + + + + + + Plugin + OpenSim.Physics.BasicPhysicsPlugin.BasicPhysicsPlugin + + + + + BasicPhysicsPlugin + OpenSim.Physics.BasicPhysicsPlugin + + + + + + + + + + + + + + + + + OpenSim.Physics.OdePlugin + + + + + OpenSim.Physics.OdePlugin + + + + + OpenSim.Physics.OdePlugin + + + + + + + + + + + OdeCharacter + + + + + + + + + parent_scene + OdeCharacter.OdeCharacter(OdeScene, PhysicsVector) + + + + + 'pos' + OdeCharacter.OdeCharacter(OdeScene, PhysicsVector) + + + + + + + + + OdeCharacter.capsule_geom + + + + + + + + + OdeCharacter.gravityAccel + + + + + + + + + OdeCharacter.SetAcceleration(PhysicsVector):Void + accel + accel + + + + + + + + + + + Plugin + OpenSim.Physics.OdePlugin.OdePlugin + + + + + OdePlugin + OpenSim.Physics.OdePlugin + + + + + + + + + + + OdePrim._position + + + + + + + + + OdePrim.SetAcceleration(PhysicsVector):Void + accel + accel + + + + + + + + + + + + + 'position' + OdeScene.AddPrim(PhysicsVector, PhysicsVector):PhysicsActor + + + 'size' + OdeScene.AddPrim(PhysicsVector, PhysicsVector):PhysicsActor + + + + + + + + + OdeScene.Land + + + + + + + + + OdeScene.LandGeom + + + + + + + + + 'heightMap' + OdeScene.SetTerrain(Single[]):Void + + + 'heightMap' + OdeScene.SetTerrain(Single[]):Void + + + + + + + + + space + + + + + space + + + + + + + + + world + + + + + world + + + + + + + + + + + + + + + + + + + OpenSim.Physics.PhysXPlugin + + + + + OpenSim.Physics.PhysXPlugin + + + + + OpenSim.Physics.PhysXPlugin + + + + + + + + + + + + + PhysXCharacter.SetAcceleration(PhysicsVector):Void + accel + accel + + + + + + + + + + + Plugin + OpenSim.Physics.PhysXPlugin.PhysXPlugin + + + + + PhysXPlugin + OpenSim.Physics.PhysXPlugin + + + + + + + + + + + PhysXPrim._position + + + + + + + + + PhysXPrim.SetAcceleration(PhysicsVector):Void + accel + accel + + + + + + + + + + + + + + + + Save it for a rainy day. + Save it for a rainy day. + Save it for a rainy day. + + + + + No valid permission requests were found for assembly '{0}'. You should always specify the minimum security permissions using SecurityAction.RequestMinimum. + + + Sign '{0}' with a strong name key. + + + Consider merging the types defined in '{0}' with another namespace. + + + It appears that field '{0}' is never used or is only ever assigned to. Use this field or remove it. + + + Change '{0}' to be read-only by removing the property setter. + + + The compound word '{0}' in {1} '{2}' exists as a discrete term. If your usage is intended to be single word, case it as '{3}'. + + + '{0}' is marked ComVisible(true) but has the following ComVisible(false) types in its object hierarchy: {1} + + + Consider changing the type of parameter '{0}' in {1} from {2} to its base type {3}. This method appears to only require base class members in its implementation. Suppress this violation if there is a compelling reason to require the more derived type in the method signature. + + + '{0}' contains a call chain that results in a call to a virtual method defined by the class. Review the following call stack for unintended consequences: {1} + + + Modify '{0}' to catch a more specific exception than '{1}' or rethrow the exception. + + + Remove the readonly declaration from '{0}' or change the field to one that is an immutable reference type. If the reference type '{1}' is, in fact, immutable, exclude this message. + + + Make '{0}' private or internal (Friend in VB, public private in C++) and provide a public or protected property to access it. + + + Change '{0}' in {1} to use Collection<T>, ReadOnlyCollection<T> or KeyedCollection<K,V> + + + {0} initializes field {1} of type {2} to {3}. Remove this initialization as it will be done automatically by the runtime. + + + {0} passes a literal as parameter {1} of a call to {2}. Retrieve the following string argument from a resource table instead: '{3}' + + + Consider a design that does not require that '{0}' be a reference parameter. + + + {0} creates an exception of type '{1}', an exception type that is not sufficiently specific and should never be raised by user code. If this exception instance might be thrown, use a different exception type. + + + Modify the call to {0} in method {1} to set the timer interval to a value that's greater than or equal to one second. + + + Correct the casing of member name '{0}'. + Correct the casing of namespace name '{0}'. + Correct the casing of parameter name '{0}'. + Correct the casing of type name '{0}'. + + + Correct the spelling of the unrecognized token '{0}' in member name '{1}'. + Consider providing a more meaningful name than the one-letter token '{0}' in member name '{1}'. + Correct the spelling of the unrecognized token '{0}' in namespace '{1}'. + In method {0}, correct the spelling of the unrecognized token '{1}' in parameter name '{2}' or strip it entirely if it represents any sort of hungarian notation. + In method {0}, consider providing a more meaningful name than the one-letter parameter name '{1}'. + Correct the spelling of the unrecognized token '{0}' in type name '{1}'. + + + Change member names {0} and '{1}' so that they differ by more than case. + + + Remove all underscores from member '{0}'. + Remove all underscores from parameter '{0}'. + Remove all underscores from type '{0}'. + + + Rename '{0}' so that it does not end in '{1}'. + + + Correct the spelling of the unrecognized token '{0}' in the literal '{1}'. + + + Correct the capitalization of member name '{0}'. + Correct the capitalization of namespace name '{0}'. + Correct the capitalization of parameter name '{0}'. + Correct the capitalization of type name '{0}'. + + + Add an AssemblyVersion attribute to '{0}'. + + + '{0}' should be marked with CLSCompliantAttribute and its value should be true. + + + Mark '{0}' as ComVisible(false) at the assembly level, then mark all types within the assembly that should be exposed to Com clients as ComVisible(true). + + + The 'this' parameter (or 'Me' in VB) of {0} is never used. Mark the member as static (or Shared in VB) or use 'this'/'Me' in the method body or at least one property accessor, if appropriate. + + + Consider making '{0}' non-public or a constant. + + + Correct the potential overflow in the operation '{0}' in '{1}'. + + + Provide a method named '{0}' as a friendly alternate for operator {1}. + + + Consider adding an overload of the equality operator for '{0}' that takes the same parameters as {1}. + + + '{0}' should override Equals. + '{0}' should override the equality (==) and inequality (!=) operators. + + + Change parameter name '{0}' of method {1} to '{2}' in order to match the identifier as it has been declared in {3}. + + + Modify {0} to call {1} instead of {2}. + + + Make '{0}' private. + + + Add a property getter to '{0}'. + + + {0} declares a local, '{1}', of type {2}, which is never used or is only assigned to. Use this local or remove it. + + + Parameter '{0}' of {1} is never used. Remove the parameter or use it in the method body. + + + Correct the capitalization of '{0}' in member name '{1}'. + 'Id' is an abbreviation and therefore is not subject to acronym casing guidelines. Correct the capitalization of 'ID' in member name '{0}' by changing it to 'Id'. + 'Id' is an abbreviation and therefore is not subject to acronym casing guidelines. Correct the capitalization of '{0}' in parameter name '{1}' by changing it to '{2}'. + Correct the capitalization of '{0}' in type name '{1}'. + + + {0} makes a call to {1} that does not explicitly provide a CultureInfo. This should be replaced with a call to {2}. + + + {0} makes a call to {1} that does not explicitly provide an IFormatProvider. This should be replaced with a call to {2}. + + + Remove the public constructors from '{0}'. + + + Replace the call to String.{0}({1}) in '{2}' with a call to String.IsNullOrEmpty. + + + The type name '{0}' conflicts in whole or in part with the namespace name '{1}'. Change either name to eliminate the conflict. + + + Implement IDisposable on '{0}' as it instantiates members of the following IDisposable types: {1} + + + Implement IDisposable on '{0}'. + + + Change the type of parameter '{0}' of method {1} from string to System.Uri, or provide an overload of {1}, that allows '{0}' to be passed as a System.Uri object. + + + Replace the term '{0}' in member name '{1}' with the preferred alternate '{2}'. + Replace the term '{0}' in type name '{1}' with the preferred alternate '{2}'. + + + Change '{0}' to a property if appropriate. + + + Validate parameter {0} passed to externally visible method {1}. + + + + diff --git a/OpenSim/Framework/Communications/Cache/AssetCache.cs b/OpenSim/Framework/Communications/Cache/AssetCache.cs new file mode 100644 index 0000000000..4f98359c7a --- /dev/null +++ b/OpenSim/Framework/Communications/Cache/AssetCache.cs @@ -0,0 +1,745 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.IO; +using System.Reflection; +using System.Threading; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Framework.Utilities; + +namespace OpenSim.Framework.Communications.Caches +{ + public delegate void DownloadComplete(AssetCache.TextureSender sender); + + /// + /// Manages local cache of assets and their sending to viewers. + /// + public class AssetCache : IAssetReceiver + { + public Dictionary Assets; + public Dictionary Textures; + + public List AssetRequests = new List(); //assets ready to be sent to viewers + public List TextureRequests = new List(); //textures ready to be sent + + public Dictionary RequestedAssets = new Dictionary(); //Assets requested from the asset server + public Dictionary RequestedTextures = new Dictionary(); //Textures requested from the asset server + + public Dictionary SendingTextures = new Dictionary(); + private BlockingQueue QueueTextures = new BlockingQueue(); + + private Dictionary> AvatarRecievedTextures = new Dictionary>(); + + private IAssetServer _assetServer; + private Thread _assetCacheThread; + + private Thread TextureSenderThread; + + /// + /// + /// + public AssetCache(IAssetServer assetServer) + { + Console.WriteLine("Creating Asset cache"); + _assetServer = assetServer; + _assetServer.SetReceiver(this); + Assets = new Dictionary(); + Textures = new Dictionary(); + this._assetCacheThread = new Thread(new ThreadStart(RunAssetManager)); + this._assetCacheThread.IsBackground = true; + this._assetCacheThread.Start(); + + this.TextureSenderThread = new Thread(new ThreadStart(this.ProcessTextureSenders)); + this.TextureSenderThread.IsBackground = true; + this.TextureSenderThread.Start(); + + } + + public AssetCache(string assetServerDLLName, string assetServerURL, string assetServerKey) + { + Console.WriteLine("Creating Asset cache"); + _assetServer = this.LoadAssetDll(assetServerDLLName); + _assetServer.SetServerInfo(assetServerURL, assetServerKey); + _assetServer.SetReceiver(this); + Assets = new Dictionary(); + Textures = new Dictionary(); + this._assetCacheThread = new Thread(new ThreadStart(RunAssetManager)); + this._assetCacheThread.IsBackground = true; + this._assetCacheThread.Start(); + + this.TextureSenderThread = new Thread(new ThreadStart(this.ProcessTextureSenders)); + this.TextureSenderThread.IsBackground = true; + this.TextureSenderThread.Start(); + } + + /// + /// + /// + public void RunAssetManager() + { + while (true) + { + try + { + this.ProcessAssetQueue(); + this.ProcessTextureQueue(); + Thread.Sleep(500); + } + catch (Exception e) + { + Console.WriteLine(e.Message + " : " + e.StackTrace); + } + } + } + + + public AssetBase GetAsset(LLUUID assetID) + { + AssetBase asset = null; + if (this.Textures.ContainsKey(assetID)) + { + asset = this.Textures[assetID]; + } + else if (this.Assets.ContainsKey(assetID)) + { + asset = this.Assets[assetID]; + } + return asset; + } + + public AssetBase GetAsset(LLUUID assetID, bool isTexture) + { + AssetBase asset = GetAsset(assetID); + if (asset == null) + { + this._assetServer.RequestAsset(assetID, isTexture); + } + return asset; + } + + public void AddAsset(AssetBase asset) + { + // Console.WriteLine("adding asset " + asset.FullID.ToStringHyphenated()); + if (asset.Type == 0) + { + //Console.WriteLine("which is a texture"); + if (!this.Textures.ContainsKey(asset.FullID)) + { //texture + TextureImage textur = new TextureImage(asset); + this.Textures.Add(textur.FullID, textur); + this._assetServer.UploadNewAsset(asset); + } + } + else + { + if (!this.Assets.ContainsKey(asset.FullID)) + { + AssetInfo assetInf = new AssetInfo(asset); + this.Assets.Add(assetInf.FullID, assetInf); + this._assetServer.UploadNewAsset(asset); + } + } + } + + /// + /// + /// + private void ProcessTextureQueue() + { + if (this.TextureRequests.Count == 0) + { + //no requests waiting + return; + } + int num; + num = this.TextureRequests.Count; + + AssetRequest req; + for (int i = 0; i < num; i++) + { + req = (AssetRequest)this.TextureRequests[i]; + if (!this.SendingTextures.ContainsKey(req.ImageInfo.FullID)) + { + //Console.WriteLine("new texture to send"); + TextureSender sender = new TextureSender(req); + //sender.OnComplete += this.TextureSent; + lock (this.SendingTextures) + { + this.SendingTextures.Add(req.ImageInfo.FullID, sender); + } + this.QueueTextures.Enqueue(sender); + } + + } + + this.TextureRequests.Clear(); + } + + public void ProcessTextureSenders() + { + while (true) + { + TextureSender sender = this.QueueTextures.Dequeue(); + bool finished = sender.SendTexture(); + if (finished) + { + this.TextureSent(sender); + } + else + { + // Console.WriteLine("readding texture"); + this.QueueTextures.Enqueue(sender); + } + } + } + + /// + /// Event handler, called by a TextureSender object to say that texture has been sent + /// + /// + public void TextureSent(TextureSender sender) + { + if (this.SendingTextures.ContainsKey(sender.request.ImageInfo.FullID)) + { + lock (this.SendingTextures) + { + this.SendingTextures.Remove(sender.request.ImageInfo.FullID); + // this.AvatarRecievedTextures[sender.request.RequestUser.AgentId].Add(sender.request.ImageInfo.FullID); + } + } + } + + public void AssetReceived(AssetBase asset, bool IsTexture) + { + if (asset.FullID != LLUUID.Zero) // if it is set to zero then the asset wasn't found by the server + { + //check if it is a texture or not + //then add to the correct cache list + //then check for waiting requests for this asset/texture (in the Requested lists) + //and move those requests into the Requests list. + + if (IsTexture) + { + // Console.WriteLine("asset recieved from asset server"); + + TextureImage image = new TextureImage(asset); + if (!this.Textures.ContainsKey(image.FullID)) + { + this.Textures.Add(image.FullID, image); + if (this.RequestedTextures.ContainsKey(image.FullID)) + { + AssetRequest req = this.RequestedTextures[image.FullID]; + req.ImageInfo = image; + if (image.Data.LongLength > 600) + { + //over 600 bytes so split up file + req.NumPackets = 1 + (int)(image.Data.Length - 600) / 1000; + } + else + { + req.NumPackets = 1; + } + this.RequestedTextures.Remove(image.FullID); + this.TextureRequests.Add(req); + } + } + } + else + { + AssetInfo assetInf = new AssetInfo(asset); + if (!this.Assets.ContainsKey(assetInf.FullID)) + { + this.Assets.Add(assetInf.FullID, assetInf); + if (this.RequestedAssets.ContainsKey(assetInf.FullID)) + { + AssetRequest req = this.RequestedAssets[assetInf.FullID]; + req.AssetInf = assetInf; + if (assetInf.Data.LongLength > 600) + { + //over 600 bytes so split up file + req.NumPackets = 1 + (int)(assetInf.Data.Length - 600 + 999) / 1000; + } + else + { + req.NumPackets = 1; + } + this.RequestedAssets.Remove(assetInf.FullID); + this.AssetRequests.Add(req); + } + } + } + } + } + + public void AssetNotFound(AssetBase asset) + { + //the asset server had no knowledge of requested asset + + } + + #region Assets + /// + /// + /// + /// + /// + public void AddAssetRequest(IClientAPI userInfo, TransferRequestPacket transferRequest) + { + LLUUID requestID = null; + byte source = 2; + if (transferRequest.TransferInfo.SourceType == 2) + { + //direct asset request + requestID = new LLUUID(transferRequest.TransferInfo.Params, 0); + } + else if (transferRequest.TransferInfo.SourceType == 3) + { + //inventory asset request + requestID = new LLUUID(transferRequest.TransferInfo.Params, 80); + source = 3; + Console.WriteLine("asset request " + requestID); + } + //check to see if asset is in local cache, if not we need to request it from asset server. + //Console.WriteLine("asset request " + requestID); + if (!this.Assets.ContainsKey(requestID)) + { + //not found asset + // so request from asset server + if (!this.RequestedAssets.ContainsKey(requestID)) + { + AssetRequest request = new AssetRequest(); + request.RequestUser = userInfo; + request.RequestAssetID = requestID; + request.TransferRequestID = transferRequest.TransferInfo.TransferID; + request.AssetRequestSource = source; + request.Params = transferRequest.TransferInfo.Params; + this.RequestedAssets.Add(requestID, request); + this._assetServer.RequestAsset(requestID, false); + } + return; + } + //it is in our cache + AssetInfo asset = this.Assets[requestID]; + + //work out how many packets it should be sent in + // and add to the AssetRequests list + AssetRequest req = new AssetRequest(); + req.RequestUser = userInfo; + req.RequestAssetID = requestID; + req.TransferRequestID = transferRequest.TransferInfo.TransferID; + req.AssetRequestSource = source; + req.Params = transferRequest.TransferInfo.Params; + req.AssetInf = asset; + + if (asset.Data.LongLength > 600) + { + //over 600 bytes so split up file + req.NumPackets = 1 + (int)(asset.Data.Length - 600 + 999) / 1000; + } + else + { + req.NumPackets = 1; + } + + this.AssetRequests.Add(req); + } + + /// + /// + /// + private void ProcessAssetQueue() + { + if (this.AssetRequests.Count == 0) + { + //no requests waiting + return; + } + int num; + + if (this.AssetRequests.Count < 5) + { + //lower than 5 so do all of them + num = this.AssetRequests.Count; + } + else + { + num = 5; + } + AssetRequest req; + for (int i = 0; i < num; i++) + { + req = (AssetRequest)this.AssetRequests[i]; + //Console.WriteLine("sending asset " + req.RequestAssetID); + TransferInfoPacket Transfer = new TransferInfoPacket(); + Transfer.TransferInfo.ChannelType = 2; + Transfer.TransferInfo.Status = 0; + Transfer.TransferInfo.TargetType = 0; + if (req.AssetRequestSource == 2) + { + Transfer.TransferInfo.Params = new byte[20]; + Array.Copy(req.RequestAssetID.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); + int assType = (int)req.AssetInf.Type; + Array.Copy(Helpers.IntToBytes(assType), 0, Transfer.TransferInfo.Params, 16, 4); + } + else if (req.AssetRequestSource == 3) + { + Transfer.TransferInfo.Params = req.Params; + // Transfer.TransferInfo.Params = new byte[100]; + //Array.Copy(req.RequestUser.AgentId.GetBytes(), 0, Transfer.TransferInfo.Params, 0, 16); + //Array.Copy(req.RequestUser.SessionId.GetBytes(), 0, Transfer.TransferInfo.Params, 16, 16); + } + Transfer.TransferInfo.Size = (int)req.AssetInf.Data.Length; + Transfer.TransferInfo.TransferID = req.TransferRequestID; + req.RequestUser.OutPacket(Transfer); + + if (req.NumPackets == 1) + { + TransferPacketPacket TransferPacket = new TransferPacketPacket(); + TransferPacket.TransferData.Packet = 0; + TransferPacket.TransferData.ChannelType = 2; + TransferPacket.TransferData.TransferID = req.TransferRequestID; + TransferPacket.TransferData.Data = req.AssetInf.Data; + TransferPacket.TransferData.Status = 1; + req.RequestUser.OutPacket(TransferPacket); + } + else + { + //more than one packet so split file up , for now it can't be bigger than 2000 bytes + TransferPacketPacket TransferPacket = new TransferPacketPacket(); + TransferPacket.TransferData.Packet = 0; + TransferPacket.TransferData.ChannelType = 2; + TransferPacket.TransferData.TransferID = req.TransferRequestID; + byte[] chunk = null; + if (req.AssetInf.Data.Length <= 1000) + { + chunk = new byte[req.AssetInf.Data.Length]; + Array.Copy(req.AssetInf.Data, chunk, req.AssetInf.Data.Length); + TransferPacket.TransferData.Data = chunk; + TransferPacket.TransferData.Status = 1; + req.RequestUser.OutPacket(TransferPacket); + } + else + { + chunk = new byte[1000]; + Array.Copy(req.AssetInf.Data, chunk, 1000); + + TransferPacket.TransferData.Data = chunk; + TransferPacket.TransferData.Status = 0; + req.RequestUser.OutPacket(TransferPacket); + + TransferPacket = new TransferPacketPacket(); + TransferPacket.TransferData.Packet = 1; + TransferPacket.TransferData.ChannelType = 2; + TransferPacket.TransferData.TransferID = req.TransferRequestID; + byte[] chunk1 = new byte[(req.AssetInf.Data.Length - 1000)]; + Array.Copy(req.AssetInf.Data, 1000, chunk1, 0, chunk1.Length); + TransferPacket.TransferData.Data = chunk1; + TransferPacket.TransferData.Status = 1; + req.RequestUser.OutPacket(TransferPacket); + } + } + + } + + //remove requests that have been completed + for (int i = 0; i < num; i++) + { + this.AssetRequests.RemoveAt(0); + } + + } + + public AssetInfo CloneAsset(LLUUID newOwner, AssetInfo sourceAsset) + { + AssetInfo newAsset = new AssetInfo(); + newAsset.Data = new byte[sourceAsset.Data.Length]; + Array.Copy(sourceAsset.Data, newAsset.Data, sourceAsset.Data.Length); + newAsset.FullID = LLUUID.Random(); + newAsset.Type = sourceAsset.Type; + newAsset.InvType = sourceAsset.InvType; + return (newAsset); + } + #endregion + + #region Textures + /// + /// + /// + /// + /// + public void AddTextureRequest(IClientAPI userInfo, LLUUID imageID, uint packetNumber) + { + // Console.WriteLine("texture request for " + imageID.ToStringHyphenated()); + //check to see if texture is in local cache, if not request from asset server + if(!this.AvatarRecievedTextures.ContainsKey(userInfo.AgentId)) + { + this.AvatarRecievedTextures.Add(userInfo.AgentId, new List()); + } + /* if(this.AvatarRecievedTextures[userInfo.AgentId].Contains(imageID)) + { + //Console.WriteLine(userInfo.AgentId +" is requesting a image( "+ imageID+" that has already been sent to them"); + return; + }*/ + if (!this.Textures.ContainsKey(imageID)) + { + if (!this.RequestedTextures.ContainsKey(imageID)) + { + //not is cache so request from asset server + AssetRequest request = new AssetRequest(); + request.RequestUser = userInfo; + request.RequestAssetID = imageID; + request.IsTextureRequest = true; + this.RequestedTextures.Add(imageID, request); + this._assetServer.RequestAsset(imageID, true); + } + return; + } + + //Console.WriteLine("texture already in cache"); + TextureImage imag = this.Textures[imageID]; + AssetRequest req = new AssetRequest(); + req.RequestUser = userInfo; + req.RequestAssetID = imageID; + req.IsTextureRequest = true; + req.ImageInfo = imag; + + if (imag.Data.LongLength > 600) + { + //over 600 bytes so split up file + req.NumPackets = 1 + (int)(imag.Data.Length - 600 ) / 1000; + //Console.WriteLine("texture is " + imag.Data.Length + " which we will send in " +req.NumPackets +" packets"); + } + else + { + req.NumPackets = 1; + } + if (packetNumber != 0) + { + req.PacketCounter = (int)packetNumber; + } + this.TextureRequests.Add(req); + } + + public TextureImage CloneImage(LLUUID newOwner, TextureImage source) + { + TextureImage newImage = new TextureImage(); + newImage.Data = new byte[source.Data.Length]; + Array.Copy(source.Data, newImage.Data, source.Data.Length); + //newImage.filename = source.filename; + newImage.FullID = LLUUID.Random(); + newImage.Name = source.Name; + return (newImage); + } + #endregion + + private IAssetServer LoadAssetDll(string dllName) + { + Assembly pluginAssembly = Assembly.LoadFrom(dllName); + IAssetServer server = null; + + foreach (Type pluginType in pluginAssembly.GetTypes()) + { + if (pluginType.IsPublic) + { + if (!pluginType.IsAbstract) + { + Type typeInterface = pluginType.GetInterface("IAssetPlugin", true); + + if (typeInterface != null) + { + IAssetPlugin plug = (IAssetPlugin)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); + server = plug.GetAssetServer(); + break; + } + + typeInterface = null; + } + } + } + pluginAssembly = null; + return server; + } + + public class AssetRequest + { + public IClientAPI RequestUser; + public LLUUID RequestAssetID; + public AssetInfo AssetInf; + public TextureImage ImageInfo; + public LLUUID TransferRequestID; + public long DataPointer = 0; + public int NumPackets = 0; + public int PacketCounter = 0; + public bool IsTextureRequest; + public byte AssetRequestSource = 2; + public byte[] Params = null; + //public bool AssetInCache; + //public int TimeRequested; + + public AssetRequest() + { + + } + } + + public class AssetInfo : AssetBase + { + public AssetInfo() + { + + } + + public AssetInfo(AssetBase aBase) + { + Data = aBase.Data; + FullID = aBase.FullID; + Type = aBase.Type; + InvType = aBase.InvType; + Name = aBase.Name; + Description = aBase.Description; + } + } + + public class TextureImage : AssetBase + { + public TextureImage() + { + + } + + public TextureImage(AssetBase aBase) + { + Data = aBase.Data; + FullID = aBase.FullID; + Type = aBase.Type; + InvType = aBase.InvType; + Name = aBase.Name; + Description = aBase.Description; + } + } + + public class TextureSender + { + public AssetRequest request; + private int counter = 0; + + public TextureSender(AssetRequest req) + { + request = req; + + } + + public bool SendTexture() + { + SendPacket(); + counter++; + + if ((request.PacketCounter > request.NumPackets) | (counter >120) |(request.NumPackets ==1)) + { + return true; + } + return false; + } + + public void SendPacket() + { + AssetRequest req = request; + // Console.WriteLine("sending " + req.ImageInfo.FullID); + if (req.PacketCounter == 0) + { + //first time for this request so send imagedata packet + if (req.NumPackets == 1) + { + //only one packet so send whole file + ImageDataPacket im = new ImageDataPacket(); + im.ImageID.Packets = 1; + im.ImageID.ID = req.ImageInfo.FullID; + im.ImageID.Size = (uint)req.ImageInfo.Data.Length; + im.ImageData.Data = req.ImageInfo.Data; + im.ImageID.Codec = 2; + req.RequestUser.OutPacket(im); + req.PacketCounter++; + //req.ImageInfo.l= time; + //System.Console.WriteLine("sent texture: " + req.ImageInfo.FullID); + // Console.WriteLine("sending packet 1 for " + req.ImageInfo.FullID.ToStringHyphenated()); + } + else + { + //more than one packet so split file up + ImageDataPacket im = new ImageDataPacket(); + im.ImageID.Packets = (ushort)(req.NumPackets); + im.ImageID.ID = req.ImageInfo.FullID; + im.ImageID.Size = (uint)req.ImageInfo.Data.Length; + im.ImageData.Data = new byte[600]; + Array.Copy(req.ImageInfo.Data, 0, im.ImageData.Data, 0, 600); + im.ImageID.Codec = 2; + req.RequestUser.OutPacket(im); + + req.PacketCounter++; + //req.ImageInfo.last_used = time; + //System.Console.WriteLine("sent first packet of texture: + // Console.WriteLine("sending packet 1 for " + req.ImageInfo.FullID.ToStringHyphenated()); + } + } + else + { + //Console.WriteLine("sending packet" + req.PacketCounter + "for " + req.ImageInfo.FullID.ToStringHyphenated()); + //send imagepacket + //more than one packet so split file up + ImagePacketPacket im = new ImagePacketPacket(); + im.ImageID.Packet = (ushort)(req.PacketCounter); + im.ImageID.ID = req.ImageInfo.FullID; + int size = req.ImageInfo.Data.Length - 600 - (1000 * (req.PacketCounter - 1)); + if (size > 1000) size = 1000; + im.ImageData.Data = new byte[size]; + Array.Copy(req.ImageInfo.Data, 600 + (1000 * (req.PacketCounter - 1)), im.ImageData.Data, 0, size); + req.RequestUser.OutPacket(im); + req.PacketCounter++; + //req.ImageInfo.last_used = time; + //System.Console.WriteLine("sent a packet of texture: "+req.image_info.FullID); + } + + } + + private void SaveAssetToFile(string filename, byte[] data) + { + FileStream fs = File.Create(filename); + BinaryWriter bw = new BinaryWriter(fs); + bw.Write(data); + bw.Close(); + fs.Close(); + } + } + } +} + diff --git a/OpenSim/Framework/Communications/Cache/AssetTransactionManager.cs b/OpenSim/Framework/Communications/Cache/AssetTransactionManager.cs new file mode 100644 index 0000000000..5f1bd29906 --- /dev/null +++ b/OpenSim/Framework/Communications/Cache/AssetTransactionManager.cs @@ -0,0 +1,107 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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; +using System.Collections.Generic; +using System.Text; +using System.IO; +using libsecondlife; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Framework.Utilities; +using OpenSim.Framework.Data; + +namespace OpenSim.Framework.Communications.Caches +{ + public class AssetTransactionManager + { + // Fields + public CommunicationsManager CommsManager; + public Dictionary AgentTransactions = new Dictionary(); + + public AssetTransactionManager(CommunicationsManager commsManager) + { + CommsManager = commsManager; + } + + // Methods + public AgentAssetTransactions AddUser(LLUUID userID) + { + if (!this.AgentTransactions.ContainsKey(userID)) + { + AgentAssetTransactions transactions = new AgentAssetTransactions(userID, this); + this.AgentTransactions.Add(userID, transactions); + return transactions; + } + return null; + } + + public AgentAssetTransactions GetUserTransActions(LLUUID userID) + { + if (this.AgentTransactions.ContainsKey(userID)) + { + return this.AgentTransactions[userID]; + } + return null; + } + + public void HandleInventoryFromTransaction(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, uint callbackID, string description, string name, sbyte invType, sbyte type, byte wearableType, uint nextOwnerMask) + { + AgentAssetTransactions transactions = this.GetUserTransActions(remoteClient.AgentId); + if (transactions != null) + { + transactions.RequestCreateInventoryItem(remoteClient, transactionID, folderID, callbackID, description, name, invType, type, wearableType, nextOwnerMask); + } + + } + + public void HandleUDPUploadRequest(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data) + { + AgentAssetTransactions transactions = this.GetUserTransActions(remoteClient.AgentId); + if (transactions != null) + { + AgentAssetTransactions.AssetXferUploader uploader = transactions.RequestXferUploader(transaction); + if (uploader != null) + { + uploader.Initialise(remoteClient, assetID, transaction, type, data); + } + } + } + + public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data) + { + AgentAssetTransactions transactions = this.GetUserTransActions(remoteClient.AgentId); + if (transactions != null) + { + transactions.HandleXfer(xferID, packetID, data); + } + } + } +} + + diff --git a/OpenSim/Framework/Communications/Cache/AssetTransactions.cs b/OpenSim/Framework/Communications/Cache/AssetTransactions.cs new file mode 100644 index 0000000000..76c2f01d3d --- /dev/null +++ b/OpenSim/Framework/Communications/Cache/AssetTransactions.cs @@ -0,0 +1,382 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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; +using System.Collections.Generic; +using System.Text; +using System.IO; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Framework.Utilities; +using OpenSim.Framework.Data; +using OpenSim.Region.Capabilities; +using OpenSim.Framework.Servers; + +namespace OpenSim.Framework.Communications.Caches +{ + public class AgentAssetTransactions + { + // Fields + public List CapsUploaders = new List(); + public List NotecardUpdaters = new List(); + public LLUUID UserID; + public Dictionary XferUploaders = new Dictionary(); + public AssetTransactionManager Manager; + + // Methods + public AgentAssetTransactions(LLUUID agentID, AssetTransactionManager manager) + { + this.UserID = agentID; + Manager = manager; + } + + public AssetCapsUploader RequestCapsUploader() + { + AssetCapsUploader uploader = new AssetCapsUploader(); + this.CapsUploaders.Add(uploader); + return uploader; + } + + public NoteCardCapsUpdate RequestNoteCardUpdater() + { + NoteCardCapsUpdate update = new NoteCardCapsUpdate(); + this.NotecardUpdaters.Add(update); + return update; + } + + public AssetXferUploader RequestXferUploader(LLUUID transactionID) + { + if (!this.XferUploaders.ContainsKey(transactionID)) + { + AssetXferUploader uploader = new AssetXferUploader(this); + + this.XferUploaders.Add(transactionID, uploader); + return uploader; + } + return null; + } + + public void HandleXfer(ulong xferID, uint packetID, byte[] data) + { + foreach (AssetXferUploader uploader in this.XferUploaders.Values) + { + if (uploader.XferID == xferID) + { + uploader.HandleXferPacket(xferID, packetID, data); + break; + } + } + } + + public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, uint callbackID, string description, string name, sbyte invType, sbyte type, byte wearableType, uint nextOwnerMask) + { + if (this.XferUploaders.ContainsKey(transactionID)) + { + this.XferUploaders[transactionID].RequestCreateInventoryItem(remoteClient, transactionID, folderID, callbackID, description, name, invType, type, wearableType, nextOwnerMask); + } + } + + // Nested Types + public class AssetCapsUploader + { + // Fields + private BaseHttpServer httpListener; + private LLUUID inventoryItemID; + private string m_assetDescription = ""; + private string m_assetName = ""; + private LLUUID m_folderID; + private LLUUID newAssetID; + private bool SaveImages = false; + private string uploaderPath = ""; + + // Events + public event UpLoadedAsset OnUpLoad; + + // Methods + public void Initialise(string assetName, string assetDescription, LLUUID assetID, LLUUID inventoryItem, LLUUID folderID, string path, BaseHttpServer httpServer) + { + this.m_assetName = assetName; + this.m_assetDescription = assetDescription; + this.m_folderID = folderID; + this.newAssetID = assetID; + this.inventoryItemID = inventoryItem; + this.uploaderPath = path; + this.httpListener = httpServer; + } + + private void SaveImageToFile(string filename, byte[] data) + { + FileStream output = File.Create(filename); + BinaryWriter writer = new BinaryWriter(output); + writer.Write(data); + writer.Close(); + output.Close(); + } + + public string uploaderCaps(byte[] data, string path, string param) + { + LLUUID inventoryItemID = this.inventoryItemID; + string text = ""; + LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete(); + complete.new_asset = this.newAssetID.ToStringHyphenated(); + complete.new_inventory_item = inventoryItemID; + complete.state = "complete"; + text = LLSDHelpers.SerialiseLLSDReply(complete); + this.httpListener.RemoveStreamHandler("POST", this.uploaderPath); + if (this.SaveImages) + { + this.SaveImageToFile(this.m_assetName + ".jp2", data); + } + if (this.OnUpLoad != null) + { + this.OnUpLoad(this.m_assetName, "description", this.newAssetID, inventoryItemID, LLUUID.Zero, data, "" , ""); + } + return text; + } + } + + public class AssetXferUploader + { + // Fields + public bool AddToInventory; + public AssetBase Asset; + public LLUUID InventFolder = LLUUID.Zero; + private IClientAPI ourClient; + public LLUUID TransactionID = LLUUID.Zero; + public bool UploadComplete; + public ulong XferID; + private string m_name = ""; + private string m_description = ""; + private sbyte type = 0; + private sbyte invType = 0; + private uint nextPerm = 0; + private bool m_finished = false; + private bool m_createItem = false; + private AgentAssetTransactions m_userTransactions; + + public AssetXferUploader(AgentAssetTransactions transactions) + { + this.m_userTransactions = transactions; + } + + // Methods + public void HandleXferPacket(ulong xferID, uint packetID, byte[] data) + { + if (this.XferID == xferID) + { + if (this.Asset.Data.Length > 1) + { + byte[] destinationArray = new byte[this.Asset.Data.Length + data.Length]; + Array.Copy(this.Asset.Data, 0, destinationArray, 0, this.Asset.Data.Length); + Array.Copy(data, 0, destinationArray, this.Asset.Data.Length, data.Length); + this.Asset.Data = destinationArray; + } + else + { + byte[] buffer2 = new byte[data.Length - 4]; + Array.Copy(data, 4, buffer2, 0, data.Length - 4); + this.Asset.Data = buffer2; + } + ConfirmXferPacketPacket newPack = new ConfirmXferPacketPacket(); + newPack.XferID.ID = xferID; + newPack.XferID.Packet = packetID; + this.ourClient.OutPacket(newPack); + if ((packetID & 0x80000000) != 0) + { + this.SendCompleteMessage(); + } + } + } + + public void Initialise(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data) + { + this.ourClient = remoteClient; + this.Asset = new AssetBase(); + this.Asset.FullID = assetID; + this.Asset.InvType = type; + this.Asset.Type = type; + this.Asset.Data = data; + this.Asset.Name = "blank"; + this.Asset.Description = "empty"; + this.TransactionID = transaction; + if (this.Asset.Data.Length > 2) + { + this.SendCompleteMessage(); + } + else + { + this.ReqestStartXfer(); + } + } + + protected void ReqestStartXfer() + { + this.UploadComplete = false; + this.XferID = Util.GetNextXferID(); + RequestXferPacket newPack = new RequestXferPacket(); + newPack.XferID.ID = this.XferID; + newPack.XferID.VFileType = this.Asset.Type; + newPack.XferID.VFileID = this.Asset.FullID; + newPack.XferID.FilePath = 0; + newPack.XferID.Filename = new byte[0]; + this.ourClient.OutPacket(newPack); + } + + protected void SendCompleteMessage() + { + this.UploadComplete = true; + AssetUploadCompletePacket newPack = new AssetUploadCompletePacket(); + newPack.AssetBlock.Type = this.Asset.Type; + newPack.AssetBlock.Success = true; + newPack.AssetBlock.UUID = this.Asset.FullID; + this.ourClient.OutPacket(newPack); + this.m_finished = true; + if (m_createItem) + { + DoCreateItem(); + } + // Console.WriteLine("upload complete "+ this.TransactionID); + //SaveAssetToFile("testudpupload" + Util.RandomClass.Next(1, 1000) + ".dat", this.Asset.Data); + } + private void SaveAssetToFile(string filename, byte[] data) + { + FileStream fs = File.Create(filename); + BinaryWriter bw = new BinaryWriter(fs); + bw.Write(data); + bw.Close(); + fs.Close(); + } + + public void RequestCreateInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID, uint callbackID, string description, string name, sbyte invType, sbyte type, byte wearableType, uint nextOwnerMask) + { + if (this.TransactionID == transactionID) + { + this.InventFolder = folderID; + this.m_name = name; + this.m_description = description; + this.type = type; + this.invType = invType; + this.nextPerm = nextOwnerMask; + this.Asset.Name = name; + this.Asset.Description = description; + this.Asset.Type = type; + this.Asset.InvType = invType; + m_createItem = true; + if (m_finished) + { + DoCreateItem(); + } + } + } + + private void DoCreateItem() + { + this.m_userTransactions.Manager.CommsManager.AssetCache.AddAsset(this.Asset); + CachedUserInfo userInfo = m_userTransactions.Manager.CommsManager.UserProfiles.GetUserDetails(ourClient.AgentId); + if (userInfo != null) + { + InventoryItemBase item = new InventoryItemBase(); + item.avatarID = this.ourClient.AgentId; + item.creatorsID = ourClient.AgentId; + item.inventoryID = LLUUID.Random(); + item.assetID = Asset.FullID; + item.inventoryDescription = this.m_description; + item.inventoryName = m_name; + item.assetType = type; + item.invType = this.invType; + item.parentFolderID = this.InventFolder; + item.inventoryCurrentPermissions = 2147483647; + item.inventoryNextPermissions = this.nextPerm; + + userInfo.AddItem(ourClient.AgentId, item); + ourClient.SendInventoryItemUpdate(item); + } + } + + public void UpdateInventoryItem(LLUUID itemID) + { + + } + } + + public class NoteCardCapsUpdate + { + // Fields + private BaseHttpServer httpListener; + private LLUUID inventoryItemID; + private string m_assetName = ""; + private LLUUID newAssetID; + private bool SaveImages = false; + private string uploaderPath = ""; + + // Events + public event UpLoadedAsset OnUpLoad; + + // Methods + public void Initialise(LLUUID inventoryItem, string path, BaseHttpServer httpServer) + { + this.inventoryItemID = inventoryItem; + this.uploaderPath = path; + this.httpListener = httpServer; + this.newAssetID = LLUUID.Random(); + } + + private void SaveImageToFile(string filename, byte[] data) + { + FileStream output = File.Create(filename); + BinaryWriter writer = new BinaryWriter(output); + writer.Write(data); + writer.Close(); + output.Close(); + } + + public string uploaderCaps(byte[] data, string path, string param) + { + LLUUID inventoryItemID = this.inventoryItemID; + string text = ""; + LLSDAssetUploadComplete complete = new LLSDAssetUploadComplete(); + complete.new_asset = this.newAssetID.ToStringHyphenated(); + complete.new_inventory_item = inventoryItemID; + complete.state = "complete"; + text = LLSDHelpers.SerialiseLLSDReply(complete); + this.httpListener.RemoveStreamHandler("POST", this.uploaderPath); + if (this.SaveImages) + { + this.SaveImageToFile(this.m_assetName + "notecard.txt", data); + } + if (this.OnUpLoad != null) + { + this.OnUpLoad(this.m_assetName, "description", this.newAssetID, inventoryItemID, LLUUID.Zero, data, "" , "" ); + } + return text; + } + } + } +} \ No newline at end of file diff --git a/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs b/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs new file mode 100644 index 0000000000..afffdfcb17 --- /dev/null +++ b/OpenSim/Framework/Communications/Cache/CachedUserInfo.cs @@ -0,0 +1,133 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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; +using System.Collections.Generic; +using System.Text; +using System.IO; +using libsecondlife; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Framework.Data; +using OpenSim.Framework.Utilities; + +namespace OpenSim.Framework.Communications.Caches +{ + public class CachedUserInfo + { + private CommunicationsManager m_parentCommsManager; + // Fields + public InventoryFolder RootFolder = null; + public UserProfileData UserProfile = null; + + public CachedUserInfo(CommunicationsManager commsManager) + { + m_parentCommsManager = commsManager; + } + + // Methods + public void FolderReceive(LLUUID userID, InventoryFolder folderInfo) + { + if (userID == this.UserProfile.UUID) + { + if (this.RootFolder == null) + { + if (folderInfo.parentID == LLUUID.Zero) + { + this.RootFolder = folderInfo; + } + } + else if (this.RootFolder.folderID == folderInfo.parentID) + { + this.RootFolder.SubFolders.Add(folderInfo.folderID, folderInfo); + } + else + { + InventoryFolder folder = this.RootFolder.HasSubFolder(folderInfo.parentID); + if (folder != null) + { + folder.SubFolders.Add(folderInfo.folderID, folderInfo); + } + } + } + } + + public void ItemReceive(LLUUID userID, InventoryItemBase itemInfo) + { + if ((userID == this.UserProfile.UUID) && (this.RootFolder != null)) + { + if (itemInfo.parentFolderID == this.RootFolder.folderID) + { + this.RootFolder.Items.Add(itemInfo.inventoryID, itemInfo); + } + else + { + InventoryFolder folder = this.RootFolder.HasSubFolder(itemInfo.parentFolderID); + if (folder != null) + { + folder.Items.Add(itemInfo.inventoryID, itemInfo); + } + } + } + } + + public void AddItem(LLUUID userID, InventoryItemBase itemInfo) + { + if ((userID == this.UserProfile.UUID) && (this.RootFolder != null)) + { + this.ItemReceive(userID, itemInfo); + this.m_parentCommsManager.InventoryServer.AddNewInventoryItem(userID, itemInfo); + } + } + + public void UpdateItem(LLUUID userID, InventoryItemBase itemInfo) + { + if ((userID == this.UserProfile.UUID) && (this.RootFolder != null)) + { + this.m_parentCommsManager.InventoryServer.AddNewInventoryItem(userID, itemInfo); + } + } + + public bool DeleteItem(LLUUID userID, InventoryItemBase item) + { + bool result = false; + if ((userID == this.UserProfile.UUID) && (this.RootFolder != null)) + { + result = RootFolder.DeleteItem(item.inventoryID); + if (result) + { + this.m_parentCommsManager.InventoryServer.DeleteInventoryItem(userID, item); + } + } + return result; + } + } + + +} + diff --git a/OpenSim/Framework/Communications/Cache/InventoryFolder.cs b/OpenSim/Framework/Communications/Cache/InventoryFolder.cs new file mode 100644 index 0000000000..87f968c6a0 --- /dev/null +++ b/OpenSim/Framework/Communications/Cache/InventoryFolder.cs @@ -0,0 +1,144 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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; +using System.Collections.Generic; +using System.Text; +using System.IO; +using libsecondlife; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Data; +using OpenSim.Framework.Types; +using OpenSim.Framework.Utilities; + +namespace OpenSim.Framework.Communications.Caches +{ + public class InventoryFolder : InventoryFolderBase + { + // Fields + public Dictionary Items = new Dictionary(); + public Dictionary SubFolders = new Dictionary(); + + public InventoryFolder(InventoryFolderBase folderbase) + { + this.agentID = folderbase.agentID; + this.folderID = folderbase.folderID; + this.name = folderbase.name; + this.parentID = folderbase.parentID; + this.type = folderbase.type; + this.version = folderbase.version; + } + + public InventoryFolder() + { + + } + + // Methods + public InventoryFolder CreateNewSubFolder(LLUUID folderID, string folderName, ushort type) + { + InventoryFolder subFold = new InventoryFolder(); + subFold.name = folderName; + subFold.folderID = folderID; + subFold.type = (short) type; + subFold.parentID = this.folderID; + subFold.agentID = this.agentID; + this.SubFolders.Add(subFold.folderID, subFold); + return subFold; + } + + public InventoryItemBase HasItem(LLUUID itemID) + { + InventoryItemBase base2 = null; + if (this.Items.ContainsKey(itemID)) + { + return this.Items[itemID]; + } + foreach (InventoryFolder folder in this.SubFolders.Values) + { + base2 = folder.HasItem(itemID); + if (base2 != null) + { + break; + } + } + return base2; + } + + public bool DeleteItem(LLUUID itemID) + { + bool found = false; + if (this.Items.ContainsKey(itemID)) + { + Items.Remove(itemID); + return true; + } + foreach (InventoryFolder folder in this.SubFolders.Values) + { + found = folder.DeleteItem(itemID); + if (found == true) + { + break; + } + } + return found; + } + + + public InventoryFolder HasSubFolder(LLUUID folderID) + { + InventoryFolder returnFolder = null; + if (this.SubFolders.ContainsKey(folderID)) + { + returnFolder = this.SubFolders[folderID]; + } + else + { + foreach (InventoryFolder folder in this.SubFolders.Values) + { + returnFolder = folder.HasSubFolder(folderID); + if (returnFolder != null) + { + break; + } + } + } + return returnFolder; + } + + public List RequestListOfItems() + { + List itemList = new List(); + foreach (InventoryItemBase item in this.Items.Values) + { + itemList.Add(item); + } + return itemList; + } + } +} diff --git a/OpenSim/Framework/Communications/Cache/LibraryRootFolder.cs b/OpenSim/Framework/Communications/Cache/LibraryRootFolder.cs new file mode 100644 index 0000000000..8d7aba8145 --- /dev/null +++ b/OpenSim/Framework/Communications/Cache/LibraryRootFolder.cs @@ -0,0 +1,213 @@ +using System; +using System.IO; +using System.Collections.Generic; +using System.Text; +using libsecondlife; +using OpenSim.Framework.Utilities; +using OpenSim.Framework.Data; +using Nini.Config; + +namespace OpenSim.Framework.Communications.Caches +{ + public class LibraryRootFolder : InventoryFolder + { + private LLUUID libOwner = new LLUUID("11111111-1111-0000-0000-000100bba000"); + private InventoryFolder m_textureFolder; + + public LibraryRootFolder() + { + this.agentID = libOwner; + this.folderID = new LLUUID("00000112-000f-0000-0000-000100bba000"); + this.name = "OpenSim Library"; + this.parentID = LLUUID.Zero; + this.type = (short)-1; + this.version = (ushort)1; + + InventoryFolder folderInfo = new InventoryFolder(); + folderInfo.agentID = libOwner; + folderInfo.folderID = new LLUUID("00000112-000f-0000-0000-000100bba001"); + folderInfo.name = "Texture Library"; + folderInfo.parentID = this.folderID; + folderInfo.type = -1; + folderInfo.version = 1; + this.SubFolders.Add(folderInfo.folderID, folderInfo); + this.m_textureFolder = folderInfo; + + this.CreateLibraryItems(); + + string filePath = Path.Combine(Util.configDir(), "OpenSimLibrary.xml"); + if (File.Exists(filePath)) + { + XmlConfigSource source = new XmlConfigSource(filePath); + this.ReadItemsFromFile(source); + } + } + + private void CreateLibraryItems() + { + + InventoryItemBase item = new InventoryItemBase(); + item.avatarID = libOwner; + item.creatorsID = libOwner; + item.inventoryID = LLUUID.Random(); + item.assetID = new LLUUID("00000000-0000-0000-9999-000000000002"); + item.inventoryDescription = "Plywood texture"; + item.inventoryName = "Plywood"; + item.assetType = 0; + item.parentFolderID = m_textureFolder.folderID; + item.inventoryBasePermissions = 0x7FFFFFFF; + item.inventoryEveryOnePermissions = 0x7FFFFFFF; + item.inventoryCurrentPermissions = 0x7FFFFFFF; + item.inventoryNextPermissions = 0x7FFFFFFF; + this.m_textureFolder.Items.Add(item.inventoryID, item); + + item = new InventoryItemBase(); + item.avatarID = libOwner; + item.creatorsID = libOwner; + item.inventoryID = LLUUID.Random(); + item.assetID = new LLUUID("00000000-0000-0000-9999-000000000003"); + item.inventoryDescription = "Rocks texture"; + item.inventoryName = "Rocks"; + item.assetType = 0; + item.parentFolderID = m_textureFolder.folderID; + item.inventoryBasePermissions = 0x7FFFFFFF; + item.inventoryEveryOnePermissions = 0x7FFFFFFF; + item.inventoryCurrentPermissions = 0x7FFFFFFF; + item.inventoryNextPermissions = 0x7FFFFFFF; + this.m_textureFolder.Items.Add(item.inventoryID, item); + + item = new InventoryItemBase(); + item.avatarID = libOwner; + item.creatorsID = libOwner; + item.inventoryID = LLUUID.Random(); + item.assetID = new LLUUID("00000000-0000-0000-9999-000000000001"); + item.inventoryDescription = "Bricks texture"; + item.inventoryName = "Bricks"; + item.assetType = 0; + item.parentFolderID = m_textureFolder.folderID; + item.inventoryBasePermissions = 0x7FFFFFFF; + item.inventoryEveryOnePermissions = 0x7FFFFFFF; + item.inventoryCurrentPermissions = 0x7FFFFFFF; + item.inventoryNextPermissions = 0x7FFFFFFF; + this.m_textureFolder.Items.Add(item.inventoryID, item); + + item = new InventoryItemBase(); + item.avatarID = libOwner; + item.creatorsID = libOwner; + item.inventoryID = LLUUID.Random(); + item.assetID = new LLUUID("00000000-0000-0000-9999-000000000004"); + item.inventoryDescription = "Granite texture"; + item.inventoryName = "Granite"; + item.assetType = 0; + item.parentFolderID = m_textureFolder.folderID; + item.inventoryBasePermissions = 0x7FFFFFFF; + item.inventoryEveryOnePermissions = 0x7FFFFFFF; + item.inventoryCurrentPermissions = 0x7FFFFFFF; + item.inventoryNextPermissions = 0x7FFFFFFF; + this.m_textureFolder.Items.Add(item.inventoryID, item); + + item = new InventoryItemBase(); + item.avatarID = libOwner; + item.creatorsID = libOwner; + item.inventoryID = LLUUID.Random(); + item.assetID = new LLUUID("00000000-0000-0000-9999-000000000005"); + item.inventoryDescription = "Hardwood texture"; + item.inventoryName = "Hardwood"; + item.assetType = 0; + item.parentFolderID = m_textureFolder.folderID; + item.inventoryBasePermissions = 0x7FFFFFFF; + item.inventoryEveryOnePermissions = 0x7FFFFFFF; + item.inventoryCurrentPermissions = 0x7FFFFFFF; + item.inventoryNextPermissions = 0x7FFFFFFF; + this.m_textureFolder.Items.Add(item.inventoryID, item); + + item = new InventoryItemBase(); + item.avatarID = libOwner; + item.creatorsID = libOwner; + item.inventoryID = new LLUUID("66c41e39-38f9-f75a-024e-585989bfaba9"); + item.assetID = new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73"); + item.inventoryDescription = "Default Shape"; + item.inventoryName = "Default Shape"; + item.assetType = 13; + item.invType = 18; + item.parentFolderID = this.folderID; + item.inventoryCurrentPermissions = 0; + item.inventoryNextPermissions = 0; + this.Items.Add(item.inventoryID, item); + + item = new InventoryItemBase(); + item.avatarID = libOwner; + item.creatorsID = libOwner; + item.inventoryID = new LLUUID("77c41e39-38f9-f75a-024e-585989bfabc9"); + item.assetID = new LLUUID("77c41e39-38f9-f75a-024e-585989bbabbb"); + item.inventoryDescription = "Default Skin"; + item.inventoryName = "Default Skin"; + item.assetType = 13; + item.invType = 18; + item.parentFolderID = this.folderID; + item.inventoryCurrentPermissions = 0; + item.inventoryNextPermissions = 0; + this.Items.Add(item.inventoryID, item); + + item = new InventoryItemBase(); + item.avatarID = libOwner; + item.creatorsID = libOwner; + item.inventoryID = new LLUUID("77c41e39-38f9-f75a-0000-585989bf0000"); + item.assetID = new LLUUID("00000000-38f9-1111-024e-222222111110"); + item.inventoryDescription = "Default Shirt"; + item.inventoryName = "Default Shirt"; + item.assetType = 5; + item.invType = 18; + item.parentFolderID = this.folderID; + item.inventoryCurrentPermissions = 0; + item.inventoryNextPermissions = 0; + this.Items.Add(item.inventoryID, item); + + item = new InventoryItemBase(); + item.avatarID = libOwner; + item.creatorsID = libOwner; + item.inventoryID = new LLUUID("77c41e39-38f9-f75a-0000-5859892f1111"); + item.assetID = new LLUUID("00000000-38f9-1111-024e-222222111120"); + item.inventoryDescription = "Default Pants"; + item.inventoryName = "Default Pants"; + item.assetType = 5; + item.invType = 18; + item.parentFolderID = this.folderID; + item.inventoryCurrentPermissions = 0; + item.inventoryNextPermissions = 0; + this.Items.Add(item.inventoryID, item); + + } + + private void ReadItemsFromFile(IConfigSource source) + { + for (int i = 0; i < source.Configs.Count; i++) + { + InventoryItemBase item = new InventoryItemBase(); + item.avatarID = libOwner; + item.creatorsID = libOwner; + item.inventoryID = new LLUUID(source.Configs[i].GetString("inventoryID", LLUUID.Random().ToStringHyphenated())); + item.assetID = new LLUUID(source.Configs[i].GetString("assetID", LLUUID.Random().ToStringHyphenated())); + item.inventoryDescription = source.Configs[i].GetString("description", ""); + item.inventoryName = source.Configs[i].GetString("name", ""); + item.assetType = source.Configs[i].GetInt("assetType", 0); + item.invType = source.Configs[i].GetInt("inventoryType", 0); + item.inventoryCurrentPermissions = (uint)source.Configs[i].GetLong("currentPermissions", 0x7FFFFFFF); + item.inventoryNextPermissions = (uint)source.Configs[i].GetLong("nextPermissions", 0x7FFFFFFF); + item.inventoryEveryOnePermissions = (uint)source.Configs[i].GetLong("everyonePermissions", 0x7FFFFFFF); + item.inventoryBasePermissions = (uint)source.Configs[i].GetLong("basePermissions", 0x7FFFFFFF); + if (item.assetType == 0) + { + item.parentFolderID = this.m_textureFolder.folderID; + this.m_textureFolder.Items.Add(item.inventoryID, item); + } + else + { + item.parentFolderID = this.folderID; + this.Items.Add(item.inventoryID, item); + } + } + } + + } +} diff --git a/OpenSim/Framework/Communications/Cache/UserProfileCache.cs b/OpenSim/Framework/Communications/Cache/UserProfileCache.cs new file mode 100644 index 0000000000..dcb91743ae --- /dev/null +++ b/OpenSim/Framework/Communications/Cache/UserProfileCache.cs @@ -0,0 +1,234 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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; +using System.Collections.Generic; +using System.Text; +using System.IO; +using libsecondlife; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Framework.Utilities; +using OpenSim.Framework.Data; + +namespace OpenSim.Framework.Communications.Caches +{ + public class UserProfileCache + { + // Fields + private CommunicationsManager m_parent; + public Dictionary UserProfiles = new Dictionary(); + + public LibraryRootFolder libraryRoot = new LibraryRootFolder(); + + // Methods + public UserProfileCache(CommunicationsManager parent) + { + this.m_parent = parent; + } + + /// + /// A new user has moved into a region in this instance + /// so get info from servers + /// + /// + public void AddNewUser(LLUUID userID) + { + if (!this.UserProfiles.ContainsKey(userID)) + { + CachedUserInfo userInfo = new CachedUserInfo(this.m_parent); + userInfo.UserProfile = this.RequestUserProfileForUser(userID); + if (userInfo.UserProfile != null) + { + this.RequestInventoryForUser(userID, userInfo); + this.UserProfiles.Add(userID, userInfo); + } + else + { + Console.WriteLine("CACHE", "User profile for user not found"); + } + } + } + + /// + /// A new user has moved into a region in this instance + /// so get info from servers + /// + /// + /// + public void AddNewUser(string firstName, string lastName) + { + } + + public CachedUserInfo GetUserDetails(LLUUID userID) + { + if (this.UserProfiles.ContainsKey(userID)) + { + return this.UserProfiles[userID]; + } + return null; + } + + public void HandleCreateInventoryFolder(IClientAPI remoteClient, LLUUID folderID, ushort folderType, string folderName, LLUUID parentID) + { + if (this.UserProfiles.ContainsKey(remoteClient.AgentId)) + { + if (this.UserProfiles[remoteClient.AgentId].RootFolder != null) + { + CachedUserInfo info = this.UserProfiles[remoteClient.AgentId]; + if (info.RootFolder.folderID == parentID) + { + InventoryFolder createdFolder = info.RootFolder.CreateNewSubFolder(folderID, folderName, folderType); + if (createdFolder != null) + { + this.m_parent.InventoryServer.AddNewInventoryFolder(remoteClient.AgentId, createdFolder); + } + } + else + { + InventoryFolder folder = info.RootFolder.HasSubFolder(parentID); + if (folder != null) + { + folder.CreateNewSubFolder(folderID, folderName, folderType); + } + } + } + } + } + + public void HandleFecthInventoryDescendents(IClientAPI remoteClient, LLUUID folderID, LLUUID ownerID, bool fetchFolders, bool fetchItems, int sortOrder) + { + InventoryFolder fold = null; + if (folderID == libraryRoot.folderID ) + { + remoteClient.SendInventoryFolderDetails(libraryRoot.agentID, libraryRoot.folderID, libraryRoot.RequestListOfItems()); + } + else if (( fold = libraryRoot.HasSubFolder(folderID)) != null) + { + remoteClient.SendInventoryFolderDetails(libraryRoot.agentID, folderID, fold.RequestListOfItems()); + } + else if (this.UserProfiles.ContainsKey(remoteClient.AgentId)) + { + if (this.UserProfiles[remoteClient.AgentId].RootFolder != null) + { + CachedUserInfo info = this.UserProfiles[remoteClient.AgentId]; + if (info.RootFolder.folderID == folderID) + { + if (fetchItems) + { + remoteClient.SendInventoryFolderDetails(remoteClient.AgentId, folderID, info.RootFolder.RequestListOfItems()); + } + } + else + { + InventoryFolder folder = info.RootFolder.HasSubFolder(folderID); + if ((folder != null) && fetchItems) + { + remoteClient.SendInventoryFolderDetails(remoteClient.AgentId, folderID, folder.RequestListOfItems()); + } + } + } + } + } + + public void HandleFetchInventory(IClientAPI remoteClient, LLUUID itemID, LLUUID ownerID) + { + if (ownerID == libraryRoot.agentID) + { + //Console.WriteLine("request info for library item"); + } + else if (this.UserProfiles.ContainsKey(remoteClient.AgentId)) + { + if (this.UserProfiles[remoteClient.AgentId].RootFolder != null) + { + InventoryItemBase item = this.UserProfiles[remoteClient.AgentId].RootFolder.HasItem(itemID); + if (item != null) + { + remoteClient.SendInventoryItemDetails(ownerID, item); + } + } + } + } + + /// + /// Request Iventory Info from Inventory server + /// + /// + private void RequestInventoryForUser(LLUUID userID, CachedUserInfo userInfo) + { + this.m_parent.InventoryServer.RequestInventoryForUser(userID, userInfo.FolderReceive, userInfo.ItemReceive); + + //for now we manually create the root folder, + // but should be requesting all inventory from inventory server. + /* InventoryFolder folderInfo = new InventoryFolder(); + folderInfo.agentID = userID; + folderInfo.folderID = userInfo.UserProfile.rootInventoryFolderID; + folderInfo.name = "My Inventory"; + folderInfo.parentID = LLUUID.Zero; + folderInfo.type = 8; + folderInfo.version = 1; + userInfo.FolderReceive(userID, folderInfo);*/ + } + + /// + /// Request the user profile from User server + /// + /// + private UserProfileData RequestUserProfileForUser(LLUUID userID) + { + return this.m_parent.UserServer.GetUserProfile(userID); + } + + /// + /// Update Inventory data to Inventory server + /// + /// + private void UpdateInventoryToServer(LLUUID userID) + { + } + + /// + /// Make sure UserProfile is updated on user server + /// + /// + private void UpdateUserProfileToServer(LLUUID userID) + { + } + + /// + /// A user has left this instance + /// so make sure servers have been updated + /// Then remove cached info + /// + /// + public void UserLogOut(LLUUID userID) + { + } + } +} + diff --git a/OpenSim/Framework/Communications/Capabilities/Caps.cs b/OpenSim/Framework/Communications/Capabilities/Caps.cs new file mode 100644 index 0000000000..4df4937136 --- /dev/null +++ b/OpenSim/Framework/Communications/Capabilities/Caps.cs @@ -0,0 +1,502 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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; +using System.Collections.Generic; +using System.Text; +using System.IO; +using libsecondlife; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Types; +using OpenSim.Framework.Utilities; +using OpenSim.Framework.Communications.Caches; +using OpenSim.Framework.Data; + +namespace OpenSim.Region.Capabilities +{ + public delegate void UpLoadedAsset(string assetName, string description, LLUUID assetID, LLUUID inventoryItem, LLUUID parentFolder, byte[] data, string inventoryType, string assetType); + public delegate LLUUID UpdateItem(LLUUID itemID, byte[] data); + public delegate void NewInventoryItem(LLUUID userID, InventoryItemBase item); + public delegate LLUUID ItemUpdatedCallback(LLUUID userID, LLUUID itemID, byte[] data); + + public class Caps + { + private string m_httpListenerHostName; + private int m_httpListenPort; + private string m_capsObjectPath = "00001-"; + private string m_requestPath = "0000/"; + private string m_mapLayerPath = "0001/"; + private string m_newInventory = "0002/"; + //private string m_requestTexture = "0003/"; + private string m_notecardUpdatePath = "0004/"; + //private string eventQueue = "0100/"; + private BaseHttpServer httpListener; + private LLUUID agentID; + private AssetCache assetCache; + private int eventQueueCount = 1; + private Queue CapsEventQueue = new Queue(); + public NewInventoryItem AddNewInventoryItem = null; + public ItemUpdatedCallback ItemUpdatedCall = null; + + public Caps(AssetCache assetCach, BaseHttpServer httpServer, string httpListen, int httpPort, string capsPath, LLUUID agent) + { + assetCache = assetCach; + m_capsObjectPath = capsPath; + httpListener = httpServer; + m_httpListenerHostName = httpListen; + m_httpListenPort = httpPort; + agentID = agent; + } + + /// + /// + /// + public void RegisterHandlers() + { + Console.WriteLine("registering CAPS handlers"); + string capsBase = "/CAPS/" + m_capsObjectPath; + try + { + httpListener.AddStreamHandler(new LLSDStreamhandler("POST", capsBase + m_mapLayerPath, this.GetMapLayer)); + httpListener.AddStreamHandler(new LLSDStreamhandler("POST", capsBase + m_newInventory, this.NewAgentInventoryRequest)); + + AddLegacyCapsHandler(httpListener, m_requestPath, CapsRequest); + //AddLegacyCapsHandler(httpListener, m_requestTexture , RequestTexture); + AddLegacyCapsHandler(httpListener, m_notecardUpdatePath, NoteCardAgentInventory); + } + catch + { + } + } + + + //[Obsolete("Use BaseHttpServer.AddStreamHandler(new LLSDStreamHandler( LLSDMethod delegate )) instead.")] + //Commented out the obsolete as at this time the first caps request can not use the new Caps method + //as the sent type is a array and not a map and the deserialising doesn't deal properly with arrays. + private void AddLegacyCapsHandler(BaseHttpServer httpListener, string path, RestMethod restMethod) + { + string capsBase = "/CAPS/" + m_capsObjectPath; + httpListener.AddStreamHandler(new RestStreamHandler("POST", capsBase + path, restMethod)); + } + + /// + /// + /// + /// + /// + /// + /// + public string CapsRequest(string request, string path, string param) + { + // Console.WriteLine("caps request " + request); + string result = LLSDHelpers.SerialiseLLSDReply(this.GetCapabilities()); + return result; + } + + /// + /// + /// + /// + protected LLSDCapsDetails GetCapabilities() + { + LLSDCapsDetails caps = new LLSDCapsDetails(); + string capsBaseUrl = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + "/CAPS/" + m_capsObjectPath; + caps.MapLayer = capsBaseUrl + m_mapLayerPath; + caps.NewFileAgentInventory = capsBaseUrl + m_newInventory; + caps.UpdateNotecardAgentInventory = capsBaseUrl + m_notecardUpdatePath; + caps.UpdateScriptAgentInventory = capsBaseUrl + m_notecardUpdatePath; + return caps; + } + + /// + /// + /// + /// + /// + public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq) + { + LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse(); + mapResponse.LayerData.Array.Add(this.GetLLSDMapLayerResponse()); + return mapResponse; + } + + /// + /// + /// + /// + protected LLSDMapLayer GetLLSDMapLayerResponse() + { + LLSDMapLayer mapLayer = new LLSDMapLayer(); + mapLayer.Right = 5000; + mapLayer.Top = 5000; + mapLayer.ImageID = new LLUUID("00000000-0000-0000-9999-000000000006"); + return mapLayer; + } + + /// + /// + /// + /// + /// + /// + /// + public string RequestTexture(string request, string path, string param) + { + Console.WriteLine("texture request " + request); + // Needs implementing (added to remove compiler warning) + return ""; + } + + #region EventQueue (Currently not enabled) + /// + /// + /// + /// + /// + /// + /// + public string ProcessEventQueue(string request, string path, string param) + { + string res = ""; + + if (this.CapsEventQueue.Count > 0) + { + lock (this.CapsEventQueue) + { + string item = CapsEventQueue.Dequeue(); + res = item; + } + } + else + { + res = this.CreateEmptyEventResponse(); + } + return res; + } + + /// + /// + /// + /// + /// + /// + public string CreateEstablishAgentComms(string caps, string ipAddressPort) + { + LLSDCapEvent eventItem = new LLSDCapEvent(); + eventItem.id = eventQueueCount; + //should be creating a EstablishAgentComms item, but there isn't a class for it yet + eventItem.events.Array.Add(new LLSDEmpty()); + string res = LLSDHelpers.SerialiseLLSDReply(eventItem); + eventQueueCount++; + + this.CapsEventQueue.Enqueue(res); + return res; + } + + /// + /// + /// + /// + public string CreateEmptyEventResponse() + { + LLSDCapEvent eventItem = new LLSDCapEvent(); + eventItem.id = eventQueueCount; + eventItem.events.Array.Add(new LLSDEmpty()); + string res = LLSDHelpers.SerialiseLLSDReply(eventItem); + eventQueueCount++; + return res; + } + #endregion + + /// + /// + /// + /// + /// + /// + /// + public string NoteCardAgentInventory(string request, string path, string param) + { + Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Helpers.StringToField(request)); + LLSDItemUpdate llsdRequest = new LLSDItemUpdate(); + LLSDHelpers.DeserialiseLLSDMap(hash, llsdRequest); + + string capsBase = "/CAPS/" + m_capsObjectPath; + LLUUID newInvItem = llsdRequest.item_id; + string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); + + ItemUpdater uploader = new ItemUpdater(newInvItem, capsBase + uploaderPath, this.httpListener); + uploader.OnUpLoad += this.ItemUpdated; + + httpListener.AddStreamHandler(new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); + string uploaderURL = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase + uploaderPath; + + LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); + uploadResponse.uploader = uploaderURL; + uploadResponse.state = "upload"; + + return LLSDHelpers.SerialiseLLSDReply(uploadResponse); + } + + /// + /// + /// + /// + /// + public LLSDAssetUploadResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest) + { + //Console.WriteLine("asset upload request via CAPS" + llsdRequest.inventory_type +" , "+ llsdRequest.asset_type); + + string assetName = llsdRequest.name; + string assetDes = llsdRequest.description; + string capsBase = "/CAPS/" + m_capsObjectPath; + LLUUID newAsset = LLUUID.Random(); + LLUUID newInvItem = LLUUID.Random(); + LLUUID parentFolder = llsdRequest.folder_id; + string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); + + AssetUploader uploader = new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, llsdRequest.asset_type, capsBase + uploaderPath, this.httpListener); + httpListener.AddStreamHandler(new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); + string uploaderURL = "http://" + m_httpListenerHostName + ":" + m_httpListenPort.ToString() + capsBase + uploaderPath; + + LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse(); + uploadResponse.uploader = uploaderURL; + uploadResponse.state = "upload"; + uploader.OnUpLoad += this.UploadCompleteHandler; + return uploadResponse; + } + + /// + /// + /// + /// + /// + /// + public void UploadCompleteHandler(string assetName, string assetDescription, LLUUID assetID, LLUUID inventoryItem, LLUUID parentFolder, byte[] data, string inventoryType, string assetType) + { + sbyte assType = 0; + sbyte inType = 0; + + if (inventoryType == "sound") + { + inType = 1; + assType = 1; + } + else if (inventoryType == "animation") + { + inType = 19; + assType = 19; + } + + AssetBase asset; + asset = new AssetBase(); + asset.FullID = assetID; + asset.Type = assType; + asset.InvType = inType; + asset.Name = assetName; + asset.Data = data; + this.assetCache.AddAsset(asset); + + InventoryItemBase item = new InventoryItemBase(); + item.avatarID = agentID; + item.creatorsID = agentID; + item.inventoryID = inventoryItem; + item.assetID = asset.FullID; + item.inventoryDescription = assetDescription; + item.inventoryName = assetName; + item.assetType = assType; + item.invType = inType; + item.parentFolderID = parentFolder; + item.inventoryCurrentPermissions = 2147483647; + item.inventoryNextPermissions = 2147483647; + + if (AddNewInventoryItem != null) + { + AddNewInventoryItem(agentID, item); + } + + } + + public LLUUID ItemUpdated(LLUUID itemID, byte[] data) + { + if (ItemUpdatedCall != null) + { + return ItemUpdatedCall(this.agentID, itemID, data); + } + return LLUUID.Zero; + } + + public class AssetUploader + { + public event UpLoadedAsset OnUpLoad; + + private string uploaderPath = ""; + private LLUUID newAssetID; + private LLUUID inventoryItemID; + private LLUUID parentFolder; + private BaseHttpServer httpListener; + private bool SaveAssets = false; + private string m_assetName = ""; + private string m_assetDes = ""; + + private string m_invType = ""; + private string m_assetType = ""; + + /// + /// + /// + /// + /// + /// + /// + public AssetUploader(string assetName, string description, LLUUID assetID, LLUUID inventoryItem, LLUUID parentFolderID, string invType, string assetType, string path, BaseHttpServer httpServer) + { + m_assetName = assetName; + m_assetDes = description; + newAssetID = assetID; + inventoryItemID = inventoryItem; + uploaderPath = path; + httpListener = httpServer; + parentFolder = parentFolderID; + m_assetType = assetType; + m_invType = invType; + + } + + /// + /// + /// + /// + /// + /// + /// + public string uploaderCaps(byte[] data, string path, string param) + { + LLUUID inv = this.inventoryItemID; + string res = ""; + LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); + uploadComplete.new_asset = newAssetID.ToStringHyphenated(); + uploadComplete.new_inventory_item = inv; + uploadComplete.state = "complete"; + + res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); + + httpListener.RemoveStreamHandler("POST", uploaderPath); + + if(this.SaveAssets) + this.SaveAssetToFile(m_assetName + ".jp2", data); + + if (OnUpLoad != null) + { + OnUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType); + } + + return res; + } + + private void SaveAssetToFile(string filename, byte[] data) + { + FileStream fs = File.Create(filename); + BinaryWriter bw = new BinaryWriter(fs); + bw.Write(data); + bw.Close(); + fs.Close(); + } + } + + public class ItemUpdater + { + public event UpdateItem OnUpLoad; + + private string uploaderPath = ""; + private LLUUID inventoryItemID; + private BaseHttpServer httpListener; + private bool SaveAssets = false; + + + /// + /// + /// + /// + /// + /// + /// + public ItemUpdater( LLUUID inventoryItem, string path, BaseHttpServer httpServer) + { + + inventoryItemID = inventoryItem; + uploaderPath = path; + httpListener = httpServer; + } + + /// + /// + /// + /// + /// + /// + /// + public string uploaderCaps(byte[] data, string path, string param) + { + LLUUID inv = this.inventoryItemID; + string res = ""; + LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); + LLUUID assetID = LLUUID.Zero; + + if (OnUpLoad != null) + { + assetID = OnUpLoad(inv, data); + } + + uploadComplete.new_asset = assetID.ToStringHyphenated(); + uploadComplete.new_inventory_item = inv; + uploadComplete.state = "complete"; + + res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); + + httpListener.RemoveStreamHandler("POST", uploaderPath); + + if (this.SaveAssets) + this.SaveAssetToFile("updateditem"+Util.RandomClass.Next(1,1000) + ".dat", data); + + return res; + } + + private void SaveAssetToFile(string filename, byte[] data) + { + FileStream fs = File.Create(filename); + BinaryWriter bw = new BinaryWriter(fs); + bw.Write(data); + bw.Close(); + fs.Close(); + } + } + } +} + + diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDArray.cs b/OpenSim/Framework/Communications/Capabilities/LLSDArray.cs new file mode 100644 index 0000000000..e04849f372 --- /dev/null +++ b/OpenSim/Framework/Communications/Capabilities/LLSDArray.cs @@ -0,0 +1,42 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Collections; + +namespace OpenSim.Region.Capabilities +{ + [LLSDType("ARRAY")] + public class LLSDArray + { + public ArrayList Array = new ArrayList(); + + public LLSDArray() + { + + } + } +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDAssetUploadComplete.cs b/OpenSim/Framework/Communications/Capabilities/LLSDAssetUploadComplete.cs new file mode 100644 index 0000000000..ce373c0f25 --- /dev/null +++ b/OpenSim/Framework/Communications/Capabilities/LLSDAssetUploadComplete.cs @@ -0,0 +1,45 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; + +namespace OpenSim.Region.Capabilities +{ + [LLSDType("MAP")] + public class LLSDAssetUploadComplete + { + public string new_asset = ""; + public LLUUID new_inventory_item = LLUUID.Zero; + public string state = ""; + //public bool success = false; + + public LLSDAssetUploadComplete() + { + + } + } +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDAssetUploadRequest.cs b/OpenSim/Framework/Communications/Capabilities/LLSDAssetUploadRequest.cs new file mode 100644 index 0000000000..7ef77cbfa7 --- /dev/null +++ b/OpenSim/Framework/Communications/Capabilities/LLSDAssetUploadRequest.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; +using libsecondlife; + +namespace OpenSim.Region.Capabilities +{ + [LLSDMap] + public class LLSDAssetUploadRequest + { + public string asset_type = ""; + public string description = ""; + public LLUUID folder_id = LLUUID.Zero; + public string inventory_type = ""; + public string name = ""; + + public LLSDAssetUploadRequest() + { + } + } +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDAssetUploadResponse.cs b/OpenSim/Framework/Communications/Capabilities/LLSDAssetUploadResponse.cs new file mode 100644 index 0000000000..1a620aed3b --- /dev/null +++ b/OpenSim/Framework/Communications/Capabilities/LLSDAssetUploadResponse.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Region.Capabilities +{ + [LLSDMap] + public class LLSDAssetUploadResponse + { + public string uploader = ""; + public string state = ""; + + public LLSDAssetUploadResponse() + { + + } + } +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDCapEvent.cs b/OpenSim/Framework/Communications/Capabilities/LLSDCapEvent.cs new file mode 100644 index 0000000000..51b4fe079c --- /dev/null +++ b/OpenSim/Framework/Communications/Capabilities/LLSDCapEvent.cs @@ -0,0 +1,41 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +namespace OpenSim.Region.Capabilities +{ + [LLSDType("MAP")] + public class LLSDCapEvent + { + public int id = 0; + public LLSDArray events = new LLSDArray(); + + public LLSDCapEvent() + { + + } + } +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDCapsDetails.cs b/OpenSim/Framework/Communications/Capabilities/LLSDCapsDetails.cs new file mode 100644 index 0000000000..c6c87f56ac --- /dev/null +++ b/OpenSim/Framework/Communications/Capabilities/LLSDCapsDetails.cs @@ -0,0 +1,22 @@ +namespace OpenSim.Region.Capabilities +{ + [LLSDType("MAP")] + public class LLSDCapsDetails + { + public string MapLayer = ""; + public string NewFileAgentInventory = ""; + //public string EventQueueGet = ""; + // public string RequestTextureDownload = ""; + // public string ChatSessionRequest = ""; + public string UpdateNotecardAgentInventory = ""; + public string UpdateScriptAgentInventory = ""; + // public string ParcelVoiceInfoRequest = ""; + + public LLSDCapsDetails() + { + + } + } +} + + diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDEmpty.cs b/OpenSim/Framework/Communications/Capabilities/LLSDEmpty.cs new file mode 100644 index 0000000000..d79c09e813 --- /dev/null +++ b/OpenSim/Framework/Communications/Capabilities/LLSDEmpty.cs @@ -0,0 +1,38 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +namespace OpenSim.Region.Capabilities +{ + [LLSDType("MAP")] + public class LLSDEmpty + { + public LLSDEmpty() + { + + } + } +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDHelpers.cs b/OpenSim/Framework/Communications/Capabilities/LLSDHelpers.cs new file mode 100644 index 0000000000..19ef0c9910 --- /dev/null +++ b/OpenSim/Framework/Communications/Capabilities/LLSDHelpers.cs @@ -0,0 +1,164 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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; +using System.IO; +using System.Reflection; +using System.Xml; +using libsecondlife; + +namespace OpenSim.Region.Capabilities +{ + public class LLSDHelpers + { + public static string SerialiseLLSDReply(object obj) + { + StringWriter sw = new StringWriter(); + XmlTextWriter writer = new XmlTextWriter(sw); + writer.Formatting = Formatting.None; + writer.WriteStartElement(String.Empty, "llsd", String.Empty); + SerializeLLSDType(writer, obj); + writer.WriteEndElement(); + writer.Close(); + return sw.ToString(); + } + + public static void SerializeLLSDType(XmlTextWriter writer, object obj) + { + Type myType = obj.GetType(); + LLSDType[] llsdattributes = (LLSDType[])myType.GetCustomAttributes(typeof(LLSDType), false); + if (llsdattributes.Length > 0) + { + switch (llsdattributes[0].ObjectType) + { + case "MAP": + writer.WriteStartElement(String.Empty, "map", String.Empty); + FieldInfo[] fields = myType.GetFields(); + for (int i = 0; i < fields.Length; i++) + { + object fieldValue = fields[i].GetValue(obj); + LLSDType[] fieldAttributes = (LLSDType[])fieldValue.GetType().GetCustomAttributes(typeof(LLSDType), false); + if (fieldAttributes.Length > 0) + { + writer.WriteStartElement(String.Empty, "key", String.Empty); + writer.WriteString(fields[i].Name); + writer.WriteEndElement(); + SerializeLLSDType(writer, fieldValue); + } + else + { + writer.WriteStartElement(String.Empty, "key", String.Empty); + writer.WriteString(fields[i].Name); + writer.WriteEndElement(); + LLSD.LLSDWriteOne(writer, fieldValue); + } + } + writer.WriteEndElement(); + break; + case "ARRAY": + // LLSDArray arrayObject = obj as LLSDArray; + // ArrayList a = arrayObject.Array; + ArrayList a = (ArrayList)obj.GetType().GetField("Array").GetValue(obj); + if (a != null) + { + writer.WriteStartElement(String.Empty, "array", String.Empty); + foreach (object item in a) + { + SerializeLLSDType(writer, item); + } + writer.WriteEndElement(); + } + break; + } + } + else + { + LLSD.LLSDWriteOne(writer, obj); + } + } + + public static object DeserialiseLLSDMap(Hashtable llsd, object obj) + { + Type myType = obj.GetType(); + LLSDType[] llsdattributes = (LLSDType[])myType.GetCustomAttributes(typeof(LLSDType), false); + if (llsdattributes.Length > 0) + { + switch (llsdattributes[0].ObjectType) + { + case "MAP": + IDictionaryEnumerator enumerator = llsd.GetEnumerator(); + while (enumerator.MoveNext()) + { + FieldInfo field = myType.GetField((string)enumerator.Key); + if (field != null) + { + if (enumerator.Value is Hashtable) + { + object fieldValue = field.GetValue(obj); + DeserialiseLLSDMap((Hashtable) enumerator.Value, fieldValue); + } + else if (enumerator.Value is ArrayList) + { + object fieldValue = field.GetValue(obj); + fieldValue.GetType().GetField("Array").SetValue(fieldValue, enumerator.Value); + //TODO + // the LLSD map/array types in the array need to be deserialised + // but first we need to know the right class to deserialise them into. + } + else + { + field.SetValue(obj, enumerator.Value); + } + } + } + break; + } + } + return obj; + } + } + + + + + + + + + + + + + + + + + + + +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDItemUpdate.cs b/OpenSim/Framework/Communications/Capabilities/LLSDItemUpdate.cs new file mode 100644 index 0000000000..d47bb0705e --- /dev/null +++ b/OpenSim/Framework/Communications/Capabilities/LLSDItemUpdate.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; +using libsecondlife; + +namespace OpenSim.Region.Capabilities +{ + [LLSDMap] + public class LLSDItemUpdate + { + public LLUUID item_id; + + public LLSDItemUpdate() + { + } + } +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDMapLayer.cs b/OpenSim/Framework/Communications/Capabilities/LLSDMapLayer.cs new file mode 100644 index 0000000000..566d0e9085 --- /dev/null +++ b/OpenSim/Framework/Communications/Capabilities/LLSDMapLayer.cs @@ -0,0 +1,46 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; + +namespace OpenSim.Region.Capabilities +{ + [LLSDType("MAP")] + public class LLSDMapLayer + { + public int Left = 0; + public int Right = 0; + public int Top = 0; + public int Bottom = 0; + public LLUUID ImageID = LLUUID.Zero; + + public LLSDMapLayer() + { + + } + } +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDMapLayerResponse.cs b/OpenSim/Framework/Communications/Capabilities/LLSDMapLayerResponse.cs new file mode 100644 index 0000000000..ce746ae82e --- /dev/null +++ b/OpenSim/Framework/Communications/Capabilities/LLSDMapLayerResponse.cs @@ -0,0 +1,41 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +namespace OpenSim.Region.Capabilities +{ + [LLSDType("MAP")] + public class LLSDMapLayerResponse + { + public LLSDMapRequest AgentData = new LLSDMapRequest(); + public LLSDArray LayerData = new LLSDArray(); + + public LLSDMapLayerResponse() + { + + } + } +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDMapRequest.cs b/OpenSim/Framework/Communications/Capabilities/LLSDMapRequest.cs new file mode 100644 index 0000000000..fb739cd04e --- /dev/null +++ b/OpenSim/Framework/Communications/Capabilities/LLSDMapRequest.cs @@ -0,0 +1,13 @@ +namespace OpenSim.Region.Capabilities +{ + [LLSDType("MAP")] + public class LLSDMapRequest + { + public int Flags = 0; + + public LLSDMapRequest() + { + + } + } +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDMethod.cs b/OpenSim/Framework/Communications/Capabilities/LLSDMethod.cs new file mode 100644 index 0000000000..5f42f446cc --- /dev/null +++ b/OpenSim/Framework/Communications/Capabilities/LLSDMethod.cs @@ -0,0 +1,8 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Region.Capabilities +{ + public delegate TResponse LLSDMethod(TRequest request); +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDStreamHandler.cs b/OpenSim/Framework/Communications/Capabilities/LLSDStreamHandler.cs new file mode 100644 index 0000000000..7d99b6eeff --- /dev/null +++ b/OpenSim/Framework/Communications/Capabilities/LLSDStreamHandler.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Text; +using OpenSim.Framework.Servers; +using System.IO; +using System.Collections; +using libsecondlife; + +namespace OpenSim.Region.Capabilities +{ + public class LLSDStreamhandler : BaseStreamHandler + where TRequest : new() + { + private LLSDMethod m_method; + + public LLSDStreamhandler(string httpMethod, string path, LLSDMethod method) + : base(httpMethod, path ) + { + m_method = method; + } + + public override byte[] Handle(string path, Stream request) + { + //Encoding encoding = Encoding.UTF8; + //StreamReader streamReader = new StreamReader(request, false); + + //string requestBody = streamReader.ReadToEnd(); + //streamReader.Close(); + + Hashtable hash = (Hashtable)LLSD.LLSDDeserialize( request ); + TRequest llsdRequest = new TRequest(); + LLSDHelpers.DeserialiseLLSDMap(hash, llsdRequest); + + TResponse response = m_method(llsdRequest); + + Encoding encoding = new UTF8Encoding(false); + + return encoding.GetBytes( LLSDHelpers.SerialiseLLSDReply(response) ); + + } + } +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDTest.cs b/OpenSim/Framework/Communications/Capabilities/LLSDTest.cs new file mode 100644 index 0000000000..f23e327b8d --- /dev/null +++ b/OpenSim/Framework/Communications/Capabilities/LLSDTest.cs @@ -0,0 +1,41 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +namespace OpenSim.Region.Capabilities +{ + [LLSDType("MAP")] + public class LLSDTest + { + public int Test1 = 20; + public int Test2 = 10; + + public LLSDTest() + { + + } + } +} diff --git a/OpenSim/Framework/Communications/Capabilities/LLSDType.cs b/OpenSim/Framework/Communications/Capabilities/LLSDType.cs new file mode 100644 index 0000000000..c58a9376bd --- /dev/null +++ b/OpenSim/Framework/Communications/Capabilities/LLSDType.cs @@ -0,0 +1,59 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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; + +namespace OpenSim.Region.Capabilities +{ + [AttributeUsage(AttributeTargets.Class)] + public class LLSDType : Attribute + { + protected string myType; + + public LLSDType(string type) + { + myType = type; + + } + + public string ObjectType + { + get + { + return myType; + } + } + } + + [AttributeUsage(AttributeTargets.Class)] + public class LLSDMap : LLSDType + { + public LLSDMap() : base( "MAP" ) + { + } + } +} diff --git a/OpenSim/Framework/Communications/CommunicationsManager.cs b/OpenSim/Framework/Communications/CommunicationsManager.cs new file mode 100644 index 0000000000..0e5e31dfc9 --- /dev/null +++ b/OpenSim/Framework/Communications/CommunicationsManager.cs @@ -0,0 +1,83 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Data; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Communications.Caches; + + +namespace OpenSim.Framework.Communications +{ + + public class CommunicationsManager + { + public IUserServices UserServer; + public IGridServices GridServer; + public IInventoryServices InventoryServer; + public IInterRegionCommunications InterRegion; + public UserProfileCache UserProfiles; + public AssetTransactionManager TransactionsManager; + public AssetCache AssetCache; + + public NetworkServersInfo ServersInfo; + public CommunicationsManager(NetworkServersInfo serversInfo, BaseHttpServer httpServer, AssetCache assetCache) + { + ServersInfo = serversInfo; + this.AssetCache = assetCache; + UserProfiles = new UserProfileCache(this); + TransactionsManager = new AssetTransactionManager(this); + } + + #region Packet Handlers + public void HandleUUIDNameRequest(LLUUID uuid, IClientAPI remote_client) + { + if (uuid == UserProfiles.libraryRoot.agentID) + { + remote_client.SendNameReply(uuid , "Mr" , "OpenSim"); + } + else + { + UserProfileData profileData = this.UserServer.GetUserProfile(uuid); + if (profileData != null) + { + LLUUID profileId = profileData.UUID; + string firstname = profileData.username; + string lastname = profileData.surname; + + remote_client.SendNameReply(profileId, firstname, lastname); + } + } + } + + #endregion + } +} diff --git a/OpenSim/Framework/Communications/IGridServices.cs b/OpenSim/Framework/Communications/IGridServices.cs new file mode 100644 index 0000000000..d2e5ab69f0 --- /dev/null +++ b/OpenSim/Framework/Communications/IGridServices.cs @@ -0,0 +1,41 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Collections.Generic; +using OpenSim.Framework.Types; + +namespace OpenSim.Framework.Communications +{ + public interface IGridServices + { + RegionCommsListener RegisterRegion(RegionInfo regionInfos); + List RequestNeighbours(RegionInfo regionInfo); + RegionInfo RequestNeighbourInfo(ulong regionHandle); + List RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY); + } +} diff --git a/OpenSim/Framework/Communications/IInterRegionCommunications.cs b/OpenSim/Framework/Communications/IInterRegionCommunications.cs new file mode 100644 index 0000000000..406cf1d8db --- /dev/null +++ b/OpenSim/Framework/Communications/IInterRegionCommunications.cs @@ -0,0 +1,39 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; +using OpenSim.Framework.Types; + +namespace OpenSim.Framework.Communications +{ + public interface IInterRegionCommunications + { + bool InformRegionOfChildAgent(ulong regionHandle, AgentCircuitData agentData); + bool ExpectAvatarCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying); + bool AcknowledgeAgentCrossed(ulong regionHandle, LLUUID agentID); + } +} diff --git a/OpenSim/Framework/Communications/IInventoryServices.cs b/OpenSim/Framework/Communications/IInventoryServices.cs new file mode 100644 index 0000000000..0cdc3bf273 --- /dev/null +++ b/OpenSim/Framework/Communications/IInventoryServices.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; +using OpenSim.Framework.Data; +using libsecondlife; +using OpenSim.Framework.Communications.Caches; +using InventoryFolder = OpenSim.Framework.Communications.Caches.InventoryFolder; + +namespace OpenSim.Framework.Communications +{ + public delegate void InventoryFolderInfo(LLUUID userID, InventoryFolder folderInfo); + public delegate void InventoryItemInfo(LLUUID userID, InventoryItemBase itemInfo); + + public interface IInventoryServices + { + void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack, InventoryItemInfo itemCallBack); + void AddNewInventoryFolder(LLUUID userID, InventoryFolder folder); + void AddNewInventoryItem(LLUUID userID, InventoryItemBase item); + void DeleteInventoryItem(LLUUID userID, InventoryItemBase item); + } +} diff --git a/OpenSim/Framework/Communications/IUserServices.cs b/OpenSim/Framework/Communications/IUserServices.cs new file mode 100644 index 0000000000..5a9f106350 --- /dev/null +++ b/OpenSim/Framework/Communications/IUserServices.cs @@ -0,0 +1,44 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; +using OpenSim.Framework.Data; + +namespace OpenSim.Framework.Communications +{ + public interface IUserServices + { + UserProfileData GetUserProfile(string firstName, string lastName); + UserProfileData GetUserProfile(string name); + UserProfileData GetUserProfile(LLUUID avatarID); + void clearUserAgent(LLUUID avatarID); + + UserProfileData SetupMasterUser(string firstName, string lastName); + UserProfileData SetupMasterUser(string firstName, string lastName, string password); + + } +} diff --git a/OpenSim/Framework/Communications/Properties/AssemblyInfo.cs b/OpenSim/Framework/Communications/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..09f6473ae4 --- /dev/null +++ b/OpenSim/Framework/Communications/Properties/AssemblyInfo.cs @@ -0,0 +1,60 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenGrid.Framework.Communications")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OpenGrid.Framework.Communications")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("13e7c396-78a9-4a5c-baf2-6f980ea75d95")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/Configuration/HTTP/HTTPConfiguration.cs b/OpenSim/Framework/Configuration/HTTP/HTTPConfiguration.cs new file mode 100644 index 0000000000..d72c40fd6f --- /dev/null +++ b/OpenSim/Framework/Configuration/HTTP/HTTPConfiguration.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.IO; +using System.Text; + +using OpenSim.Framework.Configuration.Interfaces; + +namespace OpenSim.Framework.Configuration.HTTP +{ + public class HTTPConfiguration : IGenericConfig + { + RemoteConfigSettings remoteConfigSettings; + + XmlConfiguration xmlConfig; + + private string configFileName = ""; + + public HTTPConfiguration() + { + remoteConfigSettings = new RemoteConfigSettings("remoteconfig.xml"); + xmlConfig = new XmlConfiguration(); + } + + public void SetFileName(string fileName) + { + configFileName = fileName; + } + + public void LoadData() + { + try + { + StringBuilder sb = new StringBuilder(); + + byte[] buf = new byte[8192]; + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(this.remoteConfigSettings.baseConfigURL + this.configFileName); + HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + + Stream resStream = response.GetResponseStream(); + + string tempString = null; + int count = 0; + + do + { + count = resStream.Read(buf, 0, buf.Length); + if (count != 0) + { + tempString = Encoding.ASCII.GetString(buf, 0, count); + sb.Append(tempString); + } + } + while (count > 0); + LoadDataFromString(sb.ToString()); + } + catch (WebException) + { + Console.MainLog.Instance.Warn("Unable to connect to remote configuration file (" + remoteConfigSettings.baseConfigURL + configFileName + "). Creating local file instead."); + xmlConfig.SetFileName(configFileName); + xmlConfig.LoadData(); + } + } + + public void LoadDataFromString(string data) + { + xmlConfig.LoadDataFromString(data); + + } + + public string GetAttribute(string attributeName) + { + return xmlConfig.GetAttribute(attributeName); + } + + public bool SetAttribute(string attributeName, string attributeValue) + { + return true; + } + + public void Commit() + { + } + + public void Close() + { + } + } +} diff --git a/OpenSim/Framework/Configuration/HTTP/RemoteConfigSettings.cs b/OpenSim/Framework/Configuration/HTTP/RemoteConfigSettings.cs new file mode 100644 index 0000000000..e3cfac75e1 --- /dev/null +++ b/OpenSim/Framework/Configuration/HTTP/RemoteConfigSettings.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text; + +using OpenSim.Framework.Configuration; + +namespace OpenSim.Framework.Configuration.HTTP +{ + public class RemoteConfigSettings + { + private ConfigurationMember configMember; + + public string baseConfigURL = ""; + public RemoteConfigSettings(string filename) + { + configMember = new ConfigurationMember(filename, "REMOTE CONFIG SETTINGS", loadConfigurationOptions, handleIncomingConfiguration); + configMember.forceConfigurationPluginLibrary("OpenSim.Framework.Configuration.XML.dll"); + configMember.performConfigurationRetrieve(); + } + + public void loadConfigurationOptions() + { + configMember.addConfigurationOption("base_config_url", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "URL Containing Configuration Files", "http://localhost/", false); + } + public bool handleIncomingConfiguration(string configuration_key, object configuration_result) + { + if (configuration_key == "base_config_url") + { + baseConfigURL = (string)configuration_result; + } + return true; + } + } +} diff --git a/OpenSim/Framework/Configuration/XML/XmlConfiguration.cs b/OpenSim/Framework/Configuration/XML/XmlConfiguration.cs new file mode 100644 index 0000000000..065809b199 --- /dev/null +++ b/OpenSim/Framework/Configuration/XML/XmlConfiguration.cs @@ -0,0 +1,139 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.IO; +using System.Xml; + +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Configuration.Interfaces; +using OpenSim.Framework.Utilities; + +namespace OpenSim.Framework.Configuration +{ + public class XmlConfiguration : IGenericConfig + { + private XmlDocument doc; + private XmlNode rootNode; + private XmlNode configNode; + private string fileName; + private bool createdFile = false; + + public void SetFileName(string file) + { + fileName = file; + } + + private void LoadDataToClass() + { + rootNode = doc.FirstChild; + if (rootNode.Name != "Root") + throw new Exception("Error: Invalid .xml File. Missing "); + + configNode = rootNode.FirstChild; + if (configNode.Name != "Config") + throw new Exception("Error: Invalid .xml File. first child should be "); + } + public void LoadData() + { + doc = new XmlDocument(); + if (File.Exists(fileName)) + { + XmlTextReader reader = new XmlTextReader(fileName); + reader.WhitespaceHandling = WhitespaceHandling.None; + doc.Load(reader); + reader.Close(); + } + else + { + createdFile = true; + rootNode = doc.CreateNode(XmlNodeType.Element, "Root", ""); + doc.AppendChild(rootNode); + configNode = doc.CreateNode(XmlNodeType.Element, "Config", ""); + rootNode.AppendChild(configNode); + } + + LoadDataToClass(); + + if (createdFile) + { + this.Commit(); + } + } + + public void LoadDataFromString(string data) + { + doc = new XmlDocument(); + doc.LoadXml(data); + + LoadDataToClass(); + } + public string GetAttribute(string attributeName) + { + string result = null; + if (configNode.Attributes[attributeName] != null) + { + result = ((XmlAttribute)configNode.Attributes.GetNamedItem(attributeName)).Value; + } + return result; + } + + public bool SetAttribute(string attributeName, string attributeValue) + { + if (configNode.Attributes[attributeName] != null) + { + ((XmlAttribute)configNode.Attributes.GetNamedItem(attributeName)).Value = attributeValue; + } + else + { + XmlAttribute attri; + attri = doc.CreateAttribute(attributeName); + attri.Value = attributeValue; + configNode.Attributes.Append(attri); + } + return true; + } + + public void Commit() + { + if (!Directory.Exists(Util.configDir())) + { + Directory.CreateDirectory(Util.configDir()); + } + + doc.Save(fileName); + } + + public void Close() + { + configNode = null; + rootNode = null; + doc = null; + } + + } +} diff --git a/OpenSim/Framework/Console/AssemblyInfo.cs b/OpenSim/Framework/Console/AssemblyInfo.cs new file mode 100644 index 0000000000..30f61673a5 --- /dev/null +++ b/OpenSim/Framework/Console/AssemblyInfo.cs @@ -0,0 +1,56 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Reflection; +using System.Runtime.InteropServices; +// Information about this assembly is defined by the following +// attributes. +// +// change them to the information which is associated with the assembly +// you compile. + +[assembly: AssemblyTitle("ServerConsole")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ServerConsole")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. +[assembly: ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all values by your own or you can build default build and revision +// numbers with the '*' character (the default): + +[assembly: AssemblyVersion("1.0.*")] diff --git a/OpenSim/Framework/Console/ConsoleCallbacksBase.cs b/OpenSim/Framework/Console/ConsoleCallbacksBase.cs new file mode 100644 index 0000000000..346cfe6cd3 --- /dev/null +++ b/OpenSim/Framework/Console/ConsoleCallbacksBase.cs @@ -0,0 +1,35 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +namespace OpenSim.Framework.Console +{ + public interface conscmd_callback + { + void RunCmd(string cmd, string[] cmdparams); + void Show(string ShowWhat); + } +} diff --git a/OpenSim/Framework/Console/LogBase.cs b/OpenSim/Framework/Console/LogBase.cs new file mode 100644 index 0000000000..102bf457bf --- /dev/null +++ b/OpenSim/Framework/Console/LogBase.cs @@ -0,0 +1,463 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.IO; +using System.Net; +using System.Collections.Generic; + +namespace OpenSim.Framework.Console +{ + public enum LogPriority : int + { + CRITICAL, + HIGH, + MEDIUM, + NORMAL, + LOW, + VERBOSE, + EXTRAVERBOSE + } + + public class LogBase + { + StreamWriter Log; + public conscmd_callback cmdparser; + public string componentname; + private bool m_silent; + + public LogBase(string LogFile, string componentname, conscmd_callback cmdparser, bool silent) + { + this.componentname = componentname; + this.cmdparser = cmdparser; + this.m_silent = silent; + System.Console.WriteLine("Creating new local console"); + + if (String.IsNullOrEmpty(LogFile)) + { + LogFile = componentname + ".log"; + } + + System.Console.WriteLine("Logs will be saved to current directory in " + LogFile); + + Log = File.AppendText(LogFile); + Log.WriteLine("========================================================================"); + Log.WriteLine(componentname + " Started at " + DateTime.Now.ToString()); + } + + public void Close() + { + Log.WriteLine("Shutdown at " + DateTime.Now.ToString()); + Log.Close(); + } + + [Obsolete("Log.WriteLine is obsolete, use Warn / Error / Verbose instead.")] + public void Write(string format, params object[] args) + { + // HOUSEKEEPING : Will remove once use is removed. + Notice(format, args); + return; + } + + [Obsolete("Log.WriteLine is obsolete, use Warn / Error / Verbose instead.")] + public void WriteLine(LogPriority importance, string format, params object[] args) + { + // HOUSEKEEPING : Will remove once use is removed. + Log.WriteLine(format, args); + Log.Flush(); + if (!m_silent) + { + System.Console.WriteLine(format, args); + } + return; + } + + /// + /// derive an ansi color from a string, ignoring the darker colors. + /// This is used to help automatically bin component tags with colors + /// in various print functions. + /// + /// arbitrary string for input + /// an ansii color + private ConsoleColor DeriveColor(string input) + { + int colIdx = (input.ToUpper().GetHashCode() % 6) + 9; + return (ConsoleColor)colIdx; + } + + /// + /// Sends a warning to the current log output + /// + /// The message to send + /// WriteLine-style message arguments + public void Warn(string format, params object[] args) + { + WriteNewLine(ConsoleColor.Yellow, format, args); + return; + } + + /// + /// Sends a warning to the current log output + /// + /// The module that sent this message + /// The message to send + /// WriteLine-style message arguments + public void Warn(string sender, string format, params object[] args) + { + WritePrefixLine(DeriveColor(sender), sender); + WriteNewLine(ConsoleColor.Yellow, format, args); + return; + } + + /// + /// Sends a notice to the current log output + /// + /// The message to send + /// WriteLine-style message arguments + public void Notice(string format, params object[] args) + { + WriteNewLine(ConsoleColor.White, format, args); + return; + } + + /// + /// Sends a notice to the current log output + /// + /// The module that sent this message + /// The message to send + /// WriteLine-style message arguments + public void Notice(string sender, string format, params object[] args) + { + WritePrefixLine(DeriveColor(sender), sender); + WriteNewLine(ConsoleColor.White, format, args); + return; + } + + /// + /// Sends an error to the current log output + /// + /// The message to send + /// WriteLine-style message arguments + public void Error(string format, params object[] args) + { + WriteNewLine(ConsoleColor.Red, format, args); + return; + } + + /// + /// Sends an error to the current log output + /// + /// The module that sent this message + /// The message to send + /// WriteLine-style message arguments + public void Error(string sender, string format, params object[] args) + { + WritePrefixLine(DeriveColor(sender), sender); + Error( format, args); + return; + } + + /// + /// Sends a informational message to the current log output + /// + /// The message to send + /// WriteLine-style message arguments + public void Verbose(string format, params object[] args) + { + WriteNewLine(ConsoleColor.Gray, format, args); + return; + } + + /// + /// Sends an informational message to the current log output + /// + /// The module that sent this message + /// The message to send + /// WriteLine-style message arguments + public void Verbose(string sender, string format, params object[] args) + { + WritePrefixLine(DeriveColor(sender), sender); + WriteNewLine(ConsoleColor.Gray, format, args); + return; + } + + /// + /// Sends a status message to the current log output + /// + /// The message to send + /// WriteLine-style message arguments + public void Status(string format, params object[] args) + { + WriteNewLine(ConsoleColor.Blue, format, args); + return; + } + + /// + /// Sends a status message to the current log output + /// + /// The module that sent this message + /// The message to send + /// WriteLine-style message arguments + public void Status(string sender, string format, params object[] args) + { + WritePrefixLine(DeriveColor(sender), sender); + WriteNewLine(ConsoleColor.Blue, format, args); + return; + } + + + private void WriteNewLine(ConsoleColor color, string format, params object[] args) + { + Log.WriteLine(format, args); + Log.Flush(); + if (!m_silent) + { + try + { + if (color != ConsoleColor.White) + System.Console.ForegroundColor = color; + + System.Console.WriteLine(format, args); + System.Console.ResetColor(); + } + catch (ArgumentNullException) + { + // Some older systems dont support coloured text. + System.Console.WriteLine(format, args); + } + } + return; + } + + private void WritePrefixLine(ConsoleColor color, string sender) + { + sender = sender.ToUpper(); + Log.WriteLine("[" + sender + "] "); + Log.Flush(); + + System.Console.Write("["); + + if (!m_silent) + { + try + { + System.Console.ForegroundColor = color; + System.Console.Write(sender); + System.Console.ResetColor(); + } + catch (ArgumentNullException) + { + // Some older systems dont support coloured text. + System.Console.WriteLine(sender); + } + } + + System.Console.Write("] \t"); + + return; + } + + + public string ReadLine() + { + string TempStr = System.Console.ReadLine(); + Log.WriteLine(TempStr); + return TempStr; + } + + public int Read() + { + int TempInt = System.Console.Read(); + Log.Write((char)TempInt); + return TempInt; + } + + public IPAddress CmdPromptIPAddress(string prompt, string defaultvalue) + { + IPAddress address; + string addressStr; + + while (true) + { + addressStr = MainLog.Instance.CmdPrompt(prompt, defaultvalue); + if (IPAddress.TryParse(addressStr, out address)) + { + break; + } + else + { + MainLog.Instance.Error("Illegal address. Please re-enter."); + } + } + + return address; + } + + public int CmdPromptIPPort(string prompt, string defaultvalue) + { + int port; + string portStr; + + while (true) + { + portStr = MainLog.Instance.CmdPrompt(prompt, defaultvalue); + if (int.TryParse(portStr, out port)) + { + if (port >= IPEndPoint.MinPort && port <= IPEndPoint.MaxPort) + { + break; + } + } + + MainLog.Instance.Error("Illegal address. Please re-enter."); + } + + return port; + } + + // Displays a prompt and waits for the user to enter a string, then returns that string + // Done with no echo and suitable for passwords + public string PasswdPrompt(string prompt) + { + // FIXME: Needs to be better abstracted + Log.WriteLine(prompt); + this.Notice(prompt); + ConsoleColor oldfg = System.Console.ForegroundColor; + System.Console.ForegroundColor = System.Console.BackgroundColor; + string temp = System.Console.ReadLine(); + System.Console.ForegroundColor = oldfg; + return temp; + } + + // Displays a command prompt and waits for the user to enter a string, then returns that string + public string CmdPrompt(string prompt) + { + this.Notice(String.Format("{0}: ", prompt)); + return this.ReadLine(); + } + + // Displays a command prompt and returns a default value if the user simply presses enter + public string CmdPrompt(string prompt, string defaultresponse) + { + string temp = CmdPrompt(String.Format("{0} [{1}]", prompt, defaultresponse)); + if (temp == "") + { + return defaultresponse; + } + else + { + return temp; + } + } + + // Displays a command prompt and returns a default value, user may only enter 1 of 2 options + public string CmdPrompt(string prompt, string defaultresponse, string OptionA, string OptionB) + { + bool itisdone = false; + string temp = CmdPrompt(prompt, defaultresponse); + while (itisdone == false) + { + if ((temp == OptionA) || (temp == OptionB)) + { + itisdone = true; + } + else + { + Notice("Valid options are " + OptionA + " or " + OptionB); + temp = CmdPrompt(prompt, defaultresponse); + } + } + return temp; + } + + // Runs a command with a number of parameters + public Object RunCmd(string Cmd, string[] cmdparams) + { + cmdparser.RunCmd(Cmd, cmdparams); + return null; + } + + // Shows data about something + public void ShowCommands(string ShowWhat) + { + cmdparser.Show(ShowWhat); + } + + public void MainLogPrompt() + { + + string tempstr = this.CmdPrompt(this.componentname + "# "); + MainLogRunCommand(tempstr); + } + + public void MainLogRunCommand(string command) + { + string[] tempstrarray; + tempstrarray = command.Split(' '); + string cmd = tempstrarray[0]; + Array.Reverse(tempstrarray); + Array.Resize(ref tempstrarray, tempstrarray.Length - 1); + Array.Reverse(tempstrarray); + string[] cmdparams = (string[])tempstrarray; + RunCmd(cmd, cmdparams); + } + + public string LineInfo + { + get + { + string result = String.Empty; + + string stacktrace = Environment.StackTrace; + List lines = new List(stacktrace.Split(new string[] { "at " }, StringSplitOptions.None)); + + if (lines.Count > 4) + { + lines.RemoveRange(0, 4); + + string tmpLine = lines[0]; + + int inIndex = tmpLine.IndexOf(" in "); + + if (inIndex > -1) + { + result = tmpLine.Substring(0, inIndex); + + int lineIndex = tmpLine.IndexOf(":line "); + + if (lineIndex > -1) + { + lineIndex += 6; + result += ", line " + tmpLine.Substring(lineIndex, (tmpLine.Length - lineIndex) - 5); + } + } + } + return result; + } + } + } +} diff --git a/OpenSim/Framework/Console/MainLog.cs b/OpenSim/Framework/Console/MainLog.cs new file mode 100644 index 0000000000..18063cbc37 --- /dev/null +++ b/OpenSim/Framework/Console/MainLog.cs @@ -0,0 +1,41 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +namespace OpenSim.Framework.Console +{ + public class MainLog { + + private static LogBase instance; + + public static LogBase Instance + { + get { return instance; } + set { instance = value; } + } + } + +} diff --git a/OpenSim/Framework/Data.DB4o/DB4oGridData.cs b/OpenSim/Framework/Data.DB4o/DB4oGridData.cs new file mode 100644 index 0000000000..5fec367173 --- /dev/null +++ b/OpenSim/Framework/Data.DB4o/DB4oGridData.cs @@ -0,0 +1,162 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; + +namespace OpenSim.Framework.Data.DB4o +{ + /// + /// A grid server storage mechanism employing the DB4o database system + /// + class DB4oGridData : IGridData + { + /// + /// The database manager object + /// + DB4oGridManager manager; + + /// + /// Called when the plugin is first loaded (as constructors are not called) + /// + public void Initialise() { + manager = new DB4oGridManager("gridserver.yap"); + } + + /// + /// Returns a list of regions within the specified ranges + /// + /// minimum X coordinate + /// minimum Y coordinate + /// maximum X coordinate + /// maximum Y coordinate + /// An array of region profiles + public SimProfileData[] GetProfilesInRange(uint a, uint b, uint c, uint d) + { + return null; + } + + /// + /// Returns a region located at the specified regionHandle (warning multiple regions may occupy the one spot, first found is returned) + /// + /// The handle to search for + /// A region profile + public SimProfileData GetProfileByHandle(ulong handle) { + lock (manager.simProfiles) + { + foreach (LLUUID UUID in manager.simProfiles.Keys) + { + if (manager.simProfiles[UUID].regionHandle == handle) + { + return manager.simProfiles[UUID]; + } + } + } + throw new Exception("Unable to find profile with handle (" + handle.ToString() + ")"); + } + + /// + /// Returns a specific region + /// + /// The region ID code + /// A region profile + public SimProfileData GetProfileByLLUUID(LLUUID uuid) + { + lock (manager.simProfiles) + { + if (manager.simProfiles.ContainsKey(uuid)) + return manager.simProfiles[uuid]; + } + throw new Exception("Unable to find profile with UUID (" + uuid.ToStringHyphenated() + "). Total Registered Regions: " + manager.simProfiles.Count); + } + + /// + /// Adds a new specified region to the database + /// + /// The profile to add + /// A dataresponse enum indicating success + public DataResponse AddProfile(SimProfileData profile) + { + lock (manager.simProfiles) + { + if (manager.AddRow(profile)) + { + return DataResponse.RESPONSE_OK; + } + else + { + return DataResponse.RESPONSE_ERROR; + } + } + } + + /// + /// Authenticates a new region using the shared secrets. NOT SECURE. + /// + /// The UUID the region is authenticating with + /// The location the region is logging into (unused in Db4o) + /// The shared secret + /// Authenticated? + public bool AuthenticateSim(LLUUID uuid, ulong handle, string key) { + if (manager.simProfiles[uuid].regionRecvKey == key) + return true; + return false; + } + + /// + /// Shuts down the database + /// + public void Close() + { + manager = null; + } + + /// + /// Returns the providers name + /// + /// The name of the storage system + public string getName() + { + return "DB4o Grid Provider"; + } + + /// + /// Returns the providers version + /// + /// The version of the storage system + public string getVersion() + { + return "0.1"; + } + + public ReservationData GetReservationAtPoint(uint x, uint y) + { + return null; + } + } +} diff --git a/OpenSim/Framework/Data.DB4o/DB4oManager.cs b/OpenSim/Framework/Data.DB4o/DB4oManager.cs new file mode 100644 index 0000000000..5340fb1b8f --- /dev/null +++ b/OpenSim/Framework/Data.DB4o/DB4oManager.cs @@ -0,0 +1,169 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 Db4objects.Db4o; +using libsecondlife; + +namespace OpenSim.Framework.Data.DB4o +{ + /// + /// A Database manager for Db4o + /// + class DB4oGridManager + { + /// + /// A list of the current regions connected (in-memory cache) + /// + public Dictionary simProfiles = new Dictionary(); + /// + /// Database File Name + /// + string dbfl; + + /// + /// Creates a new grid storage manager + /// + /// Filename to the database file + public DB4oGridManager(string db4odb) + { + dbfl = db4odb; + IObjectContainer database; + database = Db4oFactory.OpenFile(dbfl); + IObjectSet result = database.Get(typeof(SimProfileData)); + // Loads the file into the in-memory cache + foreach(SimProfileData row in result) { + simProfiles.Add(row.UUID, row); + } + database.Close(); + } + + /// + /// Adds a new profile to the database (Warning: Probably slow.) + /// + /// The profile to add + /// Successful? + public bool AddRow(SimProfileData row) + { + if (simProfiles.ContainsKey(row.UUID)) + { + simProfiles[row.UUID] = row; + } + else + { + simProfiles.Add(row.UUID, row); + } + + try + { + IObjectContainer database; + database = Db4oFactory.OpenFile(dbfl); + database.Set(row); + database.Close(); + return true; + } + catch (Exception) + { + return false; + } + } + + + } + + /// + /// A manager for the DB4o database (user profiles) + /// + class DB4oUserManager + { + /// + /// A list of the user profiles (in memory cache) + /// + public Dictionary userProfiles = new Dictionary(); + /// + /// Database filename + /// + string dbfl; + + /// + /// Initialises a new DB manager + /// + /// The filename to the database + public DB4oUserManager(string db4odb) + { + dbfl = db4odb; + IObjectContainer database; + database = Db4oFactory.OpenFile(dbfl); + // Load to cache + IObjectSet result = database.Get(typeof(UserProfileData)); + foreach (UserProfileData row in result) + { + if (userProfiles.ContainsKey(row.UUID)) + userProfiles[row.UUID] = row; + else + userProfiles.Add(row.UUID, row); + } + database.Close(); + } + + /// + /// Adds or updates a record to the user database. Do this when changes are needed + /// in the user profile that need to be persistant. + /// + /// TODO: the logic here is not ACID, the local cache will be + /// updated even if the persistant data is not. This may lead + /// to unexpected results. + /// + /// The profile to update + /// true on success, false on fail to persist to db + public bool UpdateRecord(UserProfileData record) + { + if (userProfiles.ContainsKey(record.UUID)) + { + userProfiles[record.UUID] = record; + } + else + { + userProfiles.Add(record.UUID, record); + } + + try + { + IObjectContainer database; + database = Db4oFactory.OpenFile(dbfl); + database.Set(record); + database.Close(); + return true; + } + catch (Exception) + { + return false; + } + } + } +} diff --git a/OpenSim/Framework/Data.DB4o/DB4oUserData.cs b/OpenSim/Framework/Data.DB4o/DB4oUserData.cs new file mode 100644 index 0000000000..e4809d65db --- /dev/null +++ b/OpenSim/Framework/Data.DB4o/DB4oUserData.cs @@ -0,0 +1,221 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.IO; +using libsecondlife; +using OpenSim.Framework.Utilities; + +namespace OpenSim.Framework.Data.DB4o +{ + /// + /// A User storage interface for the DB4o database system + /// + public class DB4oUserData : IUserData + { + /// + /// The database manager + /// + DB4oUserManager manager; + + /// + /// Artificial constructor called upon plugin load + /// + public void Initialise() + { + manager = new DB4oUserManager(Path.Combine(Util.dataDir(),"userprofiles.yap")); + } + + /// + /// Loads a specified user profile from a UUID + /// + /// The users UUID + /// A user profile + public UserProfileData getUserByUUID(LLUUID uuid) + { + if(manager.userProfiles.ContainsKey(uuid)) + return manager.userProfiles[uuid]; + return null; + } + + /// + /// Returns a user by searching for its name + /// + /// The users account name + /// A matching users profile + public UserProfileData getUserByName(string name) + { + return getUserByName(name.Split(' ')[0], name.Split(' ')[1]); + } + + /// + /// Returns a user by searching for its name + /// + /// The first part of the users account name + /// The second part of the users account name + /// A matching users profile + public UserProfileData getUserByName(string fname, string lname) + { + foreach (UserProfileData profile in manager.userProfiles.Values) + { + if (profile.username == fname && profile.surname == lname) + return profile; + } + return null; + } + + /// + /// Returns a user by UUID direct + /// + /// The users account ID + /// A matching users profile + public UserAgentData getAgentByUUID(LLUUID uuid) + { + try + { + return getUserByUUID(uuid).currentAgent; + } + catch (Exception) + { + return null; + } + } + + /// + /// Returns a session by account name + /// + /// The account name + /// The users session agent + public UserAgentData getAgentByName(string name) + { + return getAgentByName(name.Split(' ')[0], name.Split(' ')[1]); + } + + /// + /// Returns a session by account name + /// + /// The first part of the users account name + /// The second part of the users account name + /// A user agent + public UserAgentData getAgentByName(string fname, string lname) + { + try + { + return getUserByName(fname,lname).currentAgent; + } + catch (Exception) + { + return null; + } + } + + /// + /// Creates a new user profile + /// + /// The profile to add to the database + public void addNewUserProfile(UserProfileData user) + { + try + { + manager.UpdateRecord(user); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + } + + /// + /// Creates a new user profile + /// + /// The profile to add to the database + /// True on success, false on error + public bool updateUserProfile(UserProfileData user) + { + try { + return manager.UpdateRecord(user); + } catch (Exception e) { + Console.WriteLine(e.ToString()); + return false; + } + } + + + + /// + /// Creates a new user agent + /// + /// The agent to add to the database + public void addNewUserAgent(UserAgentData agent) + { + // Do nothing. yet. + } + + /// + /// Transfers money between two user accounts + /// + /// Starting account + /// End account + /// The amount to move + /// Success? + public bool moneyTransferRequest(LLUUID from, LLUUID to, uint amount) + { + return true; + } + + /// + /// Transfers inventory between two accounts + /// + /// Move to inventory server + /// Senders account + /// Recievers account + /// Inventory item + /// Success? + public bool inventoryTransferRequest(LLUUID from, LLUUID to, LLUUID item) + { + return true; + } + + /// + /// Returns the name of the storage provider + /// + /// Storage provider name + public string getName() + { + return "DB4o Userdata"; + } + + /// + /// Returns the version of the storage provider + /// + /// Storage provider version + public string getVersion() + { + return "0.1"; + } + } +} diff --git a/OpenSim/Framework/Data.DB4o/Properties/AssemblyInfo.cs b/OpenSim/Framework/Data.DB4o/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..905cd9b25a --- /dev/null +++ b/OpenSim/Framework/Data.DB4o/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.Framework.Data.DB4o")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OpenSim.Framework.Data.DB4o")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("57991e15-79da-41b7-aa06-2e6b49165a63")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/Data.MSSQL/MSSQLGridData.cs b/OpenSim/Framework/Data.MSSQL/MSSQLGridData.cs new file mode 100644 index 0000000000..ca9196a59e --- /dev/null +++ b/OpenSim/Framework/Data.MSSQL/MSSQLGridData.cs @@ -0,0 +1,194 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Security.Cryptography; +using System.Text; +using libsecondlife; + +namespace OpenSim.Framework.Data.MSSQL +{ + /// + /// A grid data interface for Microsoft SQL Server + /// + public class SqlGridData : IGridData + { + /// + /// Database manager + /// + private MSSqlManager database; + + /// + /// Initialises the Grid Interface + /// + public void Initialise() + { + database = new MSSqlManager("localhost", "db", "user", "password", "false"); + } + + /// + /// Shuts down the grid interface + /// + public void Close() + { + database.Close(); + } + + /// + /// Returns the storage system name + /// + /// A string containing the storage system name + public string getName() + { + return "Sql OpenGridData"; + } + + /// + /// Returns the storage system version + /// + /// A string containing the storage system version + public string getVersion() + { + return "0.1"; + } + + /// + /// Returns a list of regions within the specified ranges + /// + /// minimum X coordinate + /// minimum Y coordinate + /// maximum X coordinate + /// maximum Y coordinate + /// An array of region profiles + public SimProfileData[] GetProfilesInRange(uint a, uint b, uint c, uint d) + { + return null; + } + + /// + /// Returns a sim profile from it's location + /// + /// Region location handle + /// Sim profile + public SimProfileData GetProfileByHandle(ulong handle) + { + Dictionary param = new Dictionary(); + param["handle"] = handle.ToString(); + + IDbCommand result = database.Query("SELECT * FROM regions WHERE handle = @handle", param); + IDataReader reader = result.ExecuteReader(); + + SimProfileData row = database.getRow(reader); + reader.Close(); + result.Dispose(); + + return row; + } + + /// + /// Returns a sim profile from it's UUID + /// + /// The region UUID + /// The sim profile + public SimProfileData GetProfileByLLUUID(LLUUID uuid) + { + Dictionary param = new Dictionary(); + param["uuid"] = uuid.ToStringHyphenated(); + + IDbCommand result = database.Query("SELECT * FROM regions WHERE uuid = @uuid", param); + IDataReader reader = result.ExecuteReader(); + + SimProfileData row = database.getRow(reader); + reader.Close(); + result.Dispose(); + + return row; + } + + /// + /// Adds a new specified region to the database + /// + /// The profile to add + /// A dataresponse enum indicating success + public DataResponse AddProfile(SimProfileData profile) + { + if (database.insertRow(profile)) + { + return DataResponse.RESPONSE_OK; + } + else + { + return DataResponse.RESPONSE_ERROR; + } + } + + /// + /// DEPRECIATED. Attempts to authenticate a region by comparing a shared secret. + /// + /// The UUID of the challenger + /// The attempted regionHandle of the challenger + /// The secret + /// Whether the secret and regionhandle match the database entry for UUID + public bool AuthenticateSim(LLUUID uuid, ulong handle, string authkey) + { + bool throwHissyFit = false; // Should be true by 1.0 + + if (throwHissyFit) + throw new Exception("CRYPTOWEAK AUTHENTICATE: Refusing to authenticate due to replay potential."); + + SimProfileData data = GetProfileByLLUUID(uuid); + + return (handle == data.regionHandle && authkey == data.regionSecret); + } + + /// + /// NOT YET FUNCTIONAL. Provides a cryptographic authentication of a region + /// + /// This requires a security audit. + /// + /// + /// + /// + /// + public bool AuthenticateSim(LLUUID uuid, ulong handle, string authhash, string challenge) + { + SHA512Managed HashProvider = new SHA512Managed(); + ASCIIEncoding TextProvider = new ASCIIEncoding(); + + byte[] stream = TextProvider.GetBytes(uuid.ToStringHyphenated() + ":" + handle.ToString() + ":" + challenge); + byte[] hash = HashProvider.ComputeHash(stream); + return false; + } + public ReservationData GetReservationAtPoint(uint x, uint y) + { + return null; + } + } + +} diff --git a/OpenSim/Framework/Data.MSSQL/MSSQLManager.cs b/OpenSim/Framework/Data.MSSQL/MSSQLManager.cs new file mode 100644 index 0000000000..49bf31ccb2 --- /dev/null +++ b/OpenSim/Framework/Data.MSSQL/MSSQLManager.cs @@ -0,0 +1,211 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Data.SqlClient; +using libsecondlife; + +namespace OpenSim.Framework.Data.MSSQL +{ + /// + /// A management class for the MS SQL Storage Engine + /// + class MSSqlManager + { + /// + /// The database connection object + /// + IDbConnection dbcon; + + /// + /// Initialises and creates a new Sql connection and maintains it. + /// + /// The Sql server being connected to + /// The name of the Sql database being used + /// The username logging into the database + /// The password for the user logging in + /// Whether to use connection pooling or not, can be one of the following: 'yes', 'true', 'no' or 'false', if unsure use 'false'. + public MSSqlManager(string hostname, string database, string username, string password, string cpooling) + { + try + { + string connectionString = "Server=" + hostname + ";Database=" + database + ";User ID=" + username + ";Password=" + password + ";Pooling=" + cpooling + ";"; + dbcon = new SqlConnection(connectionString); + + dbcon.Open(); + } + catch (Exception e) + { + throw new Exception("Error initialising Sql Database: " + e.ToString()); + } + } + + /// + /// Shuts down the database connection + /// + public void Close() + { + dbcon.Close(); + dbcon = null; + } + + /// + /// Runs a query with protection against SQL Injection by using parameterised input. + /// + /// The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y + /// The parameters - index so that @y is indexed as 'y' + /// A Sql DB Command + public IDbCommand Query(string sql, Dictionary parameters) + { + SqlCommand dbcommand = (SqlCommand)dbcon.CreateCommand(); + dbcommand.CommandText = sql; + foreach (KeyValuePair param in parameters) + { + dbcommand.Parameters.AddWithValue(param.Key, param.Value); + } + + return (IDbCommand)dbcommand; + } + + /// + /// Runs a database reader object and returns a region row + /// + /// An active database reader + /// A region row + public SimProfileData getRow(IDataReader reader) + { + SimProfileData regionprofile = new SimProfileData(); + + if (reader.Read()) + { + // Region Main + regionprofile.regionHandle = (ulong)reader["regionHandle"]; + regionprofile.regionName = (string)reader["regionName"]; + regionprofile.UUID = new LLUUID((string)reader["uuid"]); + + // Secrets + regionprofile.regionRecvKey = (string)reader["regionRecvKey"]; + regionprofile.regionSecret = (string)reader["regionSecret"]; + regionprofile.regionSendKey = (string)reader["regionSendKey"]; + + // Region Server + regionprofile.regionDataURI = (string)reader["regionDataURI"]; + regionprofile.regionOnline = false; // Needs to be pinged before this can be set. + regionprofile.serverIP = (string)reader["serverIP"]; + regionprofile.serverPort = (uint)reader["serverPort"]; + regionprofile.serverURI = (string)reader["serverURI"]; + + // Location + regionprofile.regionLocX = (uint)((int)reader["locX"]); + regionprofile.regionLocY = (uint)((int)reader["locY"]); + regionprofile.regionLocZ = (uint)((int)reader["locZ"]); + + // Neighbours - 0 = No Override + regionprofile.regionEastOverrideHandle = (ulong)reader["eastOverrideHandle"]; + regionprofile.regionWestOverrideHandle = (ulong)reader["westOverrideHandle"]; + regionprofile.regionSouthOverrideHandle = (ulong)reader["southOverrideHandle"]; + regionprofile.regionNorthOverrideHandle = (ulong)reader["northOverrideHandle"]; + + // Assets + regionprofile.regionAssetURI = (string)reader["regionAssetURI"]; + regionprofile.regionAssetRecvKey = (string)reader["regionAssetRecvKey"]; + regionprofile.regionAssetSendKey = (string)reader["regionAssetSendKey"]; + + // Userserver + regionprofile.regionUserURI = (string)reader["regionUserURI"]; + regionprofile.regionUserRecvKey = (string)reader["regionUserRecvKey"]; + regionprofile.regionUserSendKey = (string)reader["regionUserSendKey"]; + } + else + { + throw new Exception("No rows to return"); + } + return regionprofile; + } + + /// + /// Creates a new region in the database + /// + /// The region profile to insert + /// Successful? + public bool insertRow(SimProfileData profile) + { + string sql = "REPLACE INTO regions VALUES (regionHandle, regionName, uuid, regionRecvKey, regionSecret, regionSendKey, regionDataURI, "; + sql += "serverIP, serverPort, serverURI, locX, locY, locZ, eastOverrideHandle, westOverrideHandle, southOverrideHandle, northOverrideHandle, regionAssetURI, regionAssetRecvKey, "; + sql += "regionAssetSendKey, regionUserURI, regionUserRecvKey, regionUserSendKey) VALUES "; + + sql += "(@regionHandle, @regionName, @uuid, @regionRecvKey, @regionSecret, @regionSendKey, @regionDataURI, "; + sql += "@serverIP, @serverPort, @serverURI, @locX, @locY, @locZ, @eastOverrideHandle, @westOverrideHandle, @southOverrideHandle, @northOverrideHandle, @regionAssetURI, @regionAssetRecvKey, "; + sql += "@regionAssetSendKey, @regionUserURI, @regionUserRecvKey, @regionUserSendKey);"; + + Dictionary parameters = new Dictionary(); + + parameters["regionHandle"] = profile.regionHandle.ToString(); + parameters["regionName"] = profile.regionName; + parameters["uuid"] = profile.UUID.ToString(); + parameters["regionRecvKey"] = profile.regionRecvKey; + parameters["regionSendKey"] = profile.regionSendKey; + parameters["regionDataURI"] = profile.regionDataURI; + parameters["serverIP"] = profile.serverIP; + parameters["serverPort"] = profile.serverPort.ToString(); + parameters["serverURI"] = profile.serverURI; + parameters["locX"] = profile.regionLocX.ToString(); + parameters["locY"] = profile.regionLocY.ToString(); + parameters["locZ"] = profile.regionLocZ.ToString(); + parameters["eastOverrideHandle"] = profile.regionEastOverrideHandle.ToString(); + parameters["westOverrideHandle"] = profile.regionWestOverrideHandle.ToString(); + parameters["northOverrideHandle"] = profile.regionNorthOverrideHandle.ToString(); + parameters["southOverrideHandle"] = profile.regionSouthOverrideHandle.ToString(); + parameters["regionAssetURI"] = profile.regionAssetURI; + parameters["regionAssetRecvKey"] = profile.regionAssetRecvKey; + parameters["regionAssetSendKey"] = profile.regionAssetSendKey; + parameters["regionUserURI"] = profile.regionUserURI; + parameters["regionUserRecvKey"] = profile.regionUserRecvKey; + parameters["regionUserSendKey"] = profile.regionUserSendKey; + + bool returnval = false; + + try + { + IDbCommand result = Query(sql, parameters); + + if (result.ExecuteNonQuery() == 1) + returnval = true; + + result.Dispose(); + } + catch (Exception) + { + return false; + } + + return returnval; + } + } +} diff --git a/OpenSim/Framework/Data.MSSQL/Properties/AssemblyInfo.cs b/OpenSim/Framework/Data.MSSQL/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..066c739dbb --- /dev/null +++ b/OpenSim/Framework/Data.MSSQL/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.Framework.Data.MSSQL")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OpenSim.Framework.Data.MSSQL")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("0e1c1ca4-2cf2-4315-b0e7-432c02feea8a")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/Data.MySQL/MySQLGridData.cs b/OpenSim/Framework/Data.MySQL/MySQLGridData.cs new file mode 100644 index 0000000000..ef643d27a4 --- /dev/null +++ b/OpenSim/Framework/Data.MySQL/MySQLGridData.cs @@ -0,0 +1,287 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Security.Cryptography; +using System.Text; +using libsecondlife; + +namespace OpenSim.Framework.Data.MySQL +{ + /// + /// A MySQL Interface for the Grid Server + /// + public class MySQLGridData : IGridData + { + /// + /// MySQL Database Manager + /// + private MySQLManager database; + + /// + /// Initialises the Grid Interface + /// + public void Initialise() + { + IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini"); + string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname"); + string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database"); + string settingUsername = GridDataMySqlFile.ParseFileReadValue("username"); + string settingPassword = GridDataMySqlFile.ParseFileReadValue("password"); + string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling"); + string settingPort = GridDataMySqlFile.ParseFileReadValue("port"); + + database = new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, settingPooling, settingPort); + } + + /// + /// Shuts down the grid interface + /// + public void Close() + { + database.Close(); + } + + /// + /// Returns the plugin name + /// + /// Plugin name + public string getName() + { + return "MySql OpenGridData"; + } + + /// + /// Returns the plugin version + /// + /// Plugin version + public string getVersion() + { + return "0.1"; + } + + /// + /// Returns all the specified region profiles within coordates -- coordinates are inclusive + /// + /// Minimum X coordinate + /// Minimum Y coordinate + /// Maximum X coordinate + /// Maximum Y coordinate + /// + public SimProfileData[] GetProfilesInRange(uint xmin, uint ymin, uint xmax, uint ymax) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?xmin"] = xmin.ToString(); + param["?ymin"] = ymin.ToString(); + param["?xmax"] = xmax.ToString(); + param["?ymax"] = ymax.ToString(); + + IDbCommand result = database.Query("SELECT * FROM regions WHERE locX >= ?xmin AND locX <= ?xmax AND locY >= ?ymin AND locY <= ?ymax", param); + IDataReader reader = result.ExecuteReader(); + + SimProfileData row; + + List rows = new List(); + + while ((row = database.readSimRow(reader)) != null) + { + rows.Add(row); + } + reader.Close(); + result.Dispose(); + + return rows.ToArray(); + + } + } + catch (Exception e) + { + database.Reconnect(); + Console.WriteLine(e.ToString()); + return null; + } + } + + /// + /// Returns a sim profile from it's location + /// + /// Region location handle + /// Sim profile + public SimProfileData GetProfileByHandle(ulong handle) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?handle"] = handle.ToString(); + + IDbCommand result = database.Query("SELECT * FROM regions WHERE regionHandle = ?handle", param); + IDataReader reader = result.ExecuteReader(); + + SimProfileData row = database.readSimRow(reader); + reader.Close(); + result.Dispose(); + + return row; + } + } + catch (Exception e) + { + database.Reconnect(); + Console.WriteLine(e.ToString()); + return null; + } + } + + /// + /// Returns a sim profile from it's UUID + /// + /// The region UUID + /// The sim profile + public SimProfileData GetProfileByLLUUID(LLUUID uuid) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?uuid"] = uuid.ToStringHyphenated(); + + IDbCommand result = database.Query("SELECT * FROM regions WHERE uuid = ?uuid", param); + IDataReader reader = result.ExecuteReader(); + + SimProfileData row = database.readSimRow(reader); + reader.Close(); + result.Dispose(); + + return row; + } + } + catch (Exception e) + { + database.Reconnect(); + Console.WriteLine(e.ToString()); + return null; + } + } + + /// + /// Adds a new profile to the database + /// + /// The profile to add + /// Successful? + public DataResponse AddProfile(SimProfileData profile) + { + lock (database) + { + if (database.insertRegion(profile)) + { + return DataResponse.RESPONSE_OK; + } + else + { + return DataResponse.RESPONSE_ERROR; + } + } + } + + /// + /// DEPRECIATED. Attempts to authenticate a region by comparing a shared secret. + /// + /// The UUID of the challenger + /// The attempted regionHandle of the challenger + /// The secret + /// Whether the secret and regionhandle match the database entry for UUID + public bool AuthenticateSim(LLUUID uuid, ulong handle, string authkey) + { + bool throwHissyFit = false; // Should be true by 1.0 + + if (throwHissyFit) + throw new Exception("CRYPTOWEAK AUTHENTICATE: Refusing to authenticate due to replay potential."); + + SimProfileData data = GetProfileByLLUUID(uuid); + + return (handle == data.regionHandle && authkey == data.regionSecret); + } + + /// + /// NOT YET FUNCTIONAL. Provides a cryptographic authentication of a region + /// + /// This requires a security audit. + /// + /// + /// + /// + /// + public bool AuthenticateSim(LLUUID uuid, ulong handle, string authhash, string challenge) + { + SHA512Managed HashProvider = new SHA512Managed(); + ASCIIEncoding TextProvider = new ASCIIEncoding(); + + byte[] stream = TextProvider.GetBytes(uuid.ToStringHyphenated() + ":" + handle.ToString() + ":" + challenge); + byte[] hash = HashProvider.ComputeHash(stream); + + return false; + } + + public ReservationData GetReservationAtPoint(uint x, uint y) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?x"] = x.ToString(); + param["?y"] = y.ToString(); + IDbCommand result = database.Query("SELECT * FROM reservations WHERE resXMin <= ?x AND resXMax >= ?x AND resYMin <= ?y AND resYMax >= ?y", param); + IDataReader reader = result.ExecuteReader(); + + ReservationData row = database.readReservationRow(reader); + reader.Close(); + result.Dispose(); + + return row; + } + } + catch (Exception e) + { + database.Reconnect(); + Console.WriteLine(e.ToString()); + return null; + } + } + } + + +} diff --git a/OpenSim/Framework/Data.MySQL/MySQLInventoryData.cs b/OpenSim/Framework/Data.MySQL/MySQLInventoryData.cs new file mode 100644 index 0000000000..4a9f01e1c9 --- /dev/null +++ b/OpenSim/Framework/Data.MySQL/MySQLInventoryData.cs @@ -0,0 +1,352 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; + +namespace OpenSim.Framework.Data.MySQL +{ + /// + /// A MySQL interface for the inventory server + /// + class MySQLInventoryData : IInventoryData + { + /// + /// The database manager + /// + public MySQLManager database; + + /// + /// Loads and initialises this database plugin + /// + public void Initialise() + { + IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini"); + string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname"); + string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database"); + string settingUsername = GridDataMySqlFile.ParseFileReadValue("username"); + string settingPassword = GridDataMySqlFile.ParseFileReadValue("password"); + string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling"); + string settingPort = GridDataMySqlFile.ParseFileReadValue("port"); + + database = new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, settingPooling, settingPort); + } + + /// + /// The name of this DB provider + /// + /// Name of DB provider + public string getName() + { + return "MySQL Inventory Data Interface"; + } + + /// + /// Closes this DB provider + /// + public void Close() + { + // Do nothing. + } + + /// + /// Returns the version of this DB provider + /// + /// A string containing the DB provider + public string getVersion() + { + return "0.1"; + } + + /// + /// Returns a list of items in a specified folder + /// + /// The folder to search + /// A list containing inventory items + public List getInventoryInFolder(LLUUID folderID) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?uuid"] = folderID.ToStringHyphenated(); + + IDbCommand result = database.Query("SELECT * FROM inventoryitems WHERE parentFolderID = ?uuid", param); + IDataReader reader = result.ExecuteReader(); + + List items = database.readInventoryItems(reader); + + reader.Close(); + result.Dispose(); + + return items; + } + } + catch (Exception e) + { + database.Reconnect(); + Console.WriteLine(e.ToString()); + return null; + } + } + + /// + /// Returns a list of the root folders within a users inventory + /// + /// The user whos inventory is to be searched + /// A list of folder objects + public List getUserRootFolders(LLUUID user) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?uuid"] = user.ToStringHyphenated(); + param["?zero"] = LLUUID.Zero.ToStringHyphenated(); + + IDbCommand result = database.Query("SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", param); + IDataReader reader = result.ExecuteReader(); + + List items = database.readInventoryFolders(reader); + + reader.Close(); + result.Dispose(); + + return items; + } + } + catch (Exception e) + { + database.Reconnect(); + Console.WriteLine(e.ToString()); + return null; + } + } + + /// + /// Returns the users inventory root folder. + /// + /// + /// + public InventoryFolderBase getUserRootFolder(LLUUID user) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?uuid"] = user.ToStringHyphenated(); + param["?zero"] = LLUUID.Zero.ToStringHyphenated(); + + IDbCommand result = database.Query("SELECT * FROM inventoryfolders WHERE parentFolderID = ?zero AND agentID = ?uuid", param); + IDataReader reader = result.ExecuteReader(); + + List items = database.readInventoryFolders(reader); + InventoryFolderBase rootFolder = items[0]; //should only be one folder with parent set to zero (the root one). + reader.Close(); + result.Dispose(); + + return rootFolder; + } + } + catch (Exception e) + { + database.Reconnect(); + Console.WriteLine(e.ToString()); + return null; + } + } + + /// + /// Returns a list of folders in a users inventory contained within the specified folder + /// + /// The folder to search + /// A list of inventory folders + public List getInventoryFolders(LLUUID parentID) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?uuid"] = parentID.ToStringHyphenated(); + + IDbCommand result = database.Query("SELECT * FROM inventoryfolders WHERE parentFolderID = ?uuid", param); + IDataReader reader = result.ExecuteReader(); + + List items = database.readInventoryFolders(reader); + + reader.Close(); + result.Dispose(); + + return items; + } + } + catch (Exception e) + { + database.Reconnect(); + Console.WriteLine(e.ToString()); + return null; + } + } + + /// + /// Returns a specified inventory item + /// + /// The item to return + /// An inventory item + public InventoryItemBase getInventoryItem(LLUUID item) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?uuid"] = item.ToStringHyphenated(); + + IDbCommand result = database.Query("SELECT * FROM inventoryitems WHERE inventoryID = ?uuid", param); + IDataReader reader = result.ExecuteReader(); + + List items = database.readInventoryItems(reader); + + reader.Close(); + result.Dispose(); + + if (items.Count > 0) + { + return items[0]; + } + else + { + return null; + } + } + } + catch (Exception e) + { + database.Reconnect(); + Console.WriteLine(e.ToString()); + return null; + } + } + + /// + /// Returns a specified inventory folder + /// + /// The folder to return + /// A folder class + public InventoryFolderBase getInventoryFolder(LLUUID folder) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?uuid"] = folder.ToStringHyphenated(); + + IDbCommand result = database.Query("SELECT * FROM inventoryfolders WHERE folderID = ?uuid", param); + IDataReader reader = result.ExecuteReader(); + + List items = database.readInventoryFolders(reader); + + reader.Close(); + result.Dispose(); + + if (items.Count > 0) + { + return items[0]; + } + else + { + return null; + } + } + } + catch (Exception e) + { + database.Reconnect(); + Console.WriteLine(e.ToString()); + return null; + } + } + + /// + /// Adds a specified item to the database + /// + /// The inventory item + public void addInventoryItem(InventoryItemBase item) + { + lock (database) + { + database.insertItem(item); + } + } + + /// + /// Updates the specified inventory item + /// + /// Inventory item to update + public void updateInventoryItem(InventoryItemBase item) + { + addInventoryItem(item); + } + + /// + /// + /// + /// + public void deleteInventoryItem(InventoryItemBase item) + { + + } + + /// + /// Creates a new inventory folder + /// + /// Folder to create + public void addInventoryFolder(InventoryFolderBase folder) + { + lock (database) + { + database.insertFolder(folder); + } + } + + /// + /// Updates an inventory folder + /// + /// Folder to update + public void updateInventoryFolder(InventoryFolderBase folder) + { + addInventoryFolder(folder); + } + } +} diff --git a/OpenSim/Framework/Data.MySQL/MySQLLogData.cs b/OpenSim/Framework/Data.MySQL/MySQLLogData.cs new file mode 100644 index 0000000000..38f9fd3940 --- /dev/null +++ b/OpenSim/Framework/Data.MySQL/MySQLLogData.cs @@ -0,0 +1,105 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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; + +namespace OpenSim.Framework.Data.MySQL +{ + /// + /// An interface to the log database for MySQL + /// + class MySQLLogData : ILogData + { + /// + /// The database manager + /// + public MySQLManager database; + + /// + /// Artificial constructor called when the plugin is loaded + /// + public void Initialise() + { + IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini"); + string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname"); + string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database"); + string settingUsername = GridDataMySqlFile.ParseFileReadValue("username"); + string settingPassword = GridDataMySqlFile.ParseFileReadValue("password"); + string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling"); + string settingPort = GridDataMySqlFile.ParseFileReadValue("port"); + + database = new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, settingPooling, settingPort); + } + + /// + /// Saves a log item to the database + /// + /// The daemon triggering the event + /// The target of the action (region / agent UUID, etc) + /// The method call where the problem occured + /// The arguments passed to the method + /// How critical is this? + /// The message to log + public void saveLog(string serverDaemon, string target, string methodCall, string arguments, int priority, string logMessage) + { + try + { + database.insertLogRow(serverDaemon, target, methodCall, arguments, priority, logMessage); + } + catch + { + database.Reconnect(); + } + } + + /// + /// Returns the name of this DB provider + /// + /// A string containing the DB provider name + public string getName() + { + return "MySQL Logdata Interface"; + } + + /// + /// Closes the database provider + /// + public void Close() + { + // Do nothing. + } + + /// + /// Returns the version of this DB provider + /// + /// A string containing the provider version + public string getVersion() + { + return "0.1"; + } + } +} diff --git a/OpenSim/Framework/Data.MySQL/MySQLManager.cs b/OpenSim/Framework/Data.MySQL/MySQLManager.cs new file mode 100644 index 0000000000..2a6f8ade78 --- /dev/null +++ b/OpenSim/Framework/Data.MySQL/MySQLManager.cs @@ -0,0 +1,692 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; +using MySql.Data.MySqlClient; + +namespace OpenSim.Framework.Data.MySQL +{ + /// + /// A MySQL Database manager + /// + class MySQLManager + { + /// + /// The database connection object + /// + IDbConnection dbcon; + /// + /// Connection string for ADO.net + /// + string connectionString; + + /// + /// Initialises and creates a new MySQL connection and maintains it. + /// + /// The MySQL server being connected to + /// The name of the MySQL database being used + /// The username logging into the database + /// The password for the user logging in + /// Whether to use connection pooling or not, can be one of the following: 'yes', 'true', 'no' or 'false', if unsure use 'false'. + public MySQLManager(string hostname, string database, string username, string password, string cpooling, string port) + { + try + { + connectionString = "Server=" + hostname + ";Port=" + port + ";Database=" + database + ";User ID=" + username + ";Password=" + password + ";Pooling=" + cpooling + ";"; + dbcon = new MySqlConnection(connectionString); + + dbcon.Open(); + + Console.WriteLine("MySQL connection established"); + } + catch (Exception e) + { + throw new Exception("Error initialising MySql Database: " + e.ToString()); + } + } + + /// + /// Shuts down the database connection + /// + public void Close() + { + dbcon.Close(); + dbcon = null; + } + + /// + /// Reconnects to the database + /// + public void Reconnect() + { + lock (dbcon) + { + try + { + // Close the DB connection + dbcon.Close(); + // Try reopen it + dbcon = new MySqlConnection(connectionString); + dbcon.Open(); + } + catch (Exception e) + { + Console.WriteLine("Unable to reconnect to database " + e.ToString()); + } + } + } + + /// + /// Runs a query with protection against SQL Injection by using parameterised input. + /// + /// The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y + /// The parameters - index so that @y is indexed as 'y' + /// A MySQL DB Command + public IDbCommand Query(string sql, Dictionary parameters) + { + try + { + MySqlCommand dbcommand = (MySqlCommand)dbcon.CreateCommand(); + dbcommand.CommandText = sql; + foreach (KeyValuePair param in parameters) + { + dbcommand.Parameters.Add(param.Key, param.Value); + } + + return (IDbCommand)dbcommand; + } + catch + { + lock (dbcon) + { + // Close the DB connection + try + { + dbcon.Close(); + } + catch { } + + // Try reopen it + try + { + dbcon = new MySqlConnection(connectionString); + dbcon.Open(); + } + catch (Exception e) + { + Console.WriteLine("Unable to reconnect to database " + e.ToString()); + } + + // Run the query again + try + { + MySqlCommand dbcommand = (MySqlCommand)dbcon.CreateCommand(); + dbcommand.CommandText = sql; + foreach (KeyValuePair param in parameters) + { + dbcommand.Parameters.Add(param.Key, param.Value); + } + + return (IDbCommand)dbcommand; + } + catch (Exception e) + { + // Return null if it fails. + Console.WriteLine("Failed during Query generation: " + e.ToString()); + return null; + } + } + } + } + + /// + /// Reads a region row from a database reader + /// + /// An active database reader + /// A region profile + public SimProfileData readSimRow(IDataReader reader) + { + SimProfileData retval = new SimProfileData(); + + if (reader.Read()) + { + // Region Main + retval.regionHandle = Convert.ToUInt64(reader["regionHandle"].ToString()); + retval.regionName = (string)reader["regionName"]; + retval.UUID = new LLUUID((string)reader["uuid"]); + + // Secrets + retval.regionRecvKey = (string)reader["regionRecvKey"]; + retval.regionSecret = (string)reader["regionSecret"]; + retval.regionSendKey = (string)reader["regionSendKey"]; + + // Region Server + retval.regionDataURI = (string)reader["regionDataURI"]; + retval.regionOnline = false; // Needs to be pinged before this can be set. + retval.serverIP = (string)reader["serverIP"]; + retval.serverPort = (uint)reader["serverPort"]; + retval.serverURI = (string)reader["serverURI"]; + retval.httpPort = Convert.ToUInt32(reader["serverHttpPort"].ToString()); + retval.remotingPort = Convert.ToUInt32(reader["serverRemotingPort"].ToString()); + + // Location + retval.regionLocX = Convert.ToUInt32(reader["locX"].ToString()); + retval.regionLocY = Convert.ToUInt32(reader["locY"].ToString()); + retval.regionLocZ = Convert.ToUInt32(reader["locZ"].ToString()); + + // Neighbours - 0 = No Override + retval.regionEastOverrideHandle = Convert.ToUInt64(reader["eastOverrideHandle"].ToString()); + retval.regionWestOverrideHandle = Convert.ToUInt64(reader["westOverrideHandle"].ToString()); + retval.regionSouthOverrideHandle = Convert.ToUInt64(reader["southOverrideHandle"].ToString()); + retval.regionNorthOverrideHandle = Convert.ToUInt64(reader["northOverrideHandle"].ToString()); + + // Assets + retval.regionAssetURI = (string)reader["regionAssetURI"]; + retval.regionAssetRecvKey = (string)reader["regionAssetRecvKey"]; + retval.regionAssetSendKey = (string)reader["regionAssetSendKey"]; + + // Userserver + retval.regionUserURI = (string)reader["regionUserURI"]; + retval.regionUserRecvKey = (string)reader["regionUserRecvKey"]; + retval.regionUserSendKey = (string)reader["regionUserSendKey"]; + + // World Map Addition + string tempRegionMap = reader["regionMapTexture"].ToString(); + if (tempRegionMap != "") + { + retval.regionMapTextureID = new LLUUID(tempRegionMap); + } + else + { + retval.regionMapTextureID = new LLUUID(); + } + } + else + { + return null; + } + return retval; + } + + /// + /// Reads a reservation row from a database reader + /// + /// An active database reader + /// A reservation data object + public ReservationData readReservationRow(IDataReader reader) + { + ReservationData retval = new ReservationData(); + if (reader.Read()) + { + retval.gridRecvKey = (string)reader["gridRecvKey"]; + retval.gridSendKey = (string)reader["gridSendKey"]; + retval.reservationCompany = (string)reader["resCompany"]; + retval.reservationMaxX = Convert.ToInt32(reader["resXMax"].ToString()); + retval.reservationMaxY = Convert.ToInt32(reader["resYMax"].ToString()); + retval.reservationMinX = Convert.ToInt32(reader["resXMin"].ToString()); + retval.reservationMinY = Convert.ToInt32(reader["resYMin"].ToString()); + retval.reservationName = (string)reader["resName"]; + retval.status = Convert.ToInt32(reader["status"].ToString()) == 1; + retval.userUUID = new LLUUID((string)reader["userUUID"]); + + } + else + { + return null; + } + return retval; + } + /// + /// Reads an agent row from a database reader + /// + /// An active database reader + /// A user session agent + public UserAgentData readAgentRow(IDataReader reader) + { + UserAgentData retval = new UserAgentData(); + + if (reader.Read()) + { + // Agent IDs + retval.UUID = new LLUUID((string)reader["UUID"]); + retval.sessionID = new LLUUID((string)reader["sessionID"]); + retval.secureSessionID = new LLUUID((string)reader["secureSessionID"]); + + // Agent Who? + retval.agentIP = (string)reader["agentIP"]; + retval.agentPort = Convert.ToUInt32(reader["agentPort"].ToString()); + retval.agentOnline = Convert.ToBoolean(reader["agentOnline"].ToString()); + + // Login/Logout times (UNIX Epoch) + retval.loginTime = Convert.ToInt32(reader["loginTime"].ToString()); + retval.logoutTime = Convert.ToInt32(reader["logoutTime"].ToString()); + + // Current position + retval.currentRegion = (string)reader["currentRegion"]; + retval.currentHandle = Convert.ToUInt64(reader["currentHandle"].ToString()); + LLVector3.TryParse((string)reader["currentPos"], out retval.currentPos); + } + else + { + return null; + } + return retval; + } + + /// + /// Reads a user profile from an active data reader + /// + /// An active database reader + /// A user profile + public UserProfileData readUserRow(IDataReader reader) + { + UserProfileData retval = new UserProfileData(); + + if (reader.Read()) + { + retval.UUID = new LLUUID((string)reader["UUID"]); + retval.username = (string)reader["username"]; + retval.surname = (string)reader["lastname"]; + + retval.passwordHash = (string)reader["passwordHash"]; + retval.passwordSalt = (string)reader["passwordSalt"]; + + retval.homeRegion = Convert.ToUInt64(reader["homeRegion"].ToString()); + retval.homeLocation = new LLVector3( + Convert.ToSingle(reader["homeLocationX"].ToString()), + Convert.ToSingle(reader["homeLocationY"].ToString()), + Convert.ToSingle(reader["homeLocationZ"].ToString())); + retval.homeLookAt = new LLVector3( + Convert.ToSingle(reader["homeLookAtX"].ToString()), + Convert.ToSingle(reader["homeLookAtY"].ToString()), + Convert.ToSingle(reader["homeLookAtZ"].ToString())); + + retval.created = Convert.ToInt32(reader["created"].ToString()); + retval.lastLogin = Convert.ToInt32(reader["lastLogin"].ToString()); + + retval.userInventoryURI = (string)reader["userInventoryURI"]; + retval.userAssetURI = (string)reader["userAssetURI"]; + + retval.profileCanDoMask = Convert.ToUInt32(reader["profileCanDoMask"].ToString()); + retval.profileWantDoMask = Convert.ToUInt32(reader["profileWantDoMask"].ToString()); + + retval.profileAboutText = (string)reader["profileAboutText"]; + retval.profileFirstText = (string)reader["profileFirstText"]; + + retval.profileImage = new LLUUID((string)reader["profileImage"]); + retval.profileFirstImage = new LLUUID((string)reader["profileFirstImage"]); + + } + else + { + return null; + } + return retval; + } + + /// + /// Reads a list of inventory folders returned by a query. + /// + /// A MySQL Data Reader + /// A List containing inventory folders + public List readInventoryFolders(IDataReader reader) + { + List rows = new List(); + + while(reader.Read()) + { + try + { + InventoryFolderBase folder = new InventoryFolderBase(); + + folder.agentID = new LLUUID((string)reader["agentID"]); + folder.parentID = new LLUUID((string)reader["parentFolderID"]); + folder.folderID = new LLUUID((string)reader["folderID"]); + folder.name = (string)reader["folderName"]; + + rows.Add(folder); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + } + + return rows; + } + + /// + /// Reads a collection of items from an SQL result + /// + /// The SQL Result + /// A List containing Inventory Items + public List readInventoryItems(IDataReader reader) + { + List rows = new List(); + + while (reader.Read()) + { + try + { + InventoryItemBase item = new InventoryItemBase(); + + item.assetID = new LLUUID((string)reader["assetID"]); + item.avatarID = new LLUUID((string)reader["avatarID"]); + item.inventoryCurrentPermissions = Convert.ToUInt32(reader["inventoryCurrentPermissions"].ToString()); + item.inventoryDescription = (string)reader["inventoryDescription"]; + item.inventoryID = new LLUUID((string)reader["inventoryID"]); + item.inventoryName = (string)reader["inventoryName"]; + item.inventoryNextPermissions = Convert.ToUInt32(reader["inventoryNextPermissions"].ToString()); + item.parentFolderID = new LLUUID((string)reader["parentFolderID"]); + item.assetType = Convert.ToInt32(reader["type"].ToString()); + + rows.Add(item); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + } + + return rows; + } + + /// + /// Inserts a new row into the log database + /// + /// The daemon which triggered this event + /// Who were we operating on when this occured (region UUID, user UUID, etc) + /// The method call where the problem occured + /// The arguments passed to the method + /// How critical is this? + /// Extra message info + /// Saved successfully? + public bool insertLogRow(string serverDaemon, string target, string methodCall, string arguments, int priority, string logMessage) + { + string sql = "INSERT INTO logs (`target`, `server`, `method`, `arguments`, `priority`, `message`) VALUES "; + sql += "(?target, ?server, ?method, ?arguments, ?priority, ?message)"; + + Dictionary parameters = new Dictionary(); + parameters["?server"] = serverDaemon; + parameters["?target"] = target; + parameters["?method"] = methodCall; + parameters["?arguments"] = arguments; + parameters["?priority"] = priority.ToString(); + parameters["?message"] = logMessage; + + bool returnval = false; + + try + { + IDbCommand result = Query(sql, parameters); + + if (result.ExecuteNonQuery() == 1) + returnval = true; + + result.Dispose(); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + return false; + } + + return returnval; + } + + /// + /// Inserts a new item into the database + /// + /// The item + /// Success? + public bool insertItem(InventoryItemBase item) + { + string sql = "REPLACE INTO inventoryitems (inventoryID, assetID, type, parentFolderID, avatarID, inventoryName, inventoryDescription, inventoryNextPermissions, inventoryCurrentPermissions) VALUES "; + sql += "(?inventoryID, ?assetID, ?type, ?parentFolderID, ?avatarID, ?inventoryName, ?inventoryDescription, ?inventoryNextPermissions, ?inventoryCurrentPermissions)"; + + Dictionary parameters = new Dictionary(); + parameters["?inventoryID"] = item.inventoryID.ToStringHyphenated(); + parameters["?assetID"] = item.assetID.ToStringHyphenated(); + parameters["?type"] = item.assetType.ToString(); + parameters["?parentFolderID"] = item.parentFolderID.ToStringHyphenated(); + parameters["?avatarID"] = item.avatarID.ToStringHyphenated(); + parameters["?inventoryName"] = item.inventoryName; + parameters["?inventoryDescription"] = item.inventoryDescription; + parameters["?inventoryNextPermissions"] = item.inventoryNextPermissions.ToString(); + parameters["?inventoryCurrentPermissions"] = item.inventoryCurrentPermissions.ToString(); + + bool returnval = false; + + try + { + IDbCommand result = Query(sql, parameters); + + if (result.ExecuteNonQuery() == 1) + returnval = true; + + result.Dispose(); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + return false; + } + + return returnval; + } + + /// + /// Inserts a new folder into the database + /// + /// The folder + /// Success? + public bool insertFolder(InventoryFolderBase folder) + { + string sql = "REPLACE INTO inventoryfolders (folderID, agentID, parentFolderID, folderName) VALUES "; + sql += "(?folderID, ?agentID, ?parentFolderID, ?folderName)"; + + Dictionary parameters = new Dictionary(); + parameters["?folderID"] = folder.folderID.ToStringHyphenated(); + parameters["?agentID"] = folder.agentID.ToStringHyphenated(); + parameters["?parentFolderID"] = folder.parentID.ToStringHyphenated(); + parameters["?folderName"] = folder.name; + + bool returnval = false; + try + { + IDbCommand result = Query(sql, parameters); + + if (result.ExecuteNonQuery() == 1) + returnval = true; + + result.Dispose(); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + return false; + } + return returnval; + } + + /// + /// Creates a new user and inserts it into the database + /// + /// User ID + /// First part of the login + /// Second part of the login + /// A salted hash of the users password + /// The salt used for the password hash + /// A regionHandle of the users home region + /// Home region position vector + /// Home region position vector + /// Home region position vector + /// Home region 'look at' vector + /// Home region 'look at' vector + /// Home region 'look at' vector + /// Account created (unix timestamp) + /// Last login (unix timestamp) + /// Users inventory URI + /// Users asset URI + /// I can do mask + /// I want to do mask + /// Profile text + /// Firstlife text + /// UUID for profile image + /// UUID for firstlife image + /// Success? + public bool insertUserRow(libsecondlife.LLUUID uuid, string username, string lastname, string passwordHash, string passwordSalt, UInt64 homeRegion, float homeLocX, float homeLocY, float homeLocZ, + float homeLookAtX, float homeLookAtY, float homeLookAtZ, int created, int lastlogin, string inventoryURI, string assetURI, uint canDoMask, uint wantDoMask, string aboutText, string firstText, + libsecondlife.LLUUID profileImage, libsecondlife.LLUUID firstImage) + { + string sql = "INSERT INTO users (`UUID`, `username`, `lastname`, `passwordHash`, `passwordSalt`, `homeRegion`, "; + sql += "`homeLocationX`, `homeLocationY`, `homeLocationZ`, `homeLookAtX`, `homeLookAtY`, `homeLookAtZ`, `created`, "; + sql += "`lastLogin`, `userInventoryURI`, `userAssetURI`, `profileCanDoMask`, `profileWantDoMask`, `profileAboutText`, "; + sql += "`profileFirstText`, `profileImage`, `profileFirstImage`) VALUES "; + + sql += "(?UUID, ?username, ?lastname, ?passwordHash, ?passwordSalt, ?homeRegion, "; + sql += "?homeLocationX, ?homeLocationY, ?homeLocationZ, ?homeLookAtX, ?homeLookAtY, ?homeLookAtZ, ?created, "; + sql += "?lastLogin, ?userInventoryURI, ?userAssetURI, ?profileCanDoMask, ?profileWantDoMask, ?profileAboutText, "; + sql += "?profileFirstText, ?profileImage, ?profileFirstImage)"; + + Dictionary parameters = new Dictionary(); + parameters["?UUID"] = uuid.ToStringHyphenated(); + parameters["?username"] = username.ToString(); + parameters["?lastname"] = lastname.ToString(); + parameters["?passwordHash"] = passwordHash.ToString(); + parameters["?passwordSalt"] = passwordSalt.ToString(); + parameters["?homeRegion"] = homeRegion.ToString(); + parameters["?homeLocationX"] = homeLocX.ToString(); + parameters["?homeLocationY"] = homeLocY.ToString(); + parameters["?homeLocationZ"] = homeLocZ.ToString(); + parameters["?homeLookAtX"] = homeLookAtX.ToString(); + parameters["?homeLookAtY"] = homeLookAtY.ToString(); + parameters["?homeLookAtZ"] = homeLookAtZ.ToString(); + parameters["?created"] = created.ToString(); + parameters["?lastLogin"] = lastlogin.ToString(); + parameters["?userInventoryURI"] = ""; + parameters["?userAssetURI"] = ""; + parameters["?profileCanDoMask"] = "0"; + parameters["?profileWantDoMask"] = "0"; + parameters["?profileAboutText"] = ""; + parameters["?profileFirstText"] = ""; + parameters["?profileImage"] = libsecondlife.LLUUID.Zero.ToStringHyphenated(); + parameters["?profileFirstImage"] = libsecondlife.LLUUID.Zero.ToStringHyphenated(); + + bool returnval = false; + + try + { + IDbCommand result = Query(sql, parameters); + + if (result.ExecuteNonQuery() == 1) + returnval = true; + + result.Dispose(); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + return false; + } + + return returnval; + } + + + /// + /// Inserts a new region into the database + /// + /// The region to insert + /// Success? + public bool insertRegion(SimProfileData regiondata) + { + string sql = "REPLACE INTO regions (regionHandle, regionName, uuid, regionRecvKey, regionSecret, regionSendKey, regionDataURI, "; + sql += "serverIP, serverPort, serverURI, locX, locY, locZ, eastOverrideHandle, westOverrideHandle, southOverrideHandle, northOverrideHandle, regionAssetURI, regionAssetRecvKey, "; + sql += "regionAssetSendKey, regionUserURI, regionUserRecvKey, regionUserSendKey, regionMapTexture, serverHttpPort, serverRemotingPort) VALUES "; + + sql += "(?regionHandle, ?regionName, ?uuid, ?regionRecvKey, ?regionSecret, ?regionSendKey, ?regionDataURI, "; + sql += "?serverIP, ?serverPort, ?serverURI, ?locX, ?locY, ?locZ, ?eastOverrideHandle, ?westOverrideHandle, ?southOverrideHandle, ?northOverrideHandle, ?regionAssetURI, ?regionAssetRecvKey, "; + sql += "?regionAssetSendKey, ?regionUserURI, ?regionUserRecvKey, ?regionUserSendKey, ?regionMapTexture, ?serverHttpPort, ?serverRemotingPort);"; + + Dictionary parameters = new Dictionary(); + + parameters["?regionHandle"] = regiondata.regionHandle.ToString(); + parameters["?regionName"] = regiondata.regionName.ToString(); + parameters["?uuid"] = regiondata.UUID.ToStringHyphenated(); + parameters["?regionRecvKey"] = regiondata.regionRecvKey.ToString(); + parameters["?regionSecret"] = regiondata.regionSecret.ToString(); + parameters["?regionSendKey"] = regiondata.regionSendKey.ToString(); + parameters["?regionDataURI"] = regiondata.regionDataURI.ToString(); + parameters["?serverIP"] = regiondata.serverIP.ToString(); + parameters["?serverPort"] = regiondata.serverPort.ToString(); + parameters["?serverURI"] = regiondata.serverURI.ToString(); + parameters["?locX"] = regiondata.regionLocX.ToString(); + parameters["?locY"] = regiondata.regionLocY.ToString(); + parameters["?locZ"] = regiondata.regionLocZ.ToString(); + parameters["?eastOverrideHandle"] = regiondata.regionEastOverrideHandle.ToString(); + parameters["?westOverrideHandle"] = regiondata.regionWestOverrideHandle.ToString(); + parameters["?northOverrideHandle"] = regiondata.regionNorthOverrideHandle.ToString(); + parameters["?southOverrideHandle"] = regiondata.regionSouthOverrideHandle.ToString(); + parameters["?regionAssetURI"] = regiondata.regionAssetURI.ToString(); + parameters["?regionAssetRecvKey"] = regiondata.regionAssetRecvKey.ToString(); + parameters["?regionAssetSendKey"] = regiondata.regionAssetSendKey.ToString(); + parameters["?regionUserURI"] = regiondata.regionUserURI.ToString(); + parameters["?regionUserRecvKey"] = regiondata.regionUserRecvKey.ToString(); + parameters["?regionUserSendKey"] = regiondata.regionUserSendKey.ToString(); + parameters["?regionMapTexture"] = regiondata.regionMapTextureID.ToStringHyphenated(); + parameters["?serverHttpPort"] = regiondata.httpPort.ToString(); + parameters["?serverRemotingPort"] = regiondata.remotingPort.ToString(); + + bool returnval = false; + + try + { + + IDbCommand result = Query(sql, parameters); + + //Console.WriteLine(result.CommandText); + int x; + if ((x = result.ExecuteNonQuery()) > 0) + { + returnval = true; + } + result.Dispose(); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + return false; + } + + return returnval; + } + } +} diff --git a/OpenSim/Framework/Data.MySQL/MySQLUserData.cs b/OpenSim/Framework/Data.MySQL/MySQLUserData.cs new file mode 100644 index 0000000000..9fb43d9e3d --- /dev/null +++ b/OpenSim/Framework/Data.MySQL/MySQLUserData.cs @@ -0,0 +1,278 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; + +namespace OpenSim.Framework.Data.MySQL +{ + /// + /// A database interface class to a user profile storage system + /// + class MySQLUserData : IUserData + { + /// + /// Database manager for MySQL + /// + public MySQLManager database; + + /// + /// Loads and initialises the MySQL storage plugin + /// + public void Initialise() + { + // Load from an INI file connection details + // TODO: move this to XML? + IniFile GridDataMySqlFile = new IniFile("mysql_connection.ini"); + string settingHostname = GridDataMySqlFile.ParseFileReadValue("hostname"); + string settingDatabase = GridDataMySqlFile.ParseFileReadValue("database"); + string settingUsername = GridDataMySqlFile.ParseFileReadValue("username"); + string settingPassword = GridDataMySqlFile.ParseFileReadValue("password"); + string settingPooling = GridDataMySqlFile.ParseFileReadValue("pooling"); + string settingPort = GridDataMySqlFile.ParseFileReadValue("port"); + + database = new MySQLManager(settingHostname, settingDatabase, settingUsername, settingPassword, settingPooling, settingPort); + } + + /// + /// Searches the database for a specified user profile + /// + /// The account name of the user + /// A user profile + public UserProfileData getUserByName(string name) + { + return getUserByName(name.Split(' ')[0], name.Split(' ')[1]); + } + + /// + /// Searches the database for a specified user profile by name components + /// + /// The first part of the account name + /// The second part of the account name + /// A user profile + public UserProfileData getUserByName(string user, string last) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?first"] = user; + param["?second"] = last; + + IDbCommand result = database.Query("SELECT * FROM users WHERE username = ?first AND lastname = ?second", param); + IDataReader reader = result.ExecuteReader(); + + UserProfileData row = database.readUserRow(reader); + + reader.Close(); + result.Dispose(); + + return row; + } + } + catch (Exception e) + { + database.Reconnect(); + Console.WriteLine(e.ToString()); + return null; + } + } + + /// + /// Searches the database for a specified user profile by UUID + /// + /// The account ID + /// The users profile + public UserProfileData getUserByUUID(LLUUID uuid) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?uuid"] = uuid.ToStringHyphenated(); + + IDbCommand result = database.Query("SELECT * FROM users WHERE UUID = ?uuid", param); + IDataReader reader = result.ExecuteReader(); + + UserProfileData row = database.readUserRow(reader); + + reader.Close(); + result.Dispose(); + + return row; + } + } + catch (Exception e) + { + database.Reconnect(); + Console.WriteLine(e.ToString()); + return null; + } + } + + /// + /// Returns a user session searching by name + /// + /// The account name + /// The users session + public UserAgentData getAgentByName(string name) + { + return getAgentByName(name.Split(' ')[0], name.Split(' ')[1]); + } + + /// + /// Returns a user session by account name + /// + /// First part of the users account name + /// Second part of the users account name + /// The users session + public UserAgentData getAgentByName(string user, string last) + { + UserProfileData profile = getUserByName(user, last); + return getAgentByUUID(profile.UUID); + } + + /// + /// Returns an agent session by account UUID + /// + /// The accounts UUID + /// The users session + public UserAgentData getAgentByUUID(LLUUID uuid) + { + try + { + lock (database) + { + Dictionary param = new Dictionary(); + param["?uuid"] = uuid.ToStringHyphenated(); + + IDbCommand result = database.Query("SELECT * FROM agents WHERE UUID = ?uuid", param); + IDataReader reader = result.ExecuteReader(); + + UserAgentData row = database.readAgentRow(reader); + + reader.Close(); + result.Dispose(); + + return row; + } + } + catch (Exception e) + { + database.Reconnect(); + Console.WriteLine(e.ToString()); + return null; + } + } + + /// + /// Creates a new users profile + /// + /// The user profile to create + public void addNewUserProfile(UserProfileData user) + { + try + { + lock (database) + { + database.insertUserRow(user.UUID, user.username, user.surname, user.passwordHash, user.passwordSalt, user.homeRegion, user.homeLocation.X, user.homeLocation.Y, user.homeLocation.Z, + user.homeLookAt.X, user.homeLookAt.Y, user.homeLookAt.Z, user.created, user.lastLogin, user.userInventoryURI, user.userAssetURI, user.profileCanDoMask, user.profileWantDoMask, + user.profileAboutText, user.profileFirstText, user.profileImage, user.profileFirstImage); + } + } + catch (Exception e) + { + database.Reconnect(); + Console.WriteLine(e.ToString()); + } + + } + + /// + /// Creates a new agent + /// + /// The agent to create + public void addNewUserAgent(UserAgentData agent) + { + // Do nothing. + } + + + public bool updateUserProfile(UserProfileData user) + { + return true; + // TODO: implement + } + + /// + /// Performs a money transfer request between two accounts + /// + /// The senders account ID + /// The recievers account ID + /// The amount to transfer + /// Success? + public bool moneyTransferRequest(LLUUID from, LLUUID to, uint amount) + { + return false; + } + + /// + /// Performs an inventory transfer request between two accounts + /// + /// TODO: Move to inventory server + /// The senders account ID + /// The recievers account ID + /// The item to transfer + /// Success? + public bool inventoryTransferRequest(LLUUID from, LLUUID to, LLUUID item) + { + return false; + } + + /// + /// Database provider name + /// + /// Provider name + public string getName() + { + return "MySQL Userdata Interface"; + } + + /// + /// Database provider version + /// + /// provider version + public string getVersion() + { + return "0.1"; + } + } +} diff --git a/OpenSim/Framework/Data.MySQL/Properties/AssemblyInfo.cs b/OpenSim/Framework/Data.MySQL/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..52d6a54499 --- /dev/null +++ b/OpenSim/Framework/Data.MySQL/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.Framework.Data.MySQL")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OpenSim.Framework.Data.MySQL")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("e49826b2-dcef-41be-a5bd-596733fa3304")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/Data.SQLite/Properties/AssemblyInfo.cs b/OpenSim/Framework/Data.SQLite/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..9de5edbc53 --- /dev/null +++ b/OpenSim/Framework/Data.SQLite/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.Framework.Data.SQLite")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OpenSim.Framework.Data.SQLite")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("6113d5ce-4547-49f4-9236-0dcc503457b1")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/Data.SQLite/SQLiteGridData.cs b/OpenSim/Framework/Data.SQLite/SQLiteGridData.cs new file mode 100644 index 0000000000..511c5f020c --- /dev/null +++ b/OpenSim/Framework/Data.SQLite/SQLiteGridData.cs @@ -0,0 +1,197 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Security.Cryptography; +using System.Text; +using libsecondlife; + +namespace OpenSim.Framework.Data.SQLite +{ + /// + /// A Grid Interface to the SQLite database + /// + public class SQLiteGridData : IGridData + { + /// + /// A database manager + /// + private SQLiteManager database; + + /// + /// Initialises the Grid Interface + /// + public void Initialise() + { + database = new SQLiteManager("localhost", "db", "user", "password", "false"); + } + + /// + /// Shuts down the grid interface + /// + public void Close() + { + database.Close(); + } + + /// + /// Returns the name of this grid interface + /// + /// A string containing the grid interface + public string getName() + { + return "SQLite OpenGridData"; + } + + /// + /// Returns the version of this grid interface + /// + /// A string containing the version + public string getVersion() + { + return "0.1"; + } + + /// + /// Returns a list of regions within the specified ranges + /// + /// minimum X coordinate + /// minimum Y coordinate + /// maximum X coordinate + /// maximum Y coordinate + /// An array of region profiles + public SimProfileData[] GetProfilesInRange(uint a, uint b, uint c, uint d) + { + return null; + } + + /// + /// Returns a sim profile from it's location + /// + /// Region location handle + /// Sim profile + public SimProfileData GetProfileByHandle(ulong handle) + { + Dictionary param = new Dictionary(); + param["handle"] = handle.ToString(); + + IDbCommand result = database.Query("SELECT * FROM regions WHERE handle = @handle", param); + IDataReader reader = result.ExecuteReader(); + + SimProfileData row = database.getRow(reader); + reader.Close(); + result.Dispose(); + + return row; + } + + /// + /// Returns a sim profile from it's UUID + /// + /// The region UUID + /// The sim profile + public SimProfileData GetProfileByLLUUID(LLUUID uuid) + { + Dictionary param = new Dictionary(); + param["uuid"] = uuid.ToStringHyphenated(); + + IDbCommand result = database.Query("SELECT * FROM regions WHERE uuid = @uuid", param); + IDataReader reader = result.ExecuteReader(); + + SimProfileData row = database.getRow(reader); + reader.Close(); + result.Dispose(); + + return row; + } + + /// + /// Adds a new specified region to the database + /// + /// The profile to add + /// A dataresponse enum indicating success + public DataResponse AddProfile(SimProfileData profile) + { + if (database.insertRow(profile)) + { + return DataResponse.RESPONSE_OK; + } + else + { + return DataResponse.RESPONSE_ERROR; + } + } + + /// + /// DEPRECIATED. Attempts to authenticate a region by comparing a shared secret. + /// + /// The UUID of the challenger + /// The attempted regionHandle of the challenger + /// The secret + /// Whether the secret and regionhandle match the database entry for UUID + public bool AuthenticateSim(LLUUID uuid, ulong handle, string authkey) + { + bool throwHissyFit = false; // Should be true by 1.0 + + if (throwHissyFit) + throw new Exception("CRYPTOWEAK AUTHENTICATE: Refusing to authenticate due to replay potential."); + + SimProfileData data = GetProfileByLLUUID(uuid); + + return (handle == data.regionHandle && authkey == data.regionSecret); + } + + /// + /// NOT YET FUNCTIONAL. Provides a cryptographic authentication of a region + /// + /// This requires a security audit. + /// + /// + /// + /// + /// + public bool AuthenticateSim(LLUUID uuid, ulong handle, string authhash, string challenge) + { + SHA512Managed HashProvider = new SHA512Managed(); + ASCIIEncoding TextProvider = new ASCIIEncoding(); + + byte[] stream = TextProvider.GetBytes(uuid.ToStringHyphenated() + ":" + handle.ToString() + ":" + challenge); + byte[] hash = HashProvider.ComputeHash(stream); + + return false; + } + + public ReservationData GetReservationAtPoint(uint x, uint y) + { + return null; + } + } + + +} diff --git a/OpenSim/Framework/Data.SQLite/SQLiteInventoryStore.cs b/OpenSim/Framework/Data.SQLite/SQLiteInventoryStore.cs new file mode 100644 index 0000000000..fe494fbb72 --- /dev/null +++ b/OpenSim/Framework/Data.SQLite/SQLiteInventoryStore.cs @@ -0,0 +1,485 @@ +using System; +using System.Collections.Generic; +using System.Text; + +using OpenSim.Framework.Console; +using OpenSim.Framework.Types; +using OpenSim.Framework.Utilities; +using libsecondlife; + +using System.Data; +using System.Data.SqlTypes; + +using Mono.Data.SqliteClient; + +namespace OpenSim.Framework.Data.SQLite +{ + + public class SQLiteInventoryStore : IInventoryData + { + private const string invItemsSelect = "select * from inventoryitems"; + private const string invFoldersSelect = "select * from inventoryfolders"; + + private DataSet ds; + private SqliteDataAdapter invItemsDa; + private SqliteDataAdapter invFoldersDa; + + /// + /// Initialises the interface + /// + public void Initialise() + { + Initialise("inventoryStore.db", "inventoryDatabase"); + } + + public void Initialise(string dbfile, string dbname) + { + string connectionString = "URI=file:" + dbfile + ",version=3"; + + MainLog.Instance.Verbose("Inventory", "Sqlite - connecting: " + dbfile); + SqliteConnection conn = new SqliteConnection(connectionString); + + SqliteCommand itemsSelectCmd = new SqliteCommand(invItemsSelect, conn); + invItemsDa = new SqliteDataAdapter(itemsSelectCmd); + // SqliteCommandBuilder primCb = new SqliteCommandBuilder(primDa); + + SqliteCommand foldersSelectCmd = new SqliteCommand(invFoldersSelect, conn); + invFoldersDa = new SqliteDataAdapter(foldersSelectCmd); + + ds = new DataSet(); + + invItemsDa.Fill(ds, "inventoryitems"); + invFoldersDa.Fill(ds, "inventoryfolders"); + ds.AcceptChanges(); + + DataTable itemsTable = ds.Tables["inventoryitems"]; + itemsTable.PrimaryKey = new DataColumn[] { itemsTable.Columns["UUID"] }; + setupItemsCommands(invItemsDa, conn); + + // shapeDa.FillSchema(ds, SchemaType.Source, "ShapeSchema"); + DataTable folderTable = ds.Tables["inventoryfolders"]; + folderTable.PrimaryKey = new DataColumn[] { folderTable.Columns["UUID"] }; + setupFoldersCommands(invFoldersDa, conn); + return; + } + + private SqliteParameter createSqliteParameter(string name, DbType type) + { + SqliteParameter param = new SqliteParameter(); + param.ParameterName = ":" + name; + param.DbType = type; + param.SourceColumn = name; + param.SourceVersion = DataRowVersion.Current; + return param; + } + + private Dictionary createInventoryItemsDataDefs() + { + Dictionary data = new Dictionary(); + data.Add("UUID", DbType.String); //inventoryID + data.Add("assetID", DbType.String); + data.Add("assetType", DbType.Int32); + data.Add("invType", DbType.Int32); + data.Add("parentFolderID", DbType.String); + data.Add("avatarID", DbType.String); + data.Add("creatorsID", DbType.String); + + data.Add("inventoryName", DbType.String); + data.Add("inventoryDescription", DbType.String); + // permissions + data.Add("inventoryNextPermissions", DbType.Int32); + data.Add("inventoryCurrentPermissions", DbType.Int32); + data.Add("inventoryBasePermissions", DbType.Int32); + data.Add("inventoryEveryOnePermissions", DbType.Int32); + + return data; + } + + private Dictionary createShapeDataDefs() + { + Dictionary data = new Dictionary(); + data.Add("UUID", DbType.String); //folderID + // shape is an enum + data.Add("name", DbType.String); + // vectors + data.Add("agentID", DbType.String); + data.Add("parentID", DbType.String); + data.Add("type", DbType.Int32); + data.Add("version", DbType.Int32); + return data; + } + + private SqliteCommand createInsertCommand(string table, Dictionary defs) + { + /** + * This is subtle enough to deserve some commentary. + * Instead of doing *lots* and *lots of hardcoded strings + * for database definitions we'll use the fact that + * realistically all insert statements look like "insert + * into A(b, c) values(:b, :c) on the parameterized query + * front. If we just have a list of b, c, etc... we can + * generate these strings instead of typing them out. + */ + string[] cols = new string[defs.Keys.Count]; + defs.Keys.CopyTo(cols, 0); + + string sql = "insert into " + table + "("; + sql += String.Join(", ", cols); + // important, the first ':' needs to be here, the rest get added in the join + sql += ") values (:"; + sql += String.Join(", :", cols); + sql += ")"; + SqliteCommand cmd = new SqliteCommand(sql); + + // this provides the binding for all our parameters, so + // much less code than it used to be + foreach (KeyValuePair kvp in defs) + { + cmd.Parameters.Add(createSqliteParameter(kvp.Key, kvp.Value)); + } + return cmd; + } + + private SqliteCommand createUpdateCommand(string table, string pk, Dictionary defs) + { + string sql = "update " + table + " set "; + string subsql = ""; + foreach (string key in defs.Keys) + { + if (subsql.Length > 0) + { // a map function would rock so much here + subsql += ", "; + } + subsql += key + "= :" + key; + } + sql += subsql; + sql += " where " + pk; + SqliteCommand cmd = new SqliteCommand(sql); + + // this provides the binding for all our parameters, so + // much less code than it used to be + foreach (KeyValuePair kvp in defs) + { + cmd.Parameters.Add(createSqliteParameter(kvp.Key, kvp.Value)); + } + return cmd; + } + + private void setupItemsCommands(SqliteDataAdapter da, SqliteConnection conn) + { + Dictionary invDataDefs = createInventoryItemsDataDefs(); + + da.InsertCommand = createInsertCommand("inventoryitems", invDataDefs); + da.InsertCommand.Connection = conn; + + da.UpdateCommand = createUpdateCommand("inventoryitems", "UUID=:UUID", invDataDefs); + da.UpdateCommand.Connection = conn; + + SqliteCommand delete = new SqliteCommand("delete from inventoryitems where UUID = :UUID"); + delete.Parameters.Add(createSqliteParameter("UUID", DbType.String)); + delete.Connection = conn; + da.DeleteCommand = delete; + } + + private void setupFoldersCommands(SqliteDataAdapter da, SqliteConnection conn) + { + Dictionary shapeDataDefs = createShapeDataDefs(); + + da.InsertCommand = createInsertCommand("inventoryfolders", shapeDataDefs); + da.InsertCommand.Connection = conn; + + da.UpdateCommand = createUpdateCommand("inventoryfolders", "UUID=:UUID", shapeDataDefs); + da.UpdateCommand.Connection = conn; + + SqliteCommand delete = new SqliteCommand("delete from inventoryfolders where UUID = :UUID"); + delete.Parameters.Add(createSqliteParameter("UUID", DbType.String)); + delete.Connection = conn; + da.DeleteCommand = delete; + } + + private InventoryFolderBase buildFolder(DataRow row) + { + InventoryFolderBase folder = new InventoryFolderBase(); + folder.folderID = new LLUUID((string)row["UUID"]); + folder.name = (string)row["name"]; + folder.agentID = new LLUUID((string)row["agentID"]); + folder.parentID = new LLUUID((string)row["parentID"]); + folder.type = Convert.ToInt16(row["type"]); + folder.version = Convert.ToUInt16(row["version"]); + return folder; + } + + private void fillFolderRow(DataRow row, InventoryFolderBase folder) + { + row["UUID"] = folder.folderID; + row["name"] = folder.name; + row["agentID"] = folder.agentID; + row["parentID"] = folder.parentID; + row["type"] = folder.type; + row["version"] = folder.version; + } + + public InventoryItemBase BuildItem(DataRow row) + { + InventoryItemBase item = new InventoryItemBase(); + item.inventoryID = new LLUUID((string)row["UUID"]); + item.assetID = new LLUUID((string)row["assetID"]); + item.assetType = Convert.ToInt32(row["assetType"]); + item.invType = Convert.ToInt32(row["invType"]); + item.parentFolderID = new LLUUID((string)row["parentFolderID"]); + item.avatarID = new LLUUID((string)row["avatarID"]); + item.creatorsID = new LLUUID((string)row["creatorsID"]); + item.inventoryName =(string) row["inventoryName"]; + item.inventoryDescription = (string) row["inventoryDescription"]; + + item.inventoryNextPermissions = Convert.ToUInt32(row["inventoryNextPermissions"]); + item.inventoryCurrentPermissions = Convert.ToUInt32(row["inventoryCurrentPermissions"]); + item.inventoryBasePermissions = Convert.ToUInt32(row["inventoryBasePermissions"]); + item.inventoryEveryOnePermissions = Convert.ToUInt32(row["inventoryEveryOnePermissions"]); + return item; + } + + private void fillItemRow(DataRow row, InventoryItemBase item) + { + row["UUID"] = item.inventoryID; + row["assetID"] = item.assetID; + row["assetType"] = item.assetType; + row["invType"] = item.invType; + row["parentFolderID"] = item.parentFolderID; + row["avatarID"] = item.avatarID; + row["creatorsID"] = item.creatorsID; + row["inventoryName"] = item.inventoryName; + row["inventoryDescription"] = item.inventoryDescription; + + row["inventoryNextPermissions"] = item.inventoryNextPermissions; + row["inventoryCurrentPermissions"] = item.inventoryCurrentPermissions; + row["inventoryBasePermissions"] = item.inventoryBasePermissions; + row["inventoryEveryOnePermissions"] = item.inventoryEveryOnePermissions; + } + + private void addFolder(InventoryFolderBase folder) + { + DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; + + DataRow inventoryRow = inventoryFolderTable.Rows.Find(folder.folderID); + if (inventoryRow == null) + { + inventoryRow = inventoryFolderTable.NewRow(); + fillFolderRow(inventoryRow, folder); + inventoryFolderTable.Rows.Add(inventoryRow); + } + else + { + fillFolderRow(inventoryRow, folder); + } + + this.invFoldersDa.Update(ds, "inventoryfolders"); + } + + private void addItem(InventoryItemBase item) + { + DataTable inventoryItemTable = ds.Tables["inventoryitems"]; + + DataRow inventoryRow = inventoryItemTable.Rows.Find(item.inventoryID); + if (inventoryRow == null) + { + inventoryRow = inventoryItemTable.NewRow(); + fillItemRow(inventoryRow, item); + inventoryItemTable.Rows.Add(inventoryRow); + } + else + { + fillItemRow(inventoryRow, item); + } + this.invItemsDa.Update(ds, "inventoryitems"); + } + + public void Shutdown() + { + // TODO: DataSet commit + } + + /// + /// Closes the interface + /// + public void Close() + { + } + + /// + /// The plugin being loaded + /// + /// A string containing the plugin name + public string getName() + { + return "SQLite Inventory Data Interface"; + } + + /// + /// The plugins version + /// + /// A string containing the plugin version + public string getVersion() + { + return "0.1"; + } + + /// + /// Returns a list of inventory items contained within the specified folder + /// + /// The UUID of the target folder + /// A List of InventoryItemBase items + public List getInventoryInFolder(LLUUID folderID) + { + List retval = new List(); + DataTable inventoryItemTable = ds.Tables["inventoryitems"]; + string selectExp = "parentFolderID = '" + folderID.ToString() + "'"; + DataRow[] rows = inventoryItemTable.Select(selectExp); + foreach (DataRow row in rows) + { + retval.Add(BuildItem(row)); + } + + return retval; + } + + /// + /// Returns a list of the root folders within a users inventory + /// + /// The user whos inventory is to be searched + /// A list of folder objects + public List getUserRootFolders(LLUUID user) + { + return null; + } + + /// + /// Returns the users inventory root folder. + /// + /// The UUID of the user who is having inventory being returned + /// Root inventory folder + public InventoryFolderBase getUserRootFolder(LLUUID user) + { + List folders = new List(); + DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; + string selectExp = "agentID = '" + user.ToString() + "' AND parentID = '" + LLUUID.Zero.ToString() + "'"; + DataRow[] rows = inventoryFolderTable.Select(selectExp); + foreach (DataRow row in rows) + { + folders.Add(this.buildFolder(row)); + } + + if (folders.Count == 1) + { + //we found the root + //System.Console.WriteLine("found root inventory folder"); + return folders[0]; + } + else if (folders.Count > 1) + { + //err shouldn't be more than one root + //System.Console.WriteLine("found more than one root inventory folder"); + } + else if (folders.Count == 0) + { + // no root? + //System.Console.WriteLine("couldn't find root inventory folder"); + } + + return null; + } + + /// + /// Returns a list of inventory folders contained in the folder 'parentID' + /// + /// The folder to get subfolders for + /// A list of inventory folders + public List getInventoryFolders(LLUUID parentID) + { + List folders = new List(); + DataTable inventoryFolderTable = ds.Tables["inventoryfolders"]; + string selectExp = "parentID = '" + parentID.ToString() + "'"; + DataRow[] rows = inventoryFolderTable.Select(selectExp); + foreach (DataRow row in rows) + { + folders.Add(this.buildFolder(row)); + } + // System.Console.WriteLine("found " + folders.Count + " inventory folders"); + return folders; + } + + /// + /// Returns an inventory item by its UUID + /// + /// The UUID of the item to be returned + /// A class containing item information + public InventoryItemBase getInventoryItem(LLUUID item) + { + return null; + } + + /// + /// Returns a specified inventory folder by its UUID + /// + /// The UUID of the folder to be returned + /// A class containing folder information + public InventoryFolderBase getInventoryFolder(LLUUID folder) + { + return null; + } + + /// + /// Creates a new inventory item based on item + /// + /// The item to be created + public void addInventoryItem(InventoryItemBase item) + { + this.addItem(item); + } + + /// + /// Updates an inventory item with item (updates based on ID) + /// + /// The updated item + public void updateInventoryItem(InventoryItemBase item) + { + this.addItem(item); + } + + /// + /// + /// + /// + public void deleteInventoryItem(InventoryItemBase item) + { + DataTable inventoryItemTable = ds.Tables["inventoryitems"]; + + DataRow inventoryRow = inventoryItemTable.Rows.Find(item.inventoryID); + if (inventoryRow != null) + { + inventoryRow.Delete(); + } + + this.invItemsDa.Update(ds, "inventoryitems"); + } + + /// + /// Adds a new folder specified by folder + /// + /// The inventory folder + public void addInventoryFolder(InventoryFolderBase folder) + { + this.addFolder(folder); + } + + /// + /// Updates a folder based on its ID with folder + /// + /// The inventory folder + public void updateInventoryFolder(InventoryFolderBase folder) + { + this.addFolder(folder); + } + } +} + diff --git a/OpenSim/Framework/Data.SQLite/SQLiteManager.cs b/OpenSim/Framework/Data.SQLite/SQLiteManager.cs new file mode 100644 index 0000000000..c9931ab644 --- /dev/null +++ b/OpenSim/Framework/Data.SQLite/SQLiteManager.cs @@ -0,0 +1,206 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Data.SQLite; +using libsecondlife; + +namespace OpenSim.Framework.Data.SQLite +{ + class SQLiteManager + { + IDbConnection dbcon; + + /// + /// Initialises and creates a new SQLite connection and maintains it. + /// + /// The SQLite server being connected to + /// The name of the SQLite database being used + /// The username logging into the database + /// The password for the user logging in + /// Whether to use connection pooling or not, can be one of the following: 'yes', 'true', 'no' or 'false', if unsure use 'false'. + public SQLiteManager(string hostname, string database, string username, string password, string cpooling) + { + try + { + string connectionString = "URI=file:GridServerSqlite.db;"; + dbcon = new SQLiteConnection(connectionString); + + dbcon.Open(); + } + catch (Exception e) + { + throw new Exception("Error initialising SQLite Database: " + e.ToString()); + } + } + + /// + /// Shuts down the database connection + /// + public void Close() + { + dbcon.Close(); + dbcon = null; + } + + /// + /// Runs a query with protection against SQL Injection by using parameterised input. + /// + /// The SQL string - replace any variables such as WHERE x = "y" with WHERE x = @y + /// The parameters - index so that @y is indexed as 'y' + /// A SQLite DB Command + public IDbCommand Query(string sql, Dictionary parameters) + { + SQLiteCommand dbcommand = (SQLiteCommand)dbcon.CreateCommand(); + dbcommand.CommandText = sql; + foreach (KeyValuePair param in parameters) + { + SQLiteParameter paramx = new SQLiteParameter(param.Key,param.Value); + dbcommand.Parameters.Add(paramx); + } + + return (IDbCommand)dbcommand; + } + + /// + /// Reads a region row from a database reader + /// + /// An active database reader + /// A region profile + public SimProfileData getRow(IDataReader reader) + { + SimProfileData retval = new SimProfileData(); + + if (reader.Read()) + { + // Region Main + retval.regionHandle = (ulong)reader["regionHandle"]; + retval.regionName = (string)reader["regionName"]; + retval.UUID = new LLUUID((string)reader["uuid"]); + + // Secrets + retval.regionRecvKey = (string)reader["regionRecvKey"]; + retval.regionSecret = (string)reader["regionSecret"]; + retval.regionSendKey = (string)reader["regionSendKey"]; + + // Region Server + retval.regionDataURI = (string)reader["regionDataURI"]; + retval.regionOnline = false; // Needs to be pinged before this can be set. + retval.serverIP = (string)reader["serverIP"]; + retval.serverPort = (uint)reader["serverPort"]; + retval.serverURI = (string)reader["serverURI"]; + + // Location + retval.regionLocX = (uint)((int)reader["locX"]); + retval.regionLocY = (uint)((int)reader["locY"]); + retval.regionLocZ = (uint)((int)reader["locZ"]); + + // Neighbours - 0 = No Override + retval.regionEastOverrideHandle = (ulong)reader["eastOverrideHandle"]; + retval.regionWestOverrideHandle = (ulong)reader["westOverrideHandle"]; + retval.regionSouthOverrideHandle = (ulong)reader["southOverrideHandle"]; + retval.regionNorthOverrideHandle = (ulong)reader["northOverrideHandle"]; + + // Assets + retval.regionAssetURI = (string)reader["regionAssetURI"]; + retval.regionAssetRecvKey = (string)reader["regionAssetRecvKey"]; + retval.regionAssetSendKey = (string)reader["regionAssetSendKey"]; + + // Userserver + retval.regionUserURI = (string)reader["regionUserURI"]; + retval.regionUserRecvKey = (string)reader["regionUserRecvKey"]; + retval.regionUserSendKey = (string)reader["regionUserSendKey"]; + } + else + { + throw new Exception("No rows to return"); + } + return retval; + } + + /// + /// Inserts a new region into the database + /// + /// The region to insert + /// Success? + public bool insertRow(SimProfileData profile) + { + string sql = "REPLACE INTO regions VALUES (regionHandle, regionName, uuid, regionRecvKey, regionSecret, regionSendKey, regionDataURI, "; + sql += "serverIP, serverPort, serverURI, locX, locY, locZ, eastOverrideHandle, westOverrideHandle, southOverrideHandle, northOverrideHandle, regionAssetURI, regionAssetRecvKey, "; + sql += "regionAssetSendKey, regionUserURI, regionUserRecvKey, regionUserSendKey) VALUES "; + + sql += "(@regionHandle, @regionName, @uuid, @regionRecvKey, @regionSecret, @regionSendKey, @regionDataURI, "; + sql += "@serverIP, @serverPort, @serverURI, @locX, @locY, @locZ, @eastOverrideHandle, @westOverrideHandle, @southOverrideHandle, @northOverrideHandle, @regionAssetURI, @regionAssetRecvKey, "; + sql += "@regionAssetSendKey, @regionUserURI, @regionUserRecvKey, @regionUserSendKey);"; + + Dictionary parameters = new Dictionary(); + + parameters["regionHandle"] = profile.regionHandle.ToString(); + parameters["regionName"] = profile.regionName; + parameters["uuid"] = profile.UUID.ToString(); + parameters["regionRecvKey"] = profile.regionRecvKey; + parameters["regionSendKey"] = profile.regionSendKey; + parameters["regionDataURI"] = profile.regionDataURI; + parameters["serverIP"] = profile.serverIP; + parameters["serverPort"] = profile.serverPort.ToString(); + parameters["serverURI"] = profile.serverURI; + parameters["locX"] = profile.regionLocX.ToString(); + parameters["locY"] = profile.regionLocY.ToString(); + parameters["locZ"] = profile.regionLocZ.ToString(); + parameters["eastOverrideHandle"] = profile.regionEastOverrideHandle.ToString(); + parameters["westOverrideHandle"] = profile.regionWestOverrideHandle.ToString(); + parameters["northOverrideHandle"] = profile.regionNorthOverrideHandle.ToString(); + parameters["southOverrideHandle"] = profile.regionSouthOverrideHandle.ToString(); + parameters["regionAssetURI"] = profile.regionAssetURI; + parameters["regionAssetRecvKey"] = profile.regionAssetRecvKey; + parameters["regionAssetSendKey"] = profile.regionAssetSendKey; + parameters["regionUserURI"] = profile.regionUserURI; + parameters["regionUserRecvKey"] = profile.regionUserRecvKey; + parameters["regionUserSendKey"] = profile.regionUserSendKey; + + bool returnval = false; + + try + { + IDbCommand result = Query(sql, parameters); + + if (result.ExecuteNonQuery() == 1) + returnval = true; + + result.Dispose(); + } + catch (Exception) + { + return false; + } + + return returnval; + } + } +} diff --git a/OpenSim/Framework/Data/GridData.cs b/OpenSim/Framework/Data/GridData.cs new file mode 100644 index 0000000000..5a17d2044b --- /dev/null +++ b/OpenSim/Framework/Data/GridData.cs @@ -0,0 +1,111 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; + +namespace OpenSim.Framework.Data +{ + public enum DataResponse + { + RESPONSE_OK, + RESPONSE_AUTHREQUIRED, + RESPONSE_INVALIDCREDENTIALS, + RESPONSE_ERROR + } + + /// + /// A standard grid interface + /// + public interface IGridData + { + /// + /// Returns a sim profile from a regionHandle + /// + /// A 64bit Region Handle + /// A simprofile + SimProfileData GetProfileByHandle(ulong regionHandle); + + /// + /// Returns a sim profile from a UUID + /// + /// A 128bit UUID + /// A sim profile + SimProfileData GetProfileByLLUUID(LLUUID UUID); + + /// + /// Returns all profiles within the specified range + /// + /// Minimum sim coordinate (X) + /// Minimum sim coordinate (Y) + /// Maximum sim coordinate (X) + /// Maximum sim coordinate (Y) + /// An array containing all the sim profiles in the specified range + SimProfileData[] GetProfilesInRange(uint Xmin, uint Ymin, uint Xmax, uint Ymax); + + /// + /// Authenticates a sim by use of it's recv key. + /// WARNING: Insecure + /// + /// The UUID sent by the sim + /// The regionhandle sent by the sim + /// The recieving key sent by the sim + /// Whether the sim has been authenticated + bool AuthenticateSim(LLUUID UUID, ulong regionHandle, string simrecvkey); + + /// + /// Initialises the interface + /// + void Initialise(); + + /// + /// Closes the interface + /// + void Close(); + + /// + /// The plugin being loaded + /// + /// A string containing the plugin name + string getName(); + + /// + /// The plugins version + /// + /// A string containing the plugin version + string getVersion(); + + /// + /// Adds a new profile to the database + /// + /// The profile to add + /// RESPONSE_OK if successful, error if not. + DataResponse AddProfile(SimProfileData profile); + + ReservationData GetReservationAtPoint(uint x, uint y); + + } +} diff --git a/OpenSim/Framework/Data/ILogData.cs b/OpenSim/Framework/Data/ILogData.cs new file mode 100644 index 0000000000..059fef533f --- /dev/null +++ b/OpenSim/Framework/Data/ILogData.cs @@ -0,0 +1,90 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +namespace OpenSim.Framework.Data +{ + /// + /// The severity of an individual log message + /// + public enum LogSeverity : int + { + /// + /// Critical: systems failure + /// + CRITICAL = 1, + /// + /// Major: warning prior to systems failure + /// + MAJOR = 2, + /// + /// Medium: an individual non-critical task failed + /// + MEDIUM = 3, + /// + /// Low: Informational warning + /// + LOW = 4, + /// + /// Info: Information + /// + INFO = 5, + /// + /// Verbose: Debug Information + /// + VERBOSE = 6 + } + + /// + /// An interface to a LogData storage system + /// + public interface ILogData + { + void saveLog(string serverDaemon, string target, string methodCall, string arguments, int priority,string logMessage); + /// + /// Initialises the interface + /// + void Initialise(); + + /// + /// Closes the interface + /// + void Close(); + + /// + /// The plugin being loaded + /// + /// A string containing the plugin name + string getName(); + + /// + /// The plugins version + /// + /// A string containing the plugin version + string getVersion(); + } + +} diff --git a/OpenSim/Framework/Data/IniConfig.cs b/OpenSim/Framework/Data/IniConfig.cs new file mode 100644 index 0000000000..2b52fd1d65 --- /dev/null +++ b/OpenSim/Framework/Data/IniConfig.cs @@ -0,0 +1,96 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.IO; +using System.Text.RegularExpressions; +/* + Taken from public code listing at by Alex Pinsker + http://alexpinsker.blogspot.com/2005/12/reading-ini-file-from-c_113432097333021549.html + */ + +namespace OpenSim.Framework.Data +{ + /// + /// Parse settings from ini-like files + /// + public class IniFile + { + static IniFile() + { + _iniKeyValuePatternRegex = new Regex( + @"((\s)*(?([^\=^\s^\n]+))[\s^\n]* + # key part (surrounding whitespace stripped) + \= + (\s)*(?([^\n^\s]+(\n){0,1}))) + # value part (surrounding whitespace stripped) + ", + RegexOptions.IgnorePatternWhitespace | + RegexOptions.Compiled | + RegexOptions.CultureInvariant); + } + static private Regex _iniKeyValuePatternRegex; + + public IniFile(string iniFileName) + { + _iniFileName = iniFileName; + } + + public string ParseFileReadValue(string key) + { + using (StreamReader reader = + new StreamReader(_iniFileName)) + { + do + { + string line = reader.ReadLine(); + Match match = + _iniKeyValuePatternRegex.Match(line); + if (match.Success) + { + string currentKey = + match.Groups["Key"].Value as string; + if (currentKey != null && + currentKey.Trim().CompareTo(key) == 0) + { + string value = + match.Groups["Value"].Value as string; + return value; + } + } + + } + while (reader.Peek() != -1); + } + return null; + } + + public string IniFileName + { + get { return _iniFileName; } + } private string _iniFileName; + } +} diff --git a/OpenSim/Framework/Data/InventoryData.cs b/OpenSim/Framework/Data/InventoryData.cs new file mode 100644 index 0000000000..a54afb8416 --- /dev/null +++ b/OpenSim/Framework/Data/InventoryData.cs @@ -0,0 +1,222 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Collections.Generic; +using libsecondlife; + +namespace OpenSim.Framework.Data +{ + /// + /// Inventory Item - contains all the properties associated with an individual inventory piece. + /// + public class InventoryItemBase + { + /// + /// A UUID containing the ID for the inventory item itself + /// + public LLUUID inventoryID; + /// + /// The UUID of the associated asset on the asset server + /// + public LLUUID assetID; + /// + /// This is an enumerated value determining the type of asset (eg Notecard, Sound, Object, etc) + /// + public int assetType; + /// + /// The type of inventory item. (Can be slightly different to the asset type + /// + public int invType; + /// + /// The folder this item is contained in + /// + public LLUUID parentFolderID; + /// + /// The owner of this inventory item + /// + public LLUUID avatarID; + /// + /// The creator of this item + /// + public LLUUID creatorsID; + /// + /// The name of the inventory item (must be less than 64 characters) + /// + public string inventoryName; + /// + /// The description of the inventory item (must be less than 64 characters) + /// + public string inventoryDescription; + /// + /// A mask containing the permissions for the next owner (cannot be enforced) + /// + public uint inventoryNextPermissions; + /// + /// A mask containing permissions for the current owner (cannot be enforced) + /// + public uint inventoryCurrentPermissions; + /// + /// + /// + public uint inventoryBasePermissions; + /// + /// + /// + public uint inventoryEveryOnePermissions; + } + + /// + /// A Class for folders which contain users inventory + /// + public class InventoryFolderBase + { + /// + /// The name of the folder (64 characters or less) + /// + public string name; + /// + /// The agent who's inventory this is contained by + /// + public LLUUID agentID; + /// + /// The folder this folder is contained in + /// + public LLUUID parentID; + /// + /// The UUID for this folder + /// + public LLUUID folderID; + /// + /// Tyep of Items normally stored in this folder + /// + public short type; + /// + /// + /// + public ushort version; + } + + /// + /// An interface for accessing inventory data from a storage server + /// + public interface IInventoryData + { + /// + /// Initialises the interface + /// + void Initialise(); + + /// + /// Closes the interface + /// + void Close(); + + /// + /// The plugin being loaded + /// + /// A string containing the plugin name + string getName(); + + /// + /// The plugins version + /// + /// A string containing the plugin version + string getVersion(); + + /// + /// Returns a list of inventory items contained within the specified folder + /// + /// The UUID of the target folder + /// A List of InventoryItemBase items + List getInventoryInFolder(LLUUID folderID); + + /// + /// Returns a list of the root folders within a users inventory + /// + /// The user whos inventory is to be searched + /// A list of folder objects + List getUserRootFolders(LLUUID user); + + /// + /// Returns the users inventory root folder. + /// + /// The UUID of the user who is having inventory being returned + /// Root inventory folder + InventoryFolderBase getUserRootFolder(LLUUID user); + + /// + /// Returns a list of inventory folders contained in the folder 'parentID' + /// + /// The folder to get subfolders for + /// A list of inventory folders + List getInventoryFolders(LLUUID parentID); + + /// + /// Returns an inventory item by its UUID + /// + /// The UUID of the item to be returned + /// A class containing item information + InventoryItemBase getInventoryItem(LLUUID item); + + /// + /// Returns a specified inventory folder by its UUID + /// + /// The UUID of the folder to be returned + /// A class containing folder information + InventoryFolderBase getInventoryFolder(LLUUID folder); + + /// + /// Creates a new inventory item based on item + /// + /// The item to be created + void addInventoryItem(InventoryItemBase item); + + /// + /// Updates an inventory item with item (updates based on ID) + /// + /// The updated item + void updateInventoryItem(InventoryItemBase item); + + /// + /// + /// + /// + void deleteInventoryItem(InventoryItemBase item); + + /// + /// Adds a new folder specified by folder + /// + /// The inventory folder + void addInventoryFolder(InventoryFolderBase folder); + + /// + /// Updates a folder based on its ID with folder + /// + /// The inventory folder + void updateInventoryFolder(InventoryFolderBase folder); + } +} diff --git a/OpenSim/Framework/Data/Properties/AssemblyInfo.cs b/OpenSim/Framework/Data/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..f9260a1787 --- /dev/null +++ b/OpenSim/Framework/Data/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.Framework.Data")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OpenSim.Framework.Data")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("3a711c34-b0c0-4264-b0fe-f366eabf9d7b")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/Data/ReservationData.cs b/OpenSim/Framework/Data/ReservationData.cs new file mode 100644 index 0000000000..0078df0bce --- /dev/null +++ b/OpenSim/Framework/Data/ReservationData.cs @@ -0,0 +1,47 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; + +namespace OpenSim.Framework.Data +{ + public class ReservationData + { + public LLUUID userUUID = new LLUUID(); + public int reservationMinX = 0; + public int reservationMinY = 0; + public int reservationMaxX = 65536; + public int reservationMaxY = 65536; + + public string reservationName = ""; + public string reservationCompany = ""; + public bool status = true; + + public string gridSendKey = ""; + public string gridRecvKey = ""; + } +} diff --git a/OpenSim/Framework/Data/SimProfileData.cs b/OpenSim/Framework/Data/SimProfileData.cs new file mode 100644 index 0000000000..b920cabe60 --- /dev/null +++ b/OpenSim/Framework/Data/SimProfileData.cs @@ -0,0 +1,192 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; +using Nwc.XmlRpc; + +using System; +using System.Collections; + +namespace OpenSim.Framework.Data +{ + /// + /// A class which contains information known to the grid server about a region + /// + public class SimProfileData + { + /// + /// The name of the region + /// + public string regionName = ""; + + /// + /// A 64-bit number combining map position into a (mostly) unique ID + /// + public ulong regionHandle; + + /// + /// OGS/OpenSim Specific ID for a region + /// + public LLUUID UUID; + + /// + /// Coordinates of the region + /// + public uint regionLocX; + public uint regionLocY; + public uint regionLocZ; // Reserved (round-robin, layers, etc) + + /// + /// Authentication secrets + /// + /// Not very secure, needs improvement. + public string regionSendKey = ""; + public string regionRecvKey = ""; + public string regionSecret = ""; + + /// + /// Whether the region is online + /// + public bool regionOnline; + + /// + /// Information about the server that the region is currently hosted on + /// + public string serverIP = ""; + public uint serverPort; + public string serverURI = ""; + + public uint httpPort; + public uint remotingPort; + public string httpServerURI = ""; + + /// + /// Set of optional overrides. Can be used to create non-eulicidean spaces. + /// + public ulong regionNorthOverrideHandle; + public ulong regionSouthOverrideHandle; + public ulong regionEastOverrideHandle; + public ulong regionWestOverrideHandle; + + /// + /// Optional: URI Location of the region database + /// + /// Used for floating sim pools where the region data is not nessecarily coupled to a specific server + public string regionDataURI = ""; + + /// + /// Region Asset Details + /// + public string regionAssetURI = ""; + public string regionAssetSendKey = ""; + public string regionAssetRecvKey = ""; + + /// + /// Region Userserver Details + /// + public string regionUserURI = ""; + public string regionUserSendKey = ""; + public string regionUserRecvKey = ""; + + /// + /// Region Map Texture Asset + /// + public LLUUID regionMapTextureID = new LLUUID("00000000-0000-0000-9999-000000000006"); + + /// + /// Get Sim profile data from grid server when in grid mode + /// + /// + /// + /// + /// + public SimProfileData RequestSimProfileData(LLUUID region_uuid, string gridserver_url, string gridserver_sendkey, string gridserver_recvkey) + { + Hashtable requestData = new Hashtable(); + requestData["region_uuid"] = region_uuid.UUID.ToString(); + requestData["authkey"] = gridserver_sendkey; + ArrayList SendParams = new ArrayList(); + SendParams.Add(requestData); + XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams); + XmlRpcResponse GridResp = GridReq.Send(gridserver_url, 3000); + + Hashtable responseData = (Hashtable)GridResp.Value; + + if (responseData.ContainsKey("error")) + { + return null; + } + + SimProfileData simData = new SimProfileData(); + simData.regionLocX = Convert.ToUInt32((string)responseData["region_locx"]); + simData.regionLocY = Convert.ToUInt32((string)responseData["region_locy"]); + simData.regionHandle = Helpers.UIntsToLong((simData.regionLocX * 256), (simData.regionLocY * 256)); + simData.serverIP = (string)responseData["sim_ip"]; + simData.serverPort = Convert.ToUInt32((string)responseData["sim_port"]); + simData.httpPort = Convert.ToUInt32((string)responseData["http_port"]); + simData.remotingPort = Convert.ToUInt32((string)responseData["remoting_port"]); + simData.serverURI = "http://" + simData.serverIP + ":" + simData.serverPort.ToString() + "/"; + simData.httpServerURI = "http://" + simData.serverIP + ":" + simData.httpPort.ToString() + "/"; + simData.UUID = new LLUUID((string)responseData["region_UUID"]); + simData.regionName = (string)responseData["region_name"]; + + return simData; + } + public SimProfileData RequestSimProfileData(ulong region_handle, string gridserver_url, string gridserver_sendkey, string gridserver_recvkey) + { + Hashtable requestData = new Hashtable(); + requestData["region_handle"] = region_handle.ToString(); + requestData["authkey"] = gridserver_sendkey; + ArrayList SendParams = new ArrayList(); + SendParams.Add(requestData); + XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams); + XmlRpcResponse GridResp = GridReq.Send(gridserver_url, 3000); + + Hashtable responseData = (Hashtable)GridResp.Value; + + if (responseData.ContainsKey("error")) + { + return null; + } + + SimProfileData simData = new SimProfileData(); + simData.regionLocX = Convert.ToUInt32((string)responseData["region_locx"]); + simData.regionLocY = Convert.ToUInt32((string)responseData["region_locy"]); + simData.regionHandle = Helpers.UIntsToLong((simData.regionLocX * 256), (simData.regionLocY * 256)); + simData.serverIP = (string)responseData["sim_ip"]; + simData.serverPort = Convert.ToUInt32((string)responseData["sim_port"]); + simData.httpPort = Convert.ToUInt32((string)responseData["http_port"]); + simData.remotingPort = Convert.ToUInt32((string)responseData["remoting_port"]); + simData.httpServerURI = "http://" + simData.serverIP + ":" + simData.httpPort.ToString() + "/"; + simData.serverURI = "http://" + simData.serverIP + ":" + simData.serverPort.ToString() + "/"; + simData.UUID = new LLUUID((string)responseData["region_UUID"]); + simData.regionName = (string)responseData["region_name"]; + + return simData; + } + } +} diff --git a/OpenSim/Framework/Data/UserData.cs b/OpenSim/Framework/Data/UserData.cs new file mode 100644 index 0000000000..7055608d05 --- /dev/null +++ b/OpenSim/Framework/Data/UserData.cs @@ -0,0 +1,134 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; + +namespace OpenSim.Framework.Data +{ + /// + /// An interface for connecting to user storage servers. + /// + public interface IUserData + { + /// + /// Returns a user profile from a database via their UUID + /// + /// The accounts UUID + /// The user data profile + UserProfileData getUserByUUID(LLUUID user); + + /// + /// Returns a users profile by searching their username + /// + /// The users username + /// The user data profile + UserProfileData getUserByName(string name); + + /// + /// Returns a users profile by searching their username parts + /// + /// Account firstname + /// Account lastname + /// The user data profile + UserProfileData getUserByName(string fname, string lname); + + /// + /// Returns the current agent for a user searching by it's UUID + /// + /// The users UUID + /// The current agent session + UserAgentData getAgentByUUID(LLUUID user); + + /// + /// Returns the current session agent for a user searching by username + /// + /// The users account name + /// The current agent session + UserAgentData getAgentByName(string name); + + /// + /// Returns the current session agent for a user searching by username parts + /// + /// The users first account name + /// The users account surname + /// The current agent session + UserAgentData getAgentByName(string fname, string lname); + + /// + /// Adds a new User profile to the database + /// + /// UserProfile to add + void addNewUserProfile(UserProfileData user); + + /// + /// Updates an existing user profile + /// + /// UserProfile to update + bool updateUserProfile(UserProfileData user); + + /// + /// Adds a new agent to the database + /// + /// The agent to add + void addNewUserAgent(UserAgentData agent); + + /// + /// Attempts to move currency units between accounts (NOT RELIABLE / TRUSTWORTHY. DONT TRY RUN YOUR OWN CURRENCY EXCHANGE WITH REAL VALUES) + /// + /// The account to transfer from + /// The account to transfer to + /// The amount to transfer + /// Successful? + bool moneyTransferRequest(LLUUID from, LLUUID to, uint amount); + + /// + /// Attempts to move inventory between accounts, if inventory is copyable it will be copied into the target account. + /// + /// User to transfer from + /// User to transfer to + /// Specified inventory item + /// Successful? + bool inventoryTransferRequest(LLUUID from, LLUUID to, LLUUID inventory); + + /// + /// Returns the plugin version + /// + /// Plugin version in MAJOR.MINOR.REVISION.BUILD format + string getVersion(); + + /// + /// Returns the plugin name + /// + /// Plugin name, eg MySQL User Provider + string getName(); + + /// + /// Initialises the plugin (artificial constructor) + /// + void Initialise(); + } +} diff --git a/OpenSim/Framework/Data/UserProfileData.cs b/OpenSim/Framework/Data/UserProfileData.cs new file mode 100644 index 0000000000..3a45bae126 --- /dev/null +++ b/OpenSim/Framework/Data/UserProfileData.cs @@ -0,0 +1,182 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; + +namespace OpenSim.Framework.Data +{ + /// + /// Information about a particular user known to the userserver + /// + public class UserProfileData + { + /// + /// The ID value for this user + /// + public LLUUID UUID; + + /// + /// The first component of a users account name + /// + public string username; + /// + /// The second component of a users account name + /// + public string surname; + + /// + /// A salted hash containing the users password, in the format md5(md5(password) + ":" + salt) + /// + /// This is double MD5'd because the client sends an unsalted MD5 to the loginserver + public string passwordHash; + /// + /// The salt used for the users hash, should be 32 bytes or longer + /// + public string passwordSalt; + + /// + /// The regionhandle of the users preffered home region. If multiple sims occupy the same spot, the grid may decide which region the user logs into + /// + public ulong homeRegion; + /// + /// The coordinates inside the region of the home location + /// + public LLVector3 homeLocation; + /// + /// Where the user will be looking when they rez. + /// + public LLVector3 homeLookAt; + + /// + /// A UNIX Timestamp (seconds since epoch) for the users creation + /// + public int created; + /// + /// A UNIX Timestamp for the users last login date / time + /// + public int lastLogin; + + public LLUUID rootInventoryFolderID; + + /// + /// A URI to the users inventory server, used for foreigners and large grids + /// + public string userInventoryURI; + /// + /// A URI to the users asset server, used for foreigners and large grids. + /// + public string userAssetURI; + + /// + /// A uint mask containing the "I can do" fields of the users profile + /// + public uint profileCanDoMask; + /// + /// A uint mask containing the "I want to do" part of the users profile + /// + public uint profileWantDoMask; // Profile window "I want to" mask + + /// + /// The about text listed in a users profile. + /// + public string profileAboutText; + /// + /// The first life about text listed in a users profile + /// + public string profileFirstText; + + /// + /// The profile image for an avatar stored on the asset server + /// + public LLUUID profileImage; + /// + /// The profile image for the users first life tab + /// + public LLUUID profileFirstImage; + /// + /// The users last registered agent (filled in on the user server) + /// + public UserAgentData currentAgent; + } + + /// + /// Information about a users session + /// + public class UserAgentData + { + /// + /// The UUID of the users avatar (not the agent!) + /// + public LLUUID UUID; + /// + /// The IP address of the user + /// + public string agentIP = String.Empty; + /// + /// The port of the user + /// + public uint agentPort; + /// + /// Is the user online? + /// + public bool agentOnline; + /// + /// The session ID for the user (also the agent ID) + /// + public LLUUID sessionID; + /// + /// The "secure" session ID for the user + /// + /// Not very secure. Dont rely on it for anything more than Linden Lab does. + public LLUUID secureSessionID; + /// + /// The region the user logged into initially + /// + public LLUUID regionID; + /// + /// A unix timestamp from when the user logged in + /// + public int loginTime; + /// + /// When this agent expired and logged out, 0 if still online + /// + public int logoutTime; + /// + /// Current region the user is logged into + /// + public LLUUID currentRegion; + /// + /// Region handle of the current region the user is in + /// + public ulong currentHandle; + /// + /// The position of the user within the region + /// + public LLVector3 currentPos; + } +} diff --git a/OpenSim/Framework/General/AgentCircuitManager.cs b/OpenSim/Framework/General/AgentCircuitManager.cs new file mode 100644 index 0000000000..141cb7ecff --- /dev/null +++ b/OpenSim/Framework/General/AgentCircuitManager.cs @@ -0,0 +1,130 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Collections.Generic; +using libsecondlife; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; + +namespace OpenSim.Framework.Types +{ + public class AgentCircuitManager + { + public Dictionary AgentCircuits = new Dictionary(); + + public AgentCircuitManager() + { + + } + + public virtual AuthenticateResponse AuthenticateSession(LLUUID sessionID, LLUUID agentID, uint circuitcode) + { + AgentCircuitData validcircuit = null; + if (this.AgentCircuits.ContainsKey(circuitcode)) + { + validcircuit = this.AgentCircuits[circuitcode]; + } + AuthenticateResponse user = new AuthenticateResponse(); + if (validcircuit == null) + { + //don't have this circuit code in our list + user.Authorised = false; + return (user); + } + + if ((sessionID == validcircuit.SessionID) && (agentID == validcircuit.AgentID)) + { + user.Authorised = true; + user.LoginInfo = new Login(); + user.LoginInfo.Agent = agentID; + user.LoginInfo.Session = sessionID; + user.LoginInfo.SecureSession = validcircuit.SecureSessionID; + user.LoginInfo.First = validcircuit.firstname; + user.LoginInfo.Last = validcircuit.lastname; + user.LoginInfo.InventoryFolder = validcircuit.InventoryFolder; + user.LoginInfo.BaseFolder = validcircuit.BaseFolder; + } + else + { + // Invalid + user.Authorised = false; + } + + return (user); + } + + public virtual void AddNewCircuit(uint circuitCode, AgentCircuitData agentData) + { + if (this.AgentCircuits.ContainsKey(circuitCode)) + { + this.AgentCircuits[circuitCode] = agentData; + } + else + { + this.AgentCircuits.Add(circuitCode, agentData); + } + } + + public LLVector3 GetPosition(uint circuitCode) + { + LLVector3 vec = new LLVector3(); + if (this.AgentCircuits.ContainsKey(circuitCode)) + { + vec = this.AgentCircuits[circuitCode].startpos; + } + return vec; + } + + public void UpdateAgentData(AgentCircuitData agentData) + { + if (this.AgentCircuits.ContainsKey((uint)agentData.circuitcode)) + { + this.AgentCircuits[(uint)agentData.circuitcode].firstname = agentData.firstname; + this.AgentCircuits[(uint)agentData.circuitcode].lastname = agentData.lastname; + this.AgentCircuits[(uint)agentData.circuitcode].startpos = agentData.startpos; + // Console.WriteLine("update user start pos is " + agentData.startpos.X + " , " + agentData.startpos.Y + " , " + agentData.startpos.Z); + } + } + + public void UpdateAgentChildStatus(uint circuitcode, bool childstatus) + { + if (this.AgentCircuits.ContainsKey(circuitcode)) + { + this.AgentCircuits[circuitcode].child = childstatus; + } + } + + public bool GetAgentChildStatus(uint circuitcode) + { + if (this.AgentCircuits.ContainsKey(circuitcode)) + { + return this.AgentCircuits[circuitcode].child; + } + return false; + } + } +} \ No newline at end of file diff --git a/OpenSim/Framework/General/AgentInventory.cs b/OpenSim/Framework/General/AgentInventory.cs new file mode 100644 index 0000000000..b87b24c28a --- /dev/null +++ b/OpenSim/Framework/General/AgentInventory.cs @@ -0,0 +1,261 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Collections.Generic; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Types; +using OpenSim.Framework.Utilities; + +namespace OpenSim.Framework.Inventory +{ + public class AgentInventory + { + //Holds the local copy of Inventory info for a agent + public Dictionary InventoryFolders; + public Dictionary InventoryItems; + public InventoryFolder InventoryRoot; + public int LastCached; //maybe used by opensim app, time this was last stored/compared to user server + public LLUUID AgentID; + public AvatarWearable[] Wearables; + + public AgentInventory() + { + InventoryFolders = new Dictionary(); + InventoryItems = new Dictionary(); + this.Initialise(); + } + + public virtual void Initialise() + { + Wearables = new AvatarWearable[13]; + for (int i = 0; i < 13; i++) + { + Wearables[i] = new AvatarWearable(); + } + } + + public bool CreateNewFolder(LLUUID folderID, ushort type) + { + InventoryFolder Folder = new InventoryFolder(); + Folder.FolderID = folderID; + Folder.OwnerID = this.AgentID; + Folder.DefaultType = type; + this.InventoryFolders.Add(Folder.FolderID, Folder); + return (true); + } + + public void CreateRootFolder(LLUUID newAgentID, bool createTextures) + { + this.AgentID = newAgentID; + InventoryRoot = new InventoryFolder(); + InventoryRoot.FolderID = LLUUID.Random(); + InventoryRoot.ParentID = new LLUUID(); + InventoryRoot.Version = 1; + InventoryRoot.DefaultType = 8; + InventoryRoot.OwnerID = this.AgentID; + InventoryRoot.FolderName = "My Inventory"; + InventoryFolders.Add(InventoryRoot.FolderID, InventoryRoot); + InventoryRoot.OwnerID = this.AgentID; + if (createTextures) + { + this.CreateNewFolder(LLUUID.Random(), 0, "Textures", InventoryRoot.FolderID); + } + } + + public bool CreateNewFolder(LLUUID folderID, ushort type, string folderName) + { + InventoryFolder Folder = new InventoryFolder(); + Folder.FolderID = folderID; + Folder.OwnerID = this.AgentID; + Folder.DefaultType = type; + Folder.FolderName = folderName; + this.InventoryFolders.Add(Folder.FolderID, Folder); + return (true); + } + + public bool CreateNewFolder(LLUUID folderID, ushort type, string folderName, LLUUID parentID) + { + if (!this.InventoryFolders.ContainsKey(folderID)) + { + System.Console.WriteLine("creating new folder called " + folderName + " in agents inventory"); + InventoryFolder Folder = new InventoryFolder(); + Folder.FolderID = folderID; + Folder.OwnerID = this.AgentID; + Folder.DefaultType = type; + Folder.FolderName = folderName; + Folder.ParentID = parentID; + this.InventoryFolders.Add(Folder.FolderID, Folder); + } + return (true); + } + + public bool HasFolder(LLUUID folderID) + { + if (this.InventoryFolders.ContainsKey(folderID)) + { + return true; + } + return false; + } + + public LLUUID GetFolderID(string folderName) + { + foreach (InventoryFolder inv in this.InventoryFolders.Values) + { + if (inv.FolderName == folderName) + { + return inv.FolderID; + } + } + return LLUUID.Zero; + } + + public bool UpdateItemAsset(LLUUID itemID, AssetBase asset) + { + if(this.InventoryItems.ContainsKey(itemID)) + { + InventoryItem Item = this.InventoryItems[itemID]; + Item.AssetID = asset.FullID; + System.Console.WriteLine("updated inventory item " + itemID.ToStringHyphenated() + " so it now is set to asset " + asset.FullID.ToStringHyphenated()); + //TODO need to update the rest of the info + } + return true; + } + + public bool UpdateItemDetails(LLUUID itemID, UpdateInventoryItemPacket.InventoryDataBlock packet) + { + System.Console.WriteLine("updating inventory item details"); + if (this.InventoryItems.ContainsKey(itemID)) + { + System.Console.WriteLine("changing name to "+ Util.FieldToString(packet.Name)); + InventoryItem Item = this.InventoryItems[itemID]; + Item.Name = Util.FieldToString(packet.Name); + System.Console.WriteLine("updated inventory item " + itemID.ToStringHyphenated()); + //TODO need to update the rest of the info + } + return true; + } + + public LLUUID AddToInventory(LLUUID folderID, AssetBase asset) + { + if (this.InventoryFolders.ContainsKey(folderID)) + { + LLUUID NewItemID = LLUUID.Random(); + + InventoryItem Item = new InventoryItem(); + Item.FolderID = folderID; + Item.OwnerID = AgentID; + Item.AssetID = asset.FullID; + Item.ItemID = NewItemID; + Item.Type = asset.Type; + Item.Name = asset.Name; + Item.Description = asset.Description; + Item.InvType = asset.InvType; + this.InventoryItems.Add(Item.ItemID, Item); + InventoryFolder Folder = InventoryFolders[Item.FolderID]; + Folder.Items.Add(Item); + return (Item.ItemID); + } + else + { + return (null); + } + } + + public bool DeleteFromInventory(LLUUID itemID) + { + bool res = false; + if (this.InventoryItems.ContainsKey(itemID)) + { + InventoryItem item = this.InventoryItems[itemID]; + this.InventoryItems.Remove(itemID); + foreach (InventoryFolder fold in InventoryFolders.Values) + { + if (fold.Items.Contains(item)) + { + fold.Items.Remove(item); + break; + } + } + res = true; + + } + return res; + } + } + + public class InventoryFolder + { + public List Items; + //public List Subfolders; + public LLUUID FolderID; + public LLUUID OwnerID; + public LLUUID ParentID = LLUUID.Zero; + public string FolderName; + public ushort DefaultType; + public ushort Version; + + public InventoryFolder() + { + Items = new List(); + //Subfolders = new List(); + } + + } + + public class InventoryItem + { + public LLUUID FolderID; + public LLUUID OwnerID; + public LLUUID ItemID; + public LLUUID AssetID; + public LLUUID CreatorID; + public sbyte InvType; + public sbyte Type; + public string Name =""; + public string Description; + + public InventoryItem() + { + this.CreatorID = LLUUID.Zero; + } + + public string ExportString() + { + string typ = "notecard"; + string result = ""; + result += "\tinv_object\t0\n\t{\n"; + result += "\t\tobj_id\t%s\n"; + result += "\t\tparent_id\t"+ ItemID.ToString() +"\n"; + result += "\t\ttype\t"+ typ +"\n"; + result += "\t\tname\t" + Name+"|\n"; + result += "\t}\n"; + return result; + } + } +} diff --git a/OpenSim/Framework/General/BlockingQueue.cs b/OpenSim/Framework/General/BlockingQueue.cs new file mode 100644 index 0000000000..0cc8124d4c --- /dev/null +++ b/OpenSim/Framework/General/BlockingQueue.cs @@ -0,0 +1,58 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Collections.Generic; +using System.Threading; + +namespace OpenSim.Framework.Utilities +{ + public class BlockingQueue + { + private Queue _queue = new Queue(); + private object _queueSync = new object(); + + public void Enqueue(T value) + { + lock (_queueSync) + { + _queue.Enqueue(value); + Monitor.Pulse(_queueSync); + } + } + + public T Dequeue() + { + lock (_queueSync) + { + if (_queue.Count < 1) + Monitor.Wait(_queueSync); + + return _queue.Dequeue(); + } + } + } +} diff --git a/OpenSim/Framework/General/ClientManager.cs b/OpenSim/Framework/General/ClientManager.cs new file mode 100644 index 0000000000..b560ca80c5 --- /dev/null +++ b/OpenSim/Framework/General/ClientManager.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Text; +using OpenSim.Framework.Interfaces; + +namespace OpenSim.Framework +{ + public delegate void ForEachClientDelegate( IClientAPI client ); + public class ClientManager + { + private Dictionary m_clients; + + public void ForEachClient(ForEachClientDelegate whatToDo) + { + foreach (IClientAPI client in m_clients.Values) + { + whatToDo(client); + } + } + + public ClientManager() + { + m_clients = new Dictionary(); + } + + public void Remove(uint id) + { + m_clients.Remove(id); + } + + public void Add(uint id, IClientAPI client ) + { + m_clients.Add( id, client ); + } + } +} diff --git a/OpenSim/Framework/General/Configuration/ConfigurationMember.cs b/OpenSim/Framework/General/Configuration/ConfigurationMember.cs new file mode 100644 index 0000000000..bb3192f058 --- /dev/null +++ b/OpenSim/Framework/General/Configuration/ConfigurationMember.cs @@ -0,0 +1,387 @@ +using System; +using System.Reflection; +using System.Collections; +using System.Collections.Generic; +using System.Text; +using System.Net; + +using libsecondlife; + +using OpenSim.Framework.Console; +using OpenSim.Framework.Configuration.Interfaces; + +namespace OpenSim.Framework.Configuration +{ + public class ConfigurationMember + { + public delegate bool ConfigurationOptionResult(string configuration_key, object configuration_result); + public delegate void ConfigurationOptionsLoad(); + + private List configurationOptions = new List(); + private string configurationFilename = ""; + private string configurationDescription = ""; + + private ConfigurationOptionsLoad loadFunction; + private ConfigurationOptionResult resultFunction; + + private IGenericConfig configurationPlugin = null; + /// + /// This is the default configuration DLL loaded + /// + private string configurationPluginFilename = "OpenSim.Framework.Configuration.XML.dll"; + public ConfigurationMember(string configuration_filename, string configuration_description, ConfigurationOptionsLoad load_function, ConfigurationOptionResult result_function) + { + this.configurationFilename = configuration_filename; + this.configurationDescription = configuration_description; + this.loadFunction = load_function; + this.resultFunction = result_function; + } + + public void setConfigurationFilename(string filename) + { + configurationFilename = filename; + } + public void setConfigurationDescription(string desc) + { + configurationDescription = desc; + } + + public void setConfigurationResultFunction(ConfigurationOptionResult result) + { + resultFunction = result; + } + + public void forceConfigurationPluginLibrary(string dll_filename) + { + configurationPluginFilename = dll_filename; + } + public void addConfigurationOption(string configuration_key, ConfigurationOption.ConfigurationTypes configuration_type, string configuration_question, string configuration_default, bool use_default_no_prompt) + { + ConfigurationOption configOption = new ConfigurationOption(); + configOption.configurationKey = configuration_key; + configOption.configurationQuestion = configuration_question; + configOption.configurationDefault = configuration_default; + configOption.configurationType = configuration_type; + configOption.configurationUseDefaultNoPrompt = use_default_no_prompt; + + if ((configuration_key != "" && configuration_question != "") || (configuration_key != "" && use_default_no_prompt)) + { + if (!configurationOptions.Contains(configOption)) + { + configurationOptions.Add(configOption); + } + } + else + { + MainLog.Instance.Notice("Required fields for adding a configuration option is invalid. Will not add this option (" + configuration_key + ")"); + } + } + + public void performConfigurationRetrieve() + { + configurationPlugin = this.LoadConfigDll(configurationPluginFilename); + configurationOptions.Clear(); + if(loadFunction == null) + { + MainLog.Instance.Error("Load Function for '" + this.configurationDescription + "' is null. Refusing to run configuration."); + return; + } + + if(resultFunction == null) + { + MainLog.Instance.Error("Result Function for '" + this.configurationDescription + "' is null. Refusing to run configuration."); + return; + } + + MainLog.Instance.Verbose("Calling Configuration Load Function..."); + this.loadFunction(); + + if(configurationOptions.Count <= 0) + { + MainLog.Instance.Error("No configuration options were specified for '" + this.configurationOptions + "'. Refusing to continue configuration."); + return; + } + + bool useFile = true; + if (configurationPlugin == null) + { + MainLog.Instance.Error("Configuration Plugin NOT LOADED!"); + return; + } + + if (configurationFilename.Trim() != "") + { + configurationPlugin.SetFileName(configurationFilename); + configurationPlugin.LoadData(); + useFile = true; + } + + else + { + MainLog.Instance.Notice("XML Configuration Filename is not valid; will not save to the file."); + useFile = false; + } + + foreach (ConfigurationOption configOption in configurationOptions) + { + bool convertSuccess = false; + object return_result = null; + string errorMessage = ""; + bool ignoreNextFromConfig = false; + while (convertSuccess == false) + { + + string console_result = ""; + string attribute = null; + if (useFile) + { + if (!ignoreNextFromConfig) + { + attribute = configurationPlugin.GetAttribute(configOption.configurationKey); + } + else + { + ignoreNextFromConfig = false; + } + } + + if (attribute == null) + { + if (configOption.configurationUseDefaultNoPrompt) + { + console_result = configOption.configurationDefault; + } + else + { + + if (configurationDescription.Trim() != "") + { + console_result = MainLog.Instance.CmdPrompt(configurationDescription + ": " + configOption.configurationQuestion, configOption.configurationDefault); + } + else + { + console_result = MainLog.Instance.CmdPrompt(configOption.configurationQuestion, configOption.configurationDefault); + } + } + } + else + { + console_result = attribute; + } + + switch (configOption.configurationType) + { + case ConfigurationOption.ConfigurationTypes.TYPE_STRING: + return_result = console_result; + convertSuccess = true; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY: + if (console_result.Length > 0) + { + return_result = console_result; + convertSuccess = true; + } + errorMessage = "a string that is not empty"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN: + bool boolResult; + if (Boolean.TryParse(console_result, out boolResult)) + { + convertSuccess = true; + return_result = boolResult; + } + errorMessage = "'true' or 'false' (Boolean)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_BYTE: + byte byteResult; + if (Byte.TryParse(console_result, out byteResult)) + { + convertSuccess = true; + return_result = byteResult; + } + errorMessage = "a byte (Byte)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_CHARACTER: + char charResult; + if (Char.TryParse(console_result, out charResult)) + { + convertSuccess = true; + return_result = charResult; + } + errorMessage = "a character (Char)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_INT16: + short shortResult; + if (Int16.TryParse(console_result, out shortResult)) + { + convertSuccess = true; + return_result = shortResult; + } + errorMessage = "a signed 32 bit integer (short)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_INT32: + int intResult; + if (Int32.TryParse(console_result, out intResult)) + { + convertSuccess = true; + return_result = intResult; + + } + errorMessage = "a signed 32 bit integer (int)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_INT64: + long longResult; + if (Int64.TryParse(console_result, out longResult)) + { + convertSuccess = true; + return_result = longResult; + } + errorMessage = "a signed 32 bit integer (long)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS: + IPAddress ipAddressResult; + if (IPAddress.TryParse(console_result, out ipAddressResult)) + { + convertSuccess = true; + return_result = ipAddressResult; + } + errorMessage = "an IP Address (IPAddress)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_LLUUID: + LLUUID uuidResult; + if (LLUUID.TryParse(console_result, out uuidResult)) + { + convertSuccess = true; + return_result = uuidResult; + } + errorMessage = "a UUID (LLUUID)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_LLVECTOR3: + LLVector3 vectorResult; + if (LLVector3.TryParse(console_result, out vectorResult)) + { + convertSuccess = true; + return_result = vectorResult; + } + errorMessage = "a vector (LLVector3)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_UINT16: + ushort ushortResult; + if (UInt16.TryParse(console_result, out ushortResult)) + { + convertSuccess = true; + return_result = ushortResult; + } + errorMessage = "an unsigned 16 bit integer (ushort)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_UINT32: + uint uintResult; + if (UInt32.TryParse(console_result, out uintResult)) + { + convertSuccess = true; + return_result = uintResult; + + } + errorMessage = "an unsigned 32 bit integer (uint)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_UINT64: + ulong ulongResult; + if (UInt64.TryParse(console_result, out ulongResult)) + { + convertSuccess = true; + return_result = ulongResult; + } + errorMessage = "an unsigned 64 bit integer (ulong)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_FLOAT: + float floatResult; + if (float.TryParse(console_result, out floatResult)) + { + convertSuccess = true; + return_result = floatResult; + } + errorMessage = "a single-precision floating point number (float)"; + break; + case ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE: + double doubleResult; + if (Double.TryParse(console_result, out doubleResult)) + { + convertSuccess = true; + return_result = doubleResult; + } + errorMessage = "an double-precision floating point number (double)"; + break; + } + + if (convertSuccess) + { + if (useFile) + { + configurationPlugin.SetAttribute(configOption.configurationKey, console_result); + } + + + if (!this.resultFunction(configOption.configurationKey, return_result)) + { + Console.MainLog.Instance.Notice("The handler for the last configuration option denied that input, please try again."); + convertSuccess = false; + ignoreNextFromConfig = true; + } + } + else + { + if (configOption.configurationUseDefaultNoPrompt) + { + MainLog.Instance.Error("Default given for '" + configOption.configurationKey + "' is not valid; the configuration result must be " + errorMessage + ". Will skip this option..."); + convertSuccess = true; + } + else + { + MainLog.Instance.Warn("configuration","Incorrect result given, the configuration option must be " + errorMessage + ". Prompting for same option..."); + ignoreNextFromConfig = true; + } + } + } + } + + if(useFile) + { + configurationPlugin.Commit(); + configurationPlugin.Close(); + } + } + + private IGenericConfig LoadConfigDll(string dllName) + { + Assembly pluginAssembly = Assembly.LoadFrom(dllName); + IGenericConfig plug = null; + + foreach (Type pluginType in pluginAssembly.GetTypes()) + { + if (pluginType.IsPublic) + { + if (!pluginType.IsAbstract) + { + Type typeInterface = pluginType.GetInterface("IGenericConfig", true); + + if (typeInterface != null) + { + plug = (IGenericConfig)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); + } + } + } + } + + pluginAssembly = null; + return plug; + } + + public void forceSetConfigurationOption(string configuration_key, string configuration_value) + { + this.configurationPlugin.LoadData(); + this.configurationPlugin.SetAttribute(configuration_key, configuration_value); + this.configurationPlugin.Commit(); + this.configurationPlugin.Close(); + } + } +} diff --git a/OpenSim/Framework/General/Configuration/ConfigurationOption.cs b/OpenSim/Framework/General/Configuration/ConfigurationOption.cs new file mode 100644 index 0000000000..38f60a0fe4 --- /dev/null +++ b/OpenSim/Framework/General/Configuration/ConfigurationOption.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Framework.Configuration +{ + public class ConfigurationOption + { + public enum ConfigurationTypes + { + TYPE_STRING, + TYPE_STRING_NOT_EMPTY, + TYPE_UINT16, + TYPE_UINT32, + TYPE_UINT64, + TYPE_INT16, + TYPE_INT32, + TYPE_INT64, + TYPE_IP_ADDRESS, + TYPE_CHARACTER, + TYPE_BOOLEAN, + TYPE_BYTE, + TYPE_LLUUID, + TYPE_LLVECTOR3, + TYPE_FLOAT, + TYPE_DOUBLE + }; + + public string configurationKey = ""; + public string configurationQuestion = ""; + public string configurationDefault = ""; + + public ConfigurationTypes configurationType = ConfigurationTypes.TYPE_STRING; + public bool configurationUseDefaultNoPrompt = false; + } +} diff --git a/OpenSim/Framework/General/Configuration/GridConfig.cs b/OpenSim/Framework/General/Configuration/GridConfig.cs new file mode 100644 index 0000000000..3d07d9b2a1 --- /dev/null +++ b/OpenSim/Framework/General/Configuration/GridConfig.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Framework.Configuration +{ + public class GridConfig + { + public string GridOwner = ""; + public string DefaultAssetServer = ""; + public string AssetSendKey = ""; + public string AssetRecvKey = ""; + + public string DefaultUserServer = ""; + public string UserSendKey = ""; + public string UserRecvKey = ""; + + public string SimSendKey = ""; + public string SimRecvKey = ""; + + public string DatabaseProvider = ""; + + private ConfigurationMember configMember; + public GridConfig(string description, string filename) + { + configMember = new ConfigurationMember(filename, description, this.loadConfigurationOptions, this.handleIncomingConfiguration); + configMember.performConfigurationRetrieve(); + } + + public void loadConfigurationOptions() + { + configMember.addConfigurationOption("grid_owner", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "OGS Grid Owner", "OGS development team", false); + configMember.addConfigurationOption("default_asset_server", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Default Asset Server URI", "http://127.0.0.1:8003/", false); + configMember.addConfigurationOption("asset_send_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, "Key to send to asset server", "null", false); + configMember.addConfigurationOption("asset_recv_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, "Key to expect from asset server", "null", false); + + configMember.addConfigurationOption("default_user_server", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Default User Server URI", "http://127.0.0.1:8002/", false); + configMember.addConfigurationOption("user_send_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, "Key to send to user server", "null", false); + configMember.addConfigurationOption("user_recv_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, "Key to expect from user server", "null", false); + + configMember.addConfigurationOption("sim_send_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, "Key to send to a simulator", "null", false); + configMember.addConfigurationOption("sim_recv_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, "Key to expect from a simulator", "null", false); + configMember.addConfigurationOption("database_provider", ConfigurationOption.ConfigurationTypes.TYPE_STRING, "DLL for database provider", "OpenSim.Framework.Data.MySQL.dll", false); + } + + public bool handleIncomingConfiguration(string configuration_key, object configuration_result) + { + switch (configuration_key) + { + case "grid_owner": + this.GridOwner = (string)configuration_result; + break; + case "default_asset_server": + this.DefaultAssetServer = (string)configuration_result; + break; + case "asset_send_key": + this.AssetSendKey = (string)configuration_result; + break; + case "asset_recv_key": + this.AssetRecvKey = (string)configuration_result; + break; + case "default_user_server": + this.DefaultUserServer = (string)configuration_result; + break; + case "user_send_key": + this.UserSendKey = (string)configuration_result; + break; + case "user_recv_key": + this.UserRecvKey = (string)configuration_result; + break; + case "sim_send_key": + this.SimSendKey = (string)configuration_result; + break; + case "sim_recv_key": + this.SimRecvKey = (string)configuration_result; + break; + case "database_provider": + this.DatabaseProvider = (string)configuration_result; + break; + } + + return true; + } + } +} diff --git a/OpenSim/Framework/General/Configuration/Interfaces/IGenericConfig.cs b/OpenSim/Framework/General/Configuration/Interfaces/IGenericConfig.cs new file mode 100644 index 0000000000..ceccd04fab --- /dev/null +++ b/OpenSim/Framework/General/Configuration/Interfaces/IGenericConfig.cs @@ -0,0 +1,40 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +namespace OpenSim.Framework.Configuration.Interfaces +{ + public interface IGenericConfig + { + void SetFileName(string fileName); + void LoadData(); + void LoadDataFromString(string data); + string GetAttribute(string attributeName); + bool SetAttribute(string attributeName, string attributeValue); + void Commit(); + void Close(); + } +} diff --git a/OpenSim/Framework/General/Configuration/UserConfig.cs b/OpenSim/Framework/General/Configuration/UserConfig.cs new file mode 100644 index 0000000000..218349188b --- /dev/null +++ b/OpenSim/Framework/General/Configuration/UserConfig.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Framework.Configuration +{ + /// + /// UserConfig -- For User Server Configuration + /// + public class UserConfig + { + public string DefaultStartupMsg = ""; + public string GridServerURL = ""; + public string GridSendKey = ""; + public string GridRecvKey = ""; + + public string DatabaseProvider = ""; + + private ConfigurationMember configMember; + + public UserConfig(string description, string filename) + { + configMember = new ConfigurationMember(filename, description, this.loadConfigurationOptions, this.handleIncomingConfiguration); + configMember.performConfigurationRetrieve(); + } + + public void loadConfigurationOptions() + { + configMember.addConfigurationOption("default_startup_message", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Default Startup Message", "Welcome to OGS",false); + + configMember.addConfigurationOption("default_grid_server", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Default Grid Server URI", "http://127.0.0.1:8001/", false); + configMember.addConfigurationOption("grid_send_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, "Key to send to grid server", "null", false); + configMember.addConfigurationOption("grid_recv_key", ConfigurationOption.ConfigurationTypes.TYPE_STRING, "Key to expect from grid server", "null", false); + configMember.addConfigurationOption("database_provider", ConfigurationOption.ConfigurationTypes.TYPE_STRING, "DLL for database provider", "OpenSim.Framework.Data.MySQL.dll", false); + + } + + public bool handleIncomingConfiguration(string configuration_key, object configuration_result) + { + switch (configuration_key) + { + case "default_startup_message": + this.DefaultStartupMsg = (string)configuration_result; + break; + case "default_grid_server": + this.GridServerURL = (string)configuration_result; + break; + case "grid_send_key": + this.GridSendKey = (string)configuration_result; + break; + case "grid_recv_key": + this.GridRecvKey = (string)configuration_result; + break; + case "database_provider": + this.DatabaseProvider = (string)configuration_result; + break; + } + + return true; + } + } +} diff --git a/OpenSim/Framework/General/IRegionCommsListener.cs b/OpenSim/Framework/General/IRegionCommsListener.cs new file mode 100644 index 0000000000..3d351c8643 --- /dev/null +++ b/OpenSim/Framework/General/IRegionCommsListener.cs @@ -0,0 +1,48 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Collections.Generic; +using libsecondlife; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; + +namespace OpenSim.Framework +{ + public delegate void ExpectUserDelegate(ulong regionHandle, AgentCircuitData agent); + public delegate void UpdateNeighbours(List neighbours); + public delegate void AgentCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying); + public delegate void AcknowledgeAgentCross(ulong regionHandle, LLUUID agentID); + + public interface IRegionCommsListener + { + event ExpectUserDelegate OnExpectUser; + event GenericCall2 OnExpectChildAgent; + event AgentCrossing OnAvatarCrossingIntoRegion; + event AcknowledgeAgentCross OnAcknowledgeAgentCrossed; + event UpdateNeighbours OnNeighboursUpdate; + } +} diff --git a/OpenSim/Framework/General/Interfaces/AuthenticateResponse.cs b/OpenSim/Framework/General/Interfaces/AuthenticateResponse.cs new file mode 100644 index 0000000000..508485b541 --- /dev/null +++ b/OpenSim/Framework/General/Interfaces/AuthenticateResponse.cs @@ -0,0 +1,43 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 OpenSim.Framework.Types; + +namespace OpenSim.Framework.Interfaces +{ + public class AuthenticateResponse + { + public bool Authorised; + public Login LoginInfo; + + public AuthenticateResponse() + { + + } + + } +} diff --git a/OpenSim/Framework/General/Interfaces/IAssetServer.cs b/OpenSim/Framework/General/Interfaces/IAssetServer.cs new file mode 100644 index 0000000000..ab60dd7291 --- /dev/null +++ b/OpenSim/Framework/General/Interfaces/IAssetServer.cs @@ -0,0 +1,64 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; +using OpenSim.Framework.Types; + +namespace OpenSim.Framework.Interfaces +{ + /// + /// Description of IAssetServer. + /// + + public interface IAssetServer + { + void SetReceiver(IAssetReceiver receiver); + void RequestAsset(LLUUID assetID, bool isTexture); + void UpdateAsset(AssetBase asset); + void UploadNewAsset(AssetBase asset); + void SetServerInfo(string ServerUrl, string ServerKey); + void Close(); + } + + // could change to delegate? + public interface IAssetReceiver + { + void AssetReceived(AssetBase asset, bool IsTexture); + void AssetNotFound(AssetBase asset); + } + + public interface IAssetPlugin + { + IAssetServer GetAssetServer(); + } + + public struct ARequest + { + public LLUUID AssetID; + public bool IsTexture; + } +} diff --git a/OpenSim/Framework/General/Interfaces/IClientAPI.cs b/OpenSim/Framework/General/Interfaces/IClientAPI.cs new file mode 100644 index 0000000000..1a36631547 --- /dev/null +++ b/OpenSim/Framework/General/Interfaces/IClientAPI.cs @@ -0,0 +1,233 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Collections.Generic; +using System.Net; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Types; +using OpenSim.Framework.Data; + +namespace OpenSim.Framework.Interfaces +{ + public delegate void ChatFromViewer(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID); + public delegate void ImprovedInstantMessage(LLUUID fromAgentID, LLUUID toAgentID, uint timestamp, string fromAgentName, string message); // Cut down from full list + public delegate void RezObject(IClientAPI remoteClient, LLUUID itemID, LLVector3 pos); + public delegate void ModifyTerrain(float height, float seconds, byte size, byte action, float north, float west, IClientAPI remoteClient); + public delegate void SetAppearance(byte[] texture, AgentSetAppearancePacket.VisualParamBlock[] visualParam); + public delegate void StartAnim(LLUUID animID, int seq); + public delegate void LinkObjects(uint parent, List children); + public delegate void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY); + public delegate void TeleportLocationRequest(IClientAPI remoteClient, ulong regionHandle, LLVector3 position, LLVector3 lookAt, uint flags); + public delegate void DisconnectUser(); + public delegate void RequestAvatarProperties(IClientAPI remoteClient, LLUUID avatarID); + + public delegate void GenericCall(IClientAPI remoteClient); + public delegate void GenericCall2(); + public delegate void GenericCall3(Packet packet); // really don't want to be passing packets in these events, so this is very temporary. + public delegate void GenericCall4(Packet packet, IClientAPI remoteClient); + public delegate void GenericCall5(IClientAPI remoteClient, bool status); + public delegate void GenericCall6(LLUUID uid); + public delegate void GenericCall7(uint localID, string message); + + public delegate void UpdateShape(uint localID, ObjectShapePacket.ObjectDataBlock shapeBlock); + public delegate void ObjectExtraParams(uint localID, ushort type, bool inUse, byte[] data); + public delegate void ObjectSelect(uint localID, IClientAPI remoteClient); + public delegate void ObjectDeselect(uint localID, IClientAPI remoteClient); + public delegate void UpdatePrimFlags(uint localID, Packet packet, IClientAPI remoteClient); + public delegate void UpdatePrimTexture(uint localID, byte[] texture, IClientAPI remoteClient); + public delegate void UpdateVector(uint localID, LLVector3 pos, IClientAPI remoteClient); + public delegate void UpdatePrimRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient); + public delegate void UpdatePrimSingleRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient); + public delegate void UpdatePrimGroupRotation(uint localID,LLVector3 pos, LLQuaternion rot, IClientAPI remoteClient); + public delegate void ObjectDuplicate(uint localID, LLVector3 offset, uint dupeFlags); + public delegate void StatusChange(bool status); + public delegate void NewAvatar(IClientAPI remoteClient, LLUUID agentID, bool status); + public delegate void UpdateAgent(IClientAPI remoteClient, uint flags, LLQuaternion bodyRotation); + public delegate void MoveObject(LLUUID objectID, LLVector3 offset, LLVector3 grapPos, IClientAPI remoteClient); + + public delegate void ParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, bool snap_selection, IClientAPI remote_client); + public delegate void ParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client); + public delegate void ParcelJoinRequest(int west, int south, int east, int north, IClientAPI remote_client); + public delegate void ParcelPropertiesUpdateRequest(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client); + public delegate void ParcelSelectObjects(int land_local_id, int request_type, IClientAPI remote_client); + public delegate void ParcelObjectOwnerRequest(int local_id, IClientAPI remote_client); + public delegate void EstateOwnerMessageRequest(EstateOwnerMessagePacket packet, IClientAPI remote_client); + + public delegate void UUIDNameRequest(LLUUID id, IClientAPI remote_client); + + public delegate void AddNewPrim(LLUUID ownerID, LLVector3 pos, PrimitiveBaseShape shape); + + public delegate void CreateInventoryFolder(IClientAPI remoteClient, LLUUID folderID, ushort folderType, string folderName, LLUUID parentID); + public delegate void CreateNewInventoryItem(IClientAPI remoteClient, LLUUID transActionID, LLUUID folderID, uint callbackID, string description, string name, sbyte invType, sbyte type, byte wearableType, uint nextOwnerMask); + public delegate void FetchInventoryDescendents(IClientAPI remoteClient, LLUUID folderID, LLUUID ownerID, bool fetchFolders, bool fetchItems, int sortOrder); + public delegate void FetchInventory(IClientAPI remoteClient, LLUUID itemID, LLUUID ownerID); + public delegate void RequestTaskInventory(IClientAPI remoteClient, uint localID); + + public delegate void UDPAssetUploadRequest(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data); + public delegate void XferReceive(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data); + public delegate void RequestXfer(IClientAPI remoteClient, ulong xferID, string fileName); + + public interface IClientAPI + { + event ImprovedInstantMessage OnInstantMessage; + event ChatFromViewer OnChatFromViewer; + event RezObject OnRezObject; + event ModifyTerrain OnModifyTerrain; + event SetAppearance OnSetAppearance; + event StartAnim OnStartAnim; + event LinkObjects OnLinkObjects; + event RequestMapBlocks OnRequestMapBlocks; + event TeleportLocationRequest OnTeleportLocationRequest; + event DisconnectUser OnDisconnectUser; + event RequestAvatarProperties OnRequestAvatarProperties; + + event GenericCall4 OnDeRezObject; + event GenericCall OnRegionHandShakeReply; + event GenericCall OnRequestWearables; + event GenericCall2 OnCompleteMovementToRegion; + event UpdateAgent OnAgentUpdate; + event GenericCall OnRequestAvatarsData; + event AddNewPrim OnAddPrim; + event ObjectDuplicate OnObjectDuplicate; + event UpdateVector OnGrabObject; + event ObjectSelect OnDeGrabObject; + event MoveObject OnGrabUpdate; + + event UpdateShape OnUpdatePrimShape; + event ObjectExtraParams OnUpdateExtraParams; + event ObjectSelect OnObjectSelect; + event ObjectDeselect OnObjectDeselect; + event GenericCall7 OnObjectDescription; + event GenericCall7 OnObjectName; + event UpdatePrimFlags OnUpdatePrimFlags; + event UpdatePrimTexture OnUpdatePrimTexture; + event UpdateVector OnUpdatePrimGroupPosition; + event UpdateVector OnUpdatePrimSinglePosition; + event UpdatePrimRotation OnUpdatePrimGroupRotation; + event UpdatePrimSingleRotation OnUpdatePrimSingleRotation; + event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation; + event UpdateVector OnUpdatePrimScale; + event StatusChange OnChildAgentStatus; + event GenericCall2 OnStopMovement; + event GenericCall6 OnRemoveAvatar; + + event CreateNewInventoryItem OnCreateNewInventoryItem; + event CreateInventoryFolder OnCreateNewInventoryFolder; + event FetchInventoryDescendents OnFetchInventoryDescendents; + event FetchInventory OnFetchInventory; + event RequestTaskInventory OnRequestTaskInventory; + event UDPAssetUploadRequest OnAssetUploadRequest; + event XferReceive OnXferReceive; + event RequestXfer OnRequestXfer; + + event UUIDNameRequest OnNameFromUUIDRequest; + + event ParcelPropertiesRequest OnParcelPropertiesRequest; + event ParcelDivideRequest OnParcelDivideRequest; + event ParcelJoinRequest OnParcelJoinRequest; + event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest; + event ParcelSelectObjects OnParcelSelectObjects; + event ParcelObjectOwnerRequest OnParcelObjectOwnerRequest; + event EstateOwnerMessageRequest OnEstateOwnerMessage; + + LLVector3 StartPos + { + get; + set; + } + + LLUUID AgentId + { + get; + } + + LLUUID SessionId + { + get; + } + + string FirstName + { + get; + } + + string LastName + { + get; + } + + void OutPacket(Packet newPack); + void SendWearables(AvatarWearable[] wearables); + void SendAppearance(LLUUID agentID, byte[] visualParams, byte[] textureEntry); + void SendStartPingCheck(byte seq); + void SendKillObject(ulong regionHandle, uint localID); + void SendAnimation(LLUUID animID, int seq, LLUUID sourceAgentId); + void SendRegionHandshake(RegionInfo regionInfo); + void SendChatMessage(string message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID); + void SendChatMessage(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID); + void SendInstantMessage(string message, LLUUID target, string fromName); + void SendLayerData(float[] map); + void SendLayerData(int px, int py, float[] map); + void MoveAgentIntoRegion(RegionInfo regInfo, LLVector3 pos, LLVector3 look); + void InformClientOfNeighbour(ulong neighbourHandle, IPEndPoint neighbourExternalEndPoint ); + AgentCircuitData RequestClientInfo(); + void CrossRegion(ulong newRegionHandle, LLVector3 pos, LLVector3 lookAt, IPEndPoint newRegionExternalEndPoint, string capsURL ); + void SendMapBlock(List mapBlocks); + void SendLocalTeleport(LLVector3 position, LLVector3 lookAt, uint flags); + void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint, uint locationID, uint flags, string capsURL); + void SendTeleportCancel(); + void SendTeleportLocationStart(); + void SendMoneyBalance(LLUUID transaction, bool success, byte[] description, int balance); + + void SendAvatarData(ulong regionHandle, string firstName, string lastName, LLUUID avatarID, uint avatarLocalID, LLVector3 Pos, byte[] textureEntry); + void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLVector3 velocity); + + void AttachObject(uint localID, LLQuaternion rotation, byte attachPoint); + void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos, uint flags, LLUUID objectID, LLUUID ownerID, string text, uint parentID, byte[] particleSystem, LLQuaternion rotation); + void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLQuaternion rotation); + + void SendInventoryFolderDetails(LLUUID ownerID, LLUUID folderID, List items); + void SendInventoryItemDetails(LLUUID ownerID, InventoryItemBase item); + void SendInventoryItemUpdate(InventoryItemBase Item); + void SendRemoveInventoryItem(LLUUID itemID); + void SendTaskInventory(LLUUID taskID, short serial, byte[] fileName); + void SendXferPacket(ulong xferID, uint packet, byte[] data); + + void SendPreLoadSound(LLUUID objectID, LLUUID ownerID, LLUUID soundID); + void SendPlayAttachedSound(LLUUID soundID, LLUUID objectID, LLUUID ownerID, float gain, byte flags); + + void SendNameReply(LLUUID profileId, string firstname, string lastname); + void SendAlertMessage(string message); + void SendAgentAlertMessage(string message, bool modal); + void SendLoadURL(string objectname, LLUUID objectID, LLUUID ownerID, bool groupOwned, string message, string url); + bool AddMoney( int debit ); + + void SendViewerTime(int phase); + void SendAvatarProperties(LLUUID avatarID, string aboutText, string bornOn, string charterMember, string flAbout, uint flags, LLUUID flImageID, LLUUID imageID, string profileURL, LLUUID partnerID); + } +} diff --git a/OpenSim/Framework/General/Interfaces/IScene.cs b/OpenSim/Framework/General/Interfaces/IScene.cs new file mode 100644 index 0000000000..00424a1266 --- /dev/null +++ b/OpenSim/Framework/General/Interfaces/IScene.cs @@ -0,0 +1,42 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; +using OpenSim.Framework.Types; + +namespace OpenSim.Framework.Interfaces +{ + public interface IScene + { + void AddNewClient(IClientAPI client, bool child); + void RemoveClient(LLUUID agentID); + + RegionInfo RegionInfo { get; } + object SyncRoot { get; } + uint NextLocalId { get; } + } +} diff --git a/OpenSim/Framework/General/NullClientAPI.cs b/OpenSim/Framework/General/NullClientAPI.cs new file mode 100644 index 0000000000..229abb2372 --- /dev/null +++ b/OpenSim/Framework/General/NullClientAPI.cs @@ -0,0 +1,165 @@ +using System.Collections.Generic; +using System.Net; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Framework.Data; +using libsecondlife; +using libsecondlife.Packets; + + +namespace OpenSim.Framework +{ + public class NullClientAPI : IClientAPI + { +#pragma warning disable 67 + public event ImprovedInstantMessage OnInstantMessage; + public event ChatFromViewer OnChatFromViewer; + public event RezObject OnRezObject; + public event ModifyTerrain OnModifyTerrain; + public event SetAppearance OnSetAppearance; + public event StartAnim OnStartAnim; + public event LinkObjects OnLinkObjects; + public event RequestMapBlocks OnRequestMapBlocks; + public event TeleportLocationRequest OnTeleportLocationRequest; + public event DisconnectUser OnDisconnectUser; + public event RequestAvatarProperties OnRequestAvatarProperties; + + public event GenericCall4 OnDeRezObject; + public event GenericCall OnRegionHandShakeReply; + public event GenericCall OnRequestWearables; + public event GenericCall2 OnCompleteMovementToRegion; + public event UpdateAgent OnAgentUpdate; + public event GenericCall OnRequestAvatarsData; + public event AddNewPrim OnAddPrim; + public event ObjectDuplicate OnObjectDuplicate; + public event UpdateVector OnGrabObject; + public event ObjectSelect OnDeGrabObject; + public event MoveObject OnGrabUpdate; + + public event UpdateShape OnUpdatePrimShape; + public event ObjectExtraParams OnUpdateExtraParams; + public event ObjectSelect OnObjectSelect; + public event GenericCall7 OnObjectDescription; + public event GenericCall7 OnObjectName; + public event UpdatePrimFlags OnUpdatePrimFlags; + public event UpdatePrimTexture OnUpdatePrimTexture; + public event UpdateVector OnUpdatePrimGroupPosition; + public event UpdateVector OnUpdatePrimSinglePosition; + public event UpdatePrimRotation OnUpdatePrimGroupRotation; + public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation; + public event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation; + public event UpdateVector OnUpdatePrimScale; + public event StatusChange OnChildAgentStatus; + public event GenericCall2 OnStopMovement; + public event GenericCall6 OnRemoveAvatar; + + public event CreateNewInventoryItem OnCreateNewInventoryItem; + public event CreateInventoryFolder OnCreateNewInventoryFolder; + public event FetchInventoryDescendents OnFetchInventoryDescendents; + public event FetchInventory OnFetchInventory; + public event RequestTaskInventory OnRequestTaskInventory; + public event UDPAssetUploadRequest OnAssetUploadRequest; + public event XferReceive OnXferReceive; + public event RequestXfer OnRequestXfer; + + public event UUIDNameRequest OnNameFromUUIDRequest; + + public event ParcelPropertiesRequest OnParcelPropertiesRequest; + public event ParcelDivideRequest OnParcelDivideRequest; + public event ParcelJoinRequest OnParcelJoinRequest; + public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest; + public event ParcelSelectObjects OnParcelSelectObjects; + public event ParcelObjectOwnerRequest OnParcelObjectOwnerRequest; + public event ObjectDeselect OnObjectDeselect; + + + public event EstateOwnerMessageRequest OnEstateOwnerMessage; +#pragma warning restore 67 + + private LLUUID m_uuid = LLUUID.Random(); + public virtual LLVector3 StartPos + { + get { return new LLVector3(); } + set { } + } + + public virtual LLUUID AgentId + { + get { return m_uuid; } + } + + public LLUUID SessionId + { + get { return LLUUID.Zero; } + } + + public virtual string FirstName + { + get { return ""; } + } + + public virtual string LastName + { + get { return ""; } + } + + public NullClientAPI() + { + } + + public virtual void OutPacket(Packet newPack){} + public virtual void SendWearables(AvatarWearable[] wearables){} + public virtual void SendAppearance(LLUUID agentID, byte[] visualParams, byte[] textureEntry) { } + public virtual void SendStartPingCheck(byte seq){} + public virtual void SendKillObject(ulong regionHandle, uint localID){} + public virtual void SendAnimation(LLUUID animID, int seq, LLUUID sourceAgentId){} + public virtual void SendRegionHandshake(RegionInfo regionInfo){} + public virtual void SendChatMessage(string message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID){} + public virtual void SendChatMessage(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID){} + public virtual void SendInstantMessage(string message, LLUUID target, string fromName){} + public virtual void SendLayerData(float[] map){} + public virtual void SendLayerData(int px, int py, float[] map){} + public virtual void MoveAgentIntoRegion(RegionInfo regInfo, LLVector3 pos, LLVector3 look){} + public virtual void InformClientOfNeighbour(ulong neighbourHandle, IPEndPoint neighbourExternalEndPoint){} + public virtual AgentCircuitData RequestClientInfo() { return new AgentCircuitData(); } + public virtual void CrossRegion(ulong newRegionHandle, LLVector3 pos, LLVector3 lookAt, IPEndPoint newRegionExternalEndPoint, string capsURL){} + public virtual void SendMapBlock(List mapBlocks){} + public virtual void SendLocalTeleport(LLVector3 position, LLVector3 lookAt, uint flags){} + public virtual void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint, uint locationID, uint flags, string capsURL){} + public virtual void SendTeleportCancel(){} + public virtual void SendTeleportLocationStart(){} + public virtual void SendMoneyBalance(LLUUID transaction, bool success, byte[] description, int balance){} + + public virtual void SendAvatarData(ulong regionHandle, string firstName, string lastName, LLUUID avatarID, uint avatarLocalID, LLVector3 Pos, byte[] textureEntry){} + public virtual void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLVector3 velocity){} + + public virtual void AttachObject(uint localID, LLQuaternion rotation, byte attachPoint){} + public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos, uint flags, LLUUID objectID, LLUUID ownerID, string text, uint parentID, byte[] particleSystem, LLQuaternion rotation){} + public virtual void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLQuaternion rotation){} + + public virtual void SendInventoryFolderDetails(LLUUID ownerID, LLUUID folderID, List items){} + public virtual void SendInventoryItemDetails(LLUUID ownerID, InventoryItemBase item){} + public virtual void SendInventoryItemUpdate(InventoryItemBase Item) { } + public virtual void SendRemoveInventoryItem(LLUUID itemID) { } + public virtual void SendTaskInventory(LLUUID taskID, short serial, byte[] fileName) { } + public virtual void SendXferPacket(ulong xferID, uint packet, byte[] data) { } + + public virtual void SendPreLoadSound(LLUUID objectID, LLUUID ownerID, LLUUID soundID) { } + public virtual void SendPlayAttachedSound(LLUUID soundID, LLUUID objectID, LLUUID ownerID, float gain, byte flags) { } + + public virtual void SendNameReply(LLUUID profileId, string firstname, string lastname){} + public void SendAlertMessage(string message) { } + public void SendAgentAlertMessage(string message, bool modal) { } + public void SendLoadURL(string objectname, LLUUID objectID, LLUUID ownerID, bool groupOwned, string message, string url) { } + + + public bool AddMoney(int debit) + { + return false; + } + + public void SendViewerTime(int phase) { } + public void SendAvatarProperties(LLUUID avatarID, string aboutText, string bornOn, string charterMember, string flAbout, uint flags, LLUUID flImageID, LLUUID imageID, string profileURL, LLUUID partnerID) { } + } +} + diff --git a/OpenSim/Framework/General/Properties/AssemblyInfo.cs b/OpenSim/Framework/General/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..004040bf91 --- /dev/null +++ b/OpenSim/Framework/General/Properties/AssemblyInfo.cs @@ -0,0 +1,31 @@ +using System.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.FrameWork")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OpenSim.FrameWork")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("a08e20c7-f191-4137-b1f0-9291408fa521")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/General/RegionCommsListener.cs b/OpenSim/Framework/General/RegionCommsListener.cs new file mode 100644 index 0000000000..7a950bf0bf --- /dev/null +++ b/OpenSim/Framework/General/RegionCommsListener.cs @@ -0,0 +1,114 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; + +using System.Collections.Generic; + +namespace OpenSim.Framework +{ + public class RegionCommsListener :IRegionCommsListener + { + public event ExpectUserDelegate OnExpectUser; + public event GenericCall2 OnExpectChildAgent; + public event AgentCrossing OnAvatarCrossingIntoRegion; + public event UpdateNeighbours OnNeighboursUpdate; + public event AcknowledgeAgentCross OnAcknowledgeAgentCrossed; + + /// + /// + /// + /// + /// + public virtual bool TriggerExpectUser(ulong regionHandle, AgentCircuitData agent) + { + if(OnExpectUser != null) + { + + OnExpectUser(regionHandle, agent); + return true; + } + + return false; + } + + public virtual bool TriggerExpectAvatarCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying) + { + if (OnAvatarCrossingIntoRegion != null) + { + OnAvatarCrossingIntoRegion(regionHandle, agentID, position, isFlying); + return true; + } + return false; + } + + public virtual bool TriggerAcknowledgeAgentCrossed(ulong regionHandle, LLUUID agentID) + { + if (OnAcknowledgeAgentCrossed != null) + { + OnAcknowledgeAgentCrossed(regionHandle, agentID); + return true; + } + return false; + } + + /// + /// + /// + /// TODO: Doesnt take any args?? + /// + public virtual bool TriggerExpectChildAgent() + { + if (OnExpectChildAgent != null) + { + OnExpectChildAgent(); + return true; + } + + return false; + } + + /// + /// + /// + /// Added to avoid a unused compiler warning on OnNeighboursUpdate, TODO: Check me + /// + /// + public virtual bool TriggerOnNeighboursUpdate(List neighbours) + { + if (OnNeighboursUpdate != null) + { + OnNeighboursUpdate(neighbours); + return true; + } + + return false; + } + } +} diff --git a/OpenSim/Framework/General/Remoting.cs b/OpenSim/Framework/General/Remoting.cs new file mode 100644 index 0000000000..df32db2060 --- /dev/null +++ b/OpenSim/Framework/General/Remoting.cs @@ -0,0 +1,135 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Security.Cryptography; +using System.Text; + +namespace OpenSim.Framework +{ + /// + /// NEEDS AUDIT. + /// + /// + /// Suggested implementation + /// Store two digests for each foreign host. A local copy of the local hash using the local challenge (when issued), and a local copy of the remote hash using the remote challenge. + /// When sending data to the foreign host - run 'Sign' on the data and affix the returned byte[] to the message. + /// When recieving data from the foreign host - run 'Authenticate' against the data and the attached byte[]. + /// Both hosts should be performing these operations for this to be effective. + /// + class RemoteDigest + { + private byte[] currentHash; + private byte[] secret; + + private SHA512Managed SHA512; + + /// + /// Initialises a new RemoteDigest authentication mechanism + /// + /// Needs an audit by a cryptographic professional - was not "roll your own"'d by choice but rather a serious lack of decent authentication mechanisms in .NET remoting + /// The shared secret between systems (for inter-sim, this is provided in encrypted form during connection, for grid this is input manually in setup) + /// Binary salt - some common value - to be decided what + /// The challenge key provided by the third party + public RemoteDigest(string sharedSecret, byte[] salt, string challenge) + { + SHA512 = new SHA512Managed(); + Rfc2898DeriveBytes RFC2898 = new Rfc2898DeriveBytes(sharedSecret,salt); + secret = RFC2898.GetBytes(512); + ASCIIEncoding ASCII = new ASCIIEncoding(); + + currentHash = SHA512.ComputeHash(AppendArrays(secret, ASCII.GetBytes(challenge))); + } + + /// + /// Authenticates a piece of incoming data against the local digest. Upon successful authentication, digest string is incremented. + /// + /// The incoming data + /// The remote digest + /// + public bool Authenticate(byte[] data, byte[] digest) + { + byte[] newHash = SHA512.ComputeHash(AppendArrays(AppendArrays(currentHash, secret), data)); + if (digest == newHash) + { + currentHash = newHash; + return true; + } + else + { + throw new Exception("Hash comparison failed. Key resync required."); + } + } + + /// + /// Signs a new bit of data with the current hash. Returns a byte array which should be affixed to the message. + /// Signing a piece of data will automatically increment the hash - if you sign data and do not send it, the + /// hashes will get out of sync and throw an exception when validation is attempted. + /// + /// The outgoing data + /// The local digest + public byte[] Sign(byte[] data) + { + currentHash = SHA512.ComputeHash(AppendArrays(AppendArrays(currentHash, secret), data)); + return currentHash; + } + + /// + /// Generates a new challenge string to be issued to a foreign host. Challenges are 1024-bit (effective strength of less than 512-bits) messages generated using the Crytographic Random Number Generator. + /// + /// A 128-character hexadecimal string containing the challenge. + public static string GenerateChallenge() + { + RNGCryptoServiceProvider RNG = new RNGCryptoServiceProvider(); + byte[] bytes = new byte[64]; + RNG.GetBytes(bytes); + + StringBuilder sb = new StringBuilder(bytes.Length * 2); + foreach (byte b in bytes) + { + sb.AppendFormat("{0:x2}", b); + } + return sb.ToString(); + } + + /// + /// Helper function, merges two byte arrays + /// + /// Sourced from MSDN Forum + /// A + /// B + /// C + private byte[] AppendArrays(byte[] a, byte[] b) + { + byte[] c = new byte[a.Length + b.Length]; + Buffer.BlockCopy(a, 0, c, 0, a.Length); + Buffer.BlockCopy(b, 0, c, a.Length, b.Length); + return c; + } + + } +} diff --git a/OpenSim/Framework/General/Types/AgentCiruitData.cs b/OpenSim/Framework/General/Types/AgentCiruitData.cs new file mode 100644 index 0000000000..ed9ee3c166 --- /dev/null +++ b/OpenSim/Framework/General/Types/AgentCiruitData.cs @@ -0,0 +1,49 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; +using System; + +namespace OpenSim.Framework.Types +{ + [Serializable] + public class AgentCircuitData + { + public AgentCircuitData() { } + public LLUUID AgentID; + public LLUUID SessionID; + public LLUUID SecureSessionID; + public LLVector3 startpos; + public string firstname; + public string lastname; + public uint circuitcode; + public bool child; + public LLUUID InventoryFolder; + public LLUUID BaseFolder; + public string CapsPath = ""; + } +} diff --git a/OpenSim/Framework/General/Types/AgentWearable.cs b/OpenSim/Framework/General/Types/AgentWearable.cs new file mode 100644 index 0000000000..e712ca1a06 --- /dev/null +++ b/OpenSim/Framework/General/Types/AgentWearable.cs @@ -0,0 +1,66 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; + +namespace OpenSim.Framework.Types +{ + public class AvatarWearable + { + public LLUUID AssetID = new LLUUID("00000000-0000-0000-0000-000000000000"); + public LLUUID ItemID = new LLUUID("00000000-0000-0000-0000-000000000000"); + + public AvatarWearable() + { + + } + + public static AvatarWearable[] DefaultWearables + { + get + { + AvatarWearable[] defaultWearables = new AvatarWearable[13]; //should be 13 of these + for (int i = 0; i < 13; i++) + { + defaultWearables[i] = new AvatarWearable(); + } + defaultWearables[0].AssetID = new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73"); + defaultWearables[0].ItemID = new LLUUID("66c41e39-38f9-f75a-024e-585989bfaba9"); + + defaultWearables[1].ItemID = new LLUUID("77c41e39-38f9-f75a-024e-585989bfabc9"); + defaultWearables[1].AssetID = new LLUUID("77c41e39-38f9-f75a-024e-585989bbabbb"); + + defaultWearables[4].ItemID = new LLUUID("77c41e39-38f9-f75a-0000-585989bf0000"); + defaultWearables[4].AssetID = new LLUUID("00000000-38f9-1111-024e-222222111110"); + + defaultWearables[5].ItemID = new LLUUID("77c41e39-38f9-f75a-0000-5859892f1111"); + defaultWearables[5].AssetID = new LLUUID("00000000-38f9-1111-024e-222222111120"); + return defaultWearables; + } + } + } +} diff --git a/OpenSim/Framework/General/Types/AssetBase.cs b/OpenSim/Framework/General/Types/AssetBase.cs new file mode 100644 index 0000000000..c203f5197e --- /dev/null +++ b/OpenSim/Framework/General/Types/AssetBase.cs @@ -0,0 +1,46 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; + +namespace OpenSim.Framework.Types +{ + public class AssetBase + { + public byte[] Data; + public LLUUID FullID; + public sbyte Type; + public sbyte InvType; + public string Name; + public string Description; + + public AssetBase() + { + + } + } +} diff --git a/OpenSim/Framework/General/Types/AssetLandmark.cs b/OpenSim/Framework/General/Types/AssetLandmark.cs new file mode 100644 index 0000000000..8aa872e86d --- /dev/null +++ b/OpenSim/Framework/General/Types/AssetLandmark.cs @@ -0,0 +1,59 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; +using libsecondlife; + +namespace OpenSim.Framework.Types +{ + public class AssetLandmark : AssetBase + { + public int Version; + public LLVector3 Position; + public LLUUID RegionID; + + public AssetLandmark(AssetBase a) + { + this.Data = a.Data; + this.FullID = a.FullID; + this.Type = a.Type; + this.InvType = a.InvType; + this.Name = a.Name; + this.Description = a.Description; + InternData(); + } + + private void InternData() + { + string temp = Encoding.UTF8.GetString(Data).Trim(); + string[] parts = temp.Split('\n'); + int.TryParse(parts[0].Substring(17, 1), out Version); + LLUUID.TryParse(parts[1].Substring(10, 36), out RegionID); + LLVector3.TryParse(parts[2].Substring(11, parts[2].Length - 11), out Position); + } + } +} diff --git a/OpenSim/Framework/General/Types/AssetStorage.cs b/OpenSim/Framework/General/Types/AssetStorage.cs new file mode 100644 index 0000000000..3681336fd4 --- /dev/null +++ b/OpenSim/Framework/General/Types/AssetStorage.cs @@ -0,0 +1,47 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; + +namespace OpenSim.Framework.Types +{ + public class AssetStorage + { + + public AssetStorage() { + } + + public AssetStorage(LLUUID assetUUID) { + UUID=assetUUID; + } + + public byte[] Data; + public sbyte Type; + public string Name; + public LLUUID UUID; + } +} diff --git a/OpenSim/Framework/General/Types/EstateSettings.cs b/OpenSim/Framework/General/Types/EstateSettings.cs new file mode 100644 index 0000000000..e6da23ce79 --- /dev/null +++ b/OpenSim/Framework/General/Types/EstateSettings.cs @@ -0,0 +1,732 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.IO; +using libsecondlife; +using OpenSim.Framework.Configuration; +using OpenSim.Framework.Utilities; + +namespace OpenSim.Framework.Types +{ + public class EstateSettings + { + + //Settings to this island + private float m_billableFactor; + public float billableFactor + { + get + { + return m_billableFactor; + } + set + { + m_billableFactor = value; + configMember.forceSetConfigurationOption("billable_factor", m_billableFactor.ToString()); + } + } + + + private uint m_estateID; + public uint estateID + { + get + { + return m_estateID; + } + set + { + m_estateID = value; + configMember.forceSetConfigurationOption("estate_id", m_estateID.ToString()); + } + } + + + private uint m_parentEstateID; + public uint parentEstateID + { + get + { + return m_parentEstateID; + } + set + { + m_parentEstateID = value; + configMember.forceSetConfigurationOption("parent_estate_id", m_parentEstateID.ToString()); + } + } + + private byte m_maxAgents; + public byte maxAgents + { + get + { + return m_maxAgents; + } + set + { + m_maxAgents = value; + configMember.forceSetConfigurationOption("max_agents", m_maxAgents.ToString()); + } + } + + private float m_objectBonusFactor; + public float objectBonusFactor + { + get + { + return m_objectBonusFactor; + } + set + { + m_objectBonusFactor = value; + configMember.forceSetConfigurationOption("object_bonus_factor", m_objectBonusFactor.ToString()); + } + } + + private int m_redirectGridX; + public int redirectGridX + { + get + { + return m_redirectGridX; + } + set + { + m_redirectGridX = value; + configMember.forceSetConfigurationOption("redirect_grid_x", m_redirectGridX.ToString()); + } + } + + private int m_redirectGridY; + public int redirectGridY + { + get + { + return m_redirectGridY; + } + set + { + m_redirectGridY = value; + configMember.forceSetConfigurationOption("redirect_grid_y", m_redirectGridY.ToString()); + } + } + + private Simulator.RegionFlags m_regionFlags; + public Simulator.RegionFlags regionFlags + { + get + { + return m_regionFlags; + } + set + { + m_regionFlags = value; + configMember.forceSetConfigurationOption("region_flags", m_regionFlags.ToString()); + } + } + + + private Simulator.SimAccess m_simAccess; + public Simulator.SimAccess simAccess + { + get + { + return m_simAccess; + } + set + { + m_simAccess = value; + configMember.forceSetConfigurationOption("sim_access", m_simAccess.ToString()); + } + } + + private float m_sunHour; + public float sunHour + { + get + { + return m_sunHour; + } + set + { + m_sunHour = value; + configMember.forceSetConfigurationOption("sun_hour", m_sunHour.ToString()); + } + } + + private float m_terrainRaiseLimit; + public float terrainRaiseLimit + { + get + { + return m_terrainRaiseLimit; + } + set + { + m_terrainRaiseLimit = value; + configMember.forceSetConfigurationOption("terrain_raise_limit", m_terrainRaiseLimit.ToString()); + } + } + + private float m_terrainLowerLimit; + public float terrainLowerLimit + { + get + { + return m_terrainLowerLimit; + } + set + { + m_terrainLowerLimit = value; + configMember.forceSetConfigurationOption("terrain_lower_limit", m_terrainLowerLimit.ToString()); + } + } + + private bool m_useFixedSun; + public bool useFixedSun + { + get + { + return m_useFixedSun; + } + set + { + m_useFixedSun = value; + configMember.forceSetConfigurationOption("use_fixed_sun", m_useFixedSun.ToString()); + } + } + + + private int m_pricePerMeter; + public int pricePerMeter + { + get + { + return m_pricePerMeter; + } + set + { + m_pricePerMeter = value; + configMember.forceSetConfigurationOption("price_per_meter", m_pricePerMeter.ToString()); + } + } + + + private ushort m_regionWaterHeight; + public ushort regionWaterHeight + { + get + { + return m_regionWaterHeight; + } + set + { + m_regionWaterHeight = value; + configMember.forceSetConfigurationOption("region_water_height", m_regionWaterHeight.ToString()); + } + } + + + private bool m_regionAllowTerraform; + public bool regionAllowTerraform + { + get + { + return m_regionAllowTerraform; + } + set + { + m_regionAllowTerraform = value; + configMember.forceSetConfigurationOption("region_allow_terraform", m_regionAllowTerraform.ToString()); + } + } + + + // Region Information + // Low resolution 'base' textures. No longer used. + private LLUUID m_terrainBase0; + public LLUUID terrainBase0 + { + get + { + return m_terrainBase0; + } + set + { + m_terrainBase0 = value; + configMember.forceSetConfigurationOption("terrain_base_0", m_terrainBase0.ToString()); + } + } + + private LLUUID m_terrainBase1; + public LLUUID terrainBase1 + { + get + { + return m_terrainBase1; + } + set + { + m_terrainBase1 = value; + configMember.forceSetConfigurationOption("terrain_base_1", m_terrainBase1.ToString()); + } + } + + private LLUUID m_terrainBase2; + public LLUUID terrainBase2 + { + get + { + return m_terrainBase2; + } + set + { + m_terrainBase2 = value; + configMember.forceSetConfigurationOption("terrain_base_2", m_terrainBase2.ToString()); + } + } + + private LLUUID m_terrainBase3; + public LLUUID terrainBase3 + { + get + { + return m_terrainBase3; + } + set + { + m_terrainBase3 = value; + configMember.forceSetConfigurationOption("terrain_base_3", m_terrainBase3.ToString()); + } + } + + + // Higher resolution terrain textures + private LLUUID m_terrainDetail0; + public LLUUID terrainDetail0 + { + get + { + return m_terrainDetail0; + } + set + { + + m_terrainDetail0 = value; + configMember.forceSetConfigurationOption("terrain_detail_0", m_terrainDetail0.ToString()); + } + } + + private LLUUID m_terrainDetail1; + public LLUUID terrainDetail1 + { + get + { + return m_terrainDetail1; + } + set + { + m_terrainDetail1 = value; + configMember.forceSetConfigurationOption("terrain_detail_1", m_terrainDetail1.ToString()); + } + } + private LLUUID m_terrainDetail2; + public LLUUID terrainDetail2 + { + get + { + return m_terrainDetail2; + } + set + { + m_terrainDetail2 = value; + configMember.forceSetConfigurationOption("terrain_detail_2", m_terrainDetail2.ToString()); + } + } + private LLUUID m_terrainDetail3; + public LLUUID terrainDetail3 + { + get + { + return m_terrainDetail3; + } + set + { + m_terrainDetail3 = value; + configMember.forceSetConfigurationOption("terrain_detail_3", m_terrainDetail3.ToString()); + } + } + + // First quad - each point is bilinearly interpolated at each meter of terrain + private float m_terrainStartHeight0; + public float terrainStartHeight0 + { + get + { + return m_terrainStartHeight0; + } + set + { + m_terrainStartHeight0 = value; + configMember.forceSetConfigurationOption("terrain_start_height_0", m_terrainStartHeight0.ToString()); + } + } + + + private float m_terrainStartHeight1; + public float terrainStartHeight1 + { + get + { + return m_terrainStartHeight1; + } + set + { + m_terrainStartHeight1 = value; + configMember.forceSetConfigurationOption("terrain_start_height_1", m_terrainStartHeight1.ToString()); + } + } + + private float m_terrainStartHeight2; + public float terrainStartHeight2 + { + get + { + return m_terrainStartHeight2; + } + set + { + m_terrainStartHeight2 = value; + configMember.forceSetConfigurationOption("terrain_start_height_2", m_terrainStartHeight2.ToString()); + } + } + + private float m_terrainStartHeight3; + public float terrainStartHeight3 + { + get + { + return m_terrainStartHeight3; + } + set + { + m_terrainStartHeight3 = value; + configMember.forceSetConfigurationOption("terrain_start_height_3", m_terrainStartHeight3.ToString()); + } + } + // Second quad - also bilinearly interpolated. + // Terrain texturing is done that: + // 0..3 (0 = base0, 3 = base3) = (terrain[x,y] - start[x,y]) / range[x,y] + private float m_terrainHeightRange0; + public float terrainHeightRange0 + { + get + { + return m_terrainHeightRange0; + } + set + { + m_terrainHeightRange0 = value; + configMember.forceSetConfigurationOption("terrain_height_range_0", m_terrainHeightRange0.ToString()); + } + } + + private float m_terrainHeightRange1; + public float terrainHeightRange1 + { + get + { + return m_terrainHeightRange1; + } + set + { + m_terrainHeightRange1 = value; + configMember.forceSetConfigurationOption("terrain_height_range_1", m_terrainHeightRange1.ToString()); + } + } + + private float m_terrainHeightRange2; + public float terrainHeightRange2 + { + get + { + return m_terrainHeightRange2; + } + set + { + m_terrainHeightRange2 = value; + configMember.forceSetConfigurationOption("terrain_height_range_2", m_terrainHeightRange2.ToString()); + } + } + + private float m_terrainHeightRange3; + public float terrainHeightRange3 + { + get + { + return m_terrainHeightRange3; + } + set + { + m_terrainHeightRange3 = value; + configMember.forceSetConfigurationOption("terrain_height_range_3", m_terrainHeightRange3.ToString()); + } + } + // Terrain Default (Must be in F32 Format!) + private string m_terrainFile; + public string terrainFile + { + get + { + return m_terrainFile; + } + set + { + m_terrainFile = value; + configMember.forceSetConfigurationOption("terrain_file", m_terrainFile.ToString()); + } + } + + private double m_terrainMultiplier; + public double terrainMultiplier + { + get + { + return m_terrainMultiplier; + } + set + { + m_terrainMultiplier = value; + configMember.forceSetConfigurationOption("terrain_multiplier", m_terrainMultiplier.ToString()); + } + } + + private float m_waterHeight; + public float waterHeight + { + get + { + return m_waterHeight; + } + set + { + m_waterHeight = value; + configMember.forceSetConfigurationOption("water_height", m_waterHeight.ToString()); + } + } + + private LLUUID m_terrainImageID; + public LLUUID terrainImageID + { + get + { + return m_terrainImageID; + } + set + { + m_terrainImageID = value; + configMember.forceSetConfigurationOption("terrain_image_id", m_terrainImageID.ToString()); + } + } + private ConfigurationMember configMember; + public EstateSettings() + { + configMember = new ConfigurationMember(Path.Combine(Util.configDir(),"estate_settings.xml"), "ESTATE SETTINGS", this.loadConfigurationOptions, this.handleIncomingConfiguration); + configMember.performConfigurationRetrieve(); + } + + public void loadConfigurationOptions() + { + configMember.addConfigurationOption("billable_factor", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "","0.0",true); + configMember.addConfigurationOption("estate_id", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, "","0",true); + configMember.addConfigurationOption("parent_estate_id", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, "", "0", true); + configMember.addConfigurationOption("max_agents", ConfigurationOption.ConfigurationTypes.TYPE_BYTE, "", "40", true); + + configMember.addConfigurationOption("object_bonus_factor", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "1.0", true); + configMember.addConfigurationOption("redirect_grid_x", ConfigurationOption.ConfigurationTypes.TYPE_INT32, "", "0", true); + configMember.addConfigurationOption("redirect_grid_y", ConfigurationOption.ConfigurationTypes.TYPE_INT32, "", "0", true); + configMember.addConfigurationOption("region_flags", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, "", "0", true); + configMember.addConfigurationOption("sim_access", ConfigurationOption.ConfigurationTypes.TYPE_BYTE, "", "21", true); + configMember.addConfigurationOption("sun_hour", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "0", true); + configMember.addConfigurationOption("terrain_raise_limit", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "0", true); + configMember.addConfigurationOption("terrain_lower_limit", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "0", true); + configMember.addConfigurationOption("use_fixed_sun", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN, "", "false", true); + configMember.addConfigurationOption("price_per_meter", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, "", "1", true); + configMember.addConfigurationOption("region_water_height", ConfigurationOption.ConfigurationTypes.TYPE_UINT16, "", "20", true); + configMember.addConfigurationOption("region_allow_terraform", ConfigurationOption.ConfigurationTypes.TYPE_BOOLEAN, "", "true", true); + + configMember.addConfigurationOption("terrain_base_0", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, "", "b8d3965a-ad78-bf43-699b-bff8eca6c975", true); + configMember.addConfigurationOption("terrain_base_1", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, "", "abb783e6-3e93-26c0-248a-247666855da3", true); + configMember.addConfigurationOption("terrain_base_2", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, "", "179cdabd-398a-9b6b-1391-4dc333ba321f", true); + configMember.addConfigurationOption("terrain_base_3", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, "", "beb169c7-11ea-fff2-efe5-0f24dc881df2", true); + + configMember.addConfigurationOption("terrain_detail_0", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, "", "00000000-0000-0000-0000-000000000000", true); + configMember.addConfigurationOption("terrain_detail_1", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, "", "00000000-0000-0000-0000-000000000000", true); + configMember.addConfigurationOption("terrain_detail_2", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, "", "00000000-0000-0000-0000-000000000000", true); + configMember.addConfigurationOption("terrain_detail_3", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, "", "00000000-0000-0000-0000-000000000000", true); + + configMember.addConfigurationOption("terrain_start_height_0", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "10.0", true); + configMember.addConfigurationOption("terrain_start_height_1", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "10.0", true); + configMember.addConfigurationOption("terrain_start_height_2", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "10.0", true); + configMember.addConfigurationOption("terrain_start_height_3", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "10.0", true); + + configMember.addConfigurationOption("terrain_height_range_0", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "60.0", true); + configMember.addConfigurationOption("terrain_height_range_1", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "60.0", true); + configMember.addConfigurationOption("terrain_height_range_2", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "60.0", true); + configMember.addConfigurationOption("terrain_height_range_3", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "60.0", true); + + configMember.addConfigurationOption("terrain_file", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "", "default.r32", true); + configMember.addConfigurationOption("terrain_multiplier", ConfigurationOption.ConfigurationTypes.TYPE_FLOAT, "", "60.0", true); + configMember.addConfigurationOption("water_height", ConfigurationOption.ConfigurationTypes.TYPE_DOUBLE, "", "20.0", true); + configMember.addConfigurationOption("terrain_image_id", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, "", "00000000-0000-0000-0000-000000000000", true); + } + + public bool handleIncomingConfiguration(string configuration_key, object configuration_result) + { + switch (configuration_key) + { + case "billable_factor": + this.m_billableFactor = (float)configuration_result; + break; + case "estate_id": + this.m_estateID = (uint)configuration_result; + break; + case "parent_estate_id": + this.m_parentEstateID = (uint)configuration_result; + break; + case "max_agents": + this.m_maxAgents = (byte)configuration_result; + break; + + case "object_bonus_factor": + this.m_objectBonusFactor = (float)configuration_result; + break; + case "redirect_grid_x": + this.m_redirectGridX = (int)configuration_result; + break; + case "redirect_grid_y": + this.m_redirectGridY = (int)configuration_result; + break; + case "region_flags": + this.m_regionFlags = (Simulator.RegionFlags)((uint)configuration_result); + break; + case "sim_access": + this.m_simAccess = (Simulator.SimAccess)((byte)configuration_result); + break; + case "sun_hour": + this.m_sunHour = (float)configuration_result; + break; + case "terrain_raise_limit": + this.m_terrainRaiseLimit = (float)configuration_result; + break; + case "terrain_lower_limit": + this.m_terrainLowerLimit = (float)configuration_result; + break; + case "use_fixed_sun": + this.m_useFixedSun = (bool)configuration_result; + break; + case "price_per_meter": + this.m_pricePerMeter = System.Convert.ToInt32(configuration_result); + break; + case "region_water_height": + this.m_regionWaterHeight = (ushort)configuration_result; + break; + case "region_allow_terraform": + this.m_regionAllowTerraform = (bool)configuration_result; + break; + + case "terrain_base_0": + this.m_terrainBase0 = (LLUUID)configuration_result; + break; + case "terrain_base_1": + this.m_terrainBase1 = (LLUUID)configuration_result; + break; + case "terrain_base_2": + this.m_terrainBase2 = (LLUUID)configuration_result; + break; + case "terrain_base_3": + this.m_terrainBase3 = (LLUUID)configuration_result; + break; + + case "terrain_detail_0": + this.m_terrainDetail0 = (LLUUID)configuration_result; + break; + case "terrain_detail_1": + this.m_terrainDetail1 = (LLUUID)configuration_result; + break; + case "terrain_detail_2": + this.m_terrainDetail2 = (LLUUID)configuration_result; + break; + case "terrain_detail_3": + this.m_terrainDetail3 = (LLUUID)configuration_result; + break; + + case "terrain_start_height_0": + this.m_terrainStartHeight0 = (float)configuration_result; + break; + case "terrain_start_height_1": + this.m_terrainStartHeight1 = (float)configuration_result; + break; + case "terrain_start_height_2": + this.m_terrainStartHeight2 = (float)configuration_result; + break; + case "terrain_start_height_3": + this.m_terrainStartHeight3 = (float)configuration_result; + break; + + case "terrain_height_range_0": + this.m_terrainHeightRange0 = (float)configuration_result; + break; + case "terrain_height_range_1": + this.m_terrainHeightRange1 = (float)configuration_result; + break; + case "terrain_height_range_2": + this.m_terrainHeightRange2 = (float)configuration_result; + break; + case "terrain_height_range_3": + this.m_terrainHeightRange3 = (float)configuration_result; + break; + + case "terrain_file": + this.m_terrainFile = (string)configuration_result; + break; + case "terrain_multiplier": + this.m_terrainMultiplier = System.Convert.ToDouble(configuration_result); + break; + case "water_height": + float.TryParse(((double)configuration_result).ToString(),out this.m_waterHeight); + break; + case "terrain_image_id": + this.m_terrainImageID = (LLUUID)configuration_result; + break; + } + + return true; + } + } +} diff --git a/OpenSim/Framework/General/Types/LandData.cs b/OpenSim/Framework/General/Types/LandData.cs new file mode 100644 index 0000000000..2ae4927252 --- /dev/null +++ b/OpenSim/Framework/General/Types/LandData.cs @@ -0,0 +1,120 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; + +namespace OpenSim.Framework.Types +{ + + public class LandData + { + public byte[] landBitmapByteArray = new byte[512]; + public string landName = "Your Parcel"; + public string landDesc = ""; + public LLUUID ownerID = new LLUUID(); + public bool isGroupOwned = false; + public LLVector3 AABBMin = new LLVector3(); + public LLVector3 AABBMax = new LLVector3(); + public int area = 0; + public uint auctionID = 0; //Unemplemented. If set to 0, not being auctioned + public LLUUID authBuyerID = new LLUUID(); //Unemplemented. Authorized Buyer's UUID + public Parcel.ParcelCategory category = new Parcel.ParcelCategory(); //Unemplemented. Parcel's chosen category + public int claimDate = 0; //Unemplemented + public int claimPrice = 0; //Unemplemented + public LLUUID groupID = new LLUUID(); //Unemplemented + public int groupPrims = 0; + public int otherPrims = 0; + public int ownerPrims = 0; + public int selectedPrims = 0; + public int simwidePrims = 0; + public int simwideArea = 0; + public int salePrice = 0; //Unemeplemented. Parcels price. + public Parcel.ParcelStatus landStatus = Parcel.ParcelStatus.Leased; + public uint landFlags = (uint)Parcel.ParcelFlags.AllowFly | (uint)Parcel.ParcelFlags.AllowLandmark | (uint)Parcel.ParcelFlags.AllowAllObjectEntry | (uint)Parcel.ParcelFlags.AllowDeedToGroup | (uint)Parcel.ParcelFlags.AllowTerraform | (uint)Parcel.ParcelFlags.CreateObjects | (uint)Parcel.ParcelFlags.AllowOtherScripts; + public byte landingType = 0; + public byte mediaAutoScale = 0; + public LLUUID mediaID = LLUUID.Zero; + public int localID = 0; + public LLUUID globalID = new LLUUID(); + + public string mediaURL = ""; + public string musicURL = ""; + public float passHours = 0; + public int passPrice = 0; + public LLUUID snapshotID = LLUUID.Zero; + public LLVector3 userLocation = new LLVector3(); + public LLVector3 userLookAt = new LLVector3(); + + public LandData() + { + globalID = LLUUID.Random(); + } + + public LandData Copy() + { + LandData landData = new LandData(); + + landData.AABBMax = this.AABBMax; + landData.AABBMin = this.AABBMin; + landData.area = this.area; + landData.auctionID = this.auctionID; + landData.authBuyerID = this.authBuyerID; + landData.category = this.category; + landData.claimDate = this.claimDate; + landData.claimPrice = this.claimPrice; + landData.globalID = this.globalID; + landData.groupID = this.groupID; + landData.groupPrims = this.groupPrims; + landData.otherPrims = this.otherPrims; + landData.ownerPrims = this.ownerPrims; + landData.selectedPrims = this.selectedPrims; + landData.isGroupOwned = this.isGroupOwned; + landData.localID = this.localID; + landData.landingType = this.landingType; + landData.mediaAutoScale = this.mediaAutoScale; + landData.mediaID = this.mediaID; + landData.mediaURL = this.mediaURL; + landData.musicURL = this.musicURL; + landData.ownerID = this.ownerID; + landData.landBitmapByteArray = (byte[])this.landBitmapByteArray.Clone(); + landData.landDesc = this.landDesc; + landData.landFlags = this.landFlags; + landData.landName = this.landName; + landData.landStatus = this.landStatus; + landData.passHours = this.passHours; + landData.passPrice = this.passPrice; + landData.salePrice = this.salePrice; + landData.snapshotID = this.snapshotID; + landData.userLocation = this.userLocation; + landData.userLookAt = this.userLookAt; + + return landData; + + } + } + +} diff --git a/OpenSim/Framework/General/Types/Login.cs b/OpenSim/Framework/General/Types/Login.cs new file mode 100644 index 0000000000..d54c0195c8 --- /dev/null +++ b/OpenSim/Framework/General/Types/Login.cs @@ -0,0 +1,49 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; + +namespace OpenSim.Framework.Types +{ + public class Login + { + public string First = "Test"; + public string Last = "User"; + public LLUUID Agent; + public LLUUID Session; + public LLUUID SecureSession = LLUUID.Zero; + public LLUUID InventoryFolder; + public LLUUID BaseFolder; + public uint CircuitCode; + public string CapsPath =""; + + public Login() + { + + } + } +} diff --git a/OpenSim/Framework/General/Types/MapBlockData.cs b/OpenSim/Framework/General/Types/MapBlockData.cs new file mode 100644 index 0000000000..fbb3b7392d --- /dev/null +++ b/OpenSim/Framework/General/Types/MapBlockData.cs @@ -0,0 +1,23 @@ +using System; +using libsecondlife; + +namespace OpenSim.Framework.Types +{ + public class MapBlockData + { + public uint Flags; + public ushort X; + public ushort Y; + public byte Agents; + public byte Access; + public byte WaterHeight; + public LLUUID MapImageId; + public String Name; + public uint RegionFlags; + + public MapBlockData() + { + + } + } +} diff --git a/OpenSim/Framework/General/Types/NeighbourInfo.cs b/OpenSim/Framework/General/Types/NeighbourInfo.cs new file mode 100644 index 0000000000..bb67981481 --- /dev/null +++ b/OpenSim/Framework/General/Types/NeighbourInfo.cs @@ -0,0 +1,42 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +namespace OpenSim.Framework.Types +{ + public class NeighbourInfo + { + public NeighbourInfo() + { + } + + public ulong regionhandle; + public uint RegionLocX; + public uint RegionLocY; + public string sim_ip; + public uint sim_port; + } +} diff --git a/OpenSim/Framework/General/Types/NetworkServersInfo.cs b/OpenSim/Framework/General/Types/NetworkServersInfo.cs new file mode 100644 index 0000000000..4bb5ee5fc8 --- /dev/null +++ b/OpenSim/Framework/General/Types/NetworkServersInfo.cs @@ -0,0 +1,92 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 OpenSim.Framework.Console; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Configuration; + +using Nini.Config; +namespace OpenSim.Framework.Types +{ + public class NetworkServersInfo + { + public string AssetURL = "http://127.0.0.1:8003/"; + public string AssetSendKey = ""; + + public string GridURL = ""; + public string GridSendKey = ""; + public string GridRecvKey = ""; + public string UserURL = ""; + public string UserSendKey = ""; + public string UserRecvKey = ""; + public bool isSandbox; + + public int HttpListenerPort = 9000; + public int RemotingListenerPort = 8895; + + + public NetworkServersInfo() + { + } + + public NetworkServersInfo(uint defaultHomeLocX, uint defaultHomeLocY) + { + m_defaultHomeLocX = defaultHomeLocX; + m_defaultHomeLocY = defaultHomeLocY; + } + + private uint? m_defaultHomeLocX; + public uint DefaultHomeLocX + { + get { return m_defaultHomeLocX.Value; } + } + + private uint? m_defaultHomeLocY; + public uint DefaultHomeLocY + { + get { return m_defaultHomeLocY.Value; } + } + + public void loadFromConfiguration(IConfigSource config) + { + m_defaultHomeLocX = (uint)config.Configs["StandAlone"].GetInt("default_location_x", 1000); + m_defaultHomeLocY = (uint)config.Configs["StandAlone"].GetInt("default_location_y", 1000); + + HttpListenerPort = config.Configs["Network"].GetInt("http_listener_port", 9000); + RemotingListenerPort = config.Configs["Network"].GetInt("remoting_listener_port", 8895); + GridURL = config.Configs["Network"].GetString("grid_server_url", "http://127.0.0.1:8001"); + GridSendKey = config.Configs["Network"].GetString("grid_send_key", "null"); + GridRecvKey = config.Configs["Network"].GetString("grid_recv_key", "null"); + UserURL = config.Configs["Network"].GetString("user_server_url", "http://127.0.0.1:8002"); + UserSendKey = config.Configs["Network"].GetString("user_send_key", "null"); + UserRecvKey = config.Configs["Network"].GetString("user_recv_key", "null"); + AssetURL = config.Configs["Network"].GetString("asset_server_url", "http://127.0.0.1:8003"); + + } + } +} diff --git a/OpenSim/Framework/General/Types/PrimData.cs b/OpenSim/Framework/General/Types/PrimData.cs new file mode 100644 index 0000000000..7242f53ede --- /dev/null +++ b/OpenSim/Framework/General/Types/PrimData.cs @@ -0,0 +1,228 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; + +namespace OpenSim.Framework.Types +{ + public class PrimData + { + private const uint FULL_MASK_PERMISSIONS = 2147483647; + + public LLUUID OwnerID; + public byte PCode; + public ushort PathBegin; + public ushort PathEnd; + public byte PathScaleX; + public byte PathScaleY; + public byte PathShearX; + public byte PathShearY; + public sbyte PathSkew; + public ushort ProfileBegin; + public ushort ProfileEnd; + public LLVector3 Scale; + public byte PathCurve; + public byte ProfileCurve; + public uint ParentID = 0; + public ushort ProfileHollow; + public sbyte PathRadiusOffset; + public byte PathRevolutions; + public sbyte PathTaperX; + public sbyte PathTaperY; + public sbyte PathTwist; + public sbyte PathTwistBegin; + public byte[] TextureEntry; // a LL textureEntry in byte[] format + + public Int32 CreationDate; + public uint OwnerMask = FULL_MASK_PERMISSIONS; + public uint NextOwnerMask = FULL_MASK_PERMISSIONS; + public uint GroupMask = FULL_MASK_PERMISSIONS; + public uint EveryoneMask = FULL_MASK_PERMISSIONS; + public uint BaseMask = FULL_MASK_PERMISSIONS; + + //following only used during prim storage + public LLVector3 Position; + public LLQuaternion Rotation = new LLQuaternion(0, 1, 0, 0); + public uint LocalID; + public LLUUID FullID; + + public PrimData() + { + + } + + public PrimData(byte[] data) + { + int i = 0; + + this.OwnerID = new LLUUID(data, i); i += 16; + this.PCode = data[i++]; + this.PathBegin = (ushort)(data[i++] + (data[i++] << 8)); + this.PathEnd = (ushort)(data[i++] + (data[i++] << 8)); + this.PathScaleX = data[i++]; + this.PathScaleY = data[i++]; + this.PathShearX = data[i++]; + this.PathShearY = data[i++]; + this.PathSkew = (sbyte)data[i++]; + this.ProfileBegin = (ushort)(data[i++] + (data[i++] << 8)); + this.ProfileEnd = (ushort)(data[i++] + (data[i++] << 8)); + this.Scale = new LLVector3(data, i); i += 12; + this.PathCurve = data[i++]; + this.ProfileCurve = data[i++]; + this.ParentID = (uint)(data[i++] + (data[i++] << 8) + (data[i++] << 16) + (data[i++] << 24)); + this.ProfileHollow = (ushort)(data[i++] + (data[i++] << 8)); + this.PathRadiusOffset = (sbyte)data[i++]; + this.PathRevolutions = data[i++]; + this.PathTaperX = (sbyte)data[i++]; + this.PathTaperY = (sbyte)data[i++]; + this.PathTwist = (sbyte)data[i++]; + this.PathTwistBegin = (sbyte)data[i++]; + ushort length = (ushort)(data[i++] + (data[i++] << 8)); + this.TextureEntry = new byte[length]; + Array.Copy(data, i, TextureEntry, 0, length); i += length; + this.CreationDate = (Int32)(data[i++] + (data[i++] << 8) + (data[i++] << 16) + (data[i++] << 24)); + this.OwnerMask = (uint)(data[i++] + (data[i++] << 8) + (data[i++] << 16) + (data[i++] << 24)); + this.NextOwnerMask = (uint)(data[i++] + (data[i++] << 8) + (data[i++] << 16) + (data[i++] << 24)); + this.GroupMask = (uint)(data[i++] + (data[i++] << 8) + (data[i++] << 16) + (data[i++] << 24)); + this.EveryoneMask = (uint)(data[i++] + (data[i++] << 8) + (data[i++] << 16) + (data[i++] << 24)); + this.BaseMask = (uint)(data[i++] + (data[i++] << 8) + (data[i++] << 16) + (data[i++] << 24)); + this.Position = new LLVector3(data, i); i += 12; + this.Rotation = new LLQuaternion(data, i, true); i += 12; + this.LocalID = (uint)(data[i++] + (data[i++] << 8) + (data[i++] << 16) + (data[i++] << 24)); + this.FullID = new LLUUID(data, i); i += 16; + + } + + public byte[] ToBytes() + { + int i = 0; + byte[] bytes = new byte[126 + TextureEntry.Length]; + Array.Copy(OwnerID.GetBytes(), 0, bytes, i, 16); i += 16; + bytes[i++] = this.PCode; + bytes[i++] = (byte)(this.PathBegin % 256); + bytes[i++] = (byte)((this.PathBegin >> 8) % 256); + bytes[i++] = (byte)(this.PathEnd % 256); + bytes[i++] = (byte)((this.PathEnd >> 8) % 256); + bytes[i++] = this.PathScaleX; + bytes[i++] = this.PathScaleY; + bytes[i++] = this.PathShearX; + bytes[i++] = this.PathShearY; + bytes[i++] = (byte)this.PathSkew; + bytes[i++] = (byte)(this.ProfileBegin % 256); + bytes[i++] = (byte)((this.ProfileBegin >> 8) % 256); + bytes[i++] = (byte)(this.ProfileEnd % 256); + bytes[i++] = (byte)((this.ProfileEnd >> 8) % 256); + Array.Copy(Scale.GetBytes(), 0, bytes, i, 12); i += 12; + bytes[i++] = this.PathCurve; + bytes[i++] = this.ProfileCurve; + bytes[i++] = (byte)(ParentID % 256); + bytes[i++] = (byte)((ParentID >> 8) % 256); + bytes[i++] = (byte)((ParentID >> 16) % 256); + bytes[i++] = (byte)((ParentID >> 24) % 256); + bytes[i++] = (byte)(this.ProfileHollow % 256); + bytes[i++] = (byte)((this.ProfileHollow >> 8) % 256); + bytes[i++] = ((byte)this.PathRadiusOffset); + bytes[i++] = this.PathRevolutions; + bytes[i++] = ((byte)this.PathTaperX); + bytes[i++] = ((byte)this.PathTaperY); + bytes[i++] = ((byte)this.PathTwist); + bytes[i++] = ((byte)this.PathTwistBegin); + bytes[i++] = (byte)(TextureEntry.Length % 256); + bytes[i++] = (byte)((TextureEntry.Length >> 8) % 256); + Array.Copy(TextureEntry, 0, bytes, i, TextureEntry.Length); i += TextureEntry.Length; + bytes[i++] = (byte)(this.CreationDate % 256); + bytes[i++] = (byte)((this.CreationDate >> 8) % 256); + bytes[i++] = (byte)((this.CreationDate >> 16) % 256); + bytes[i++] = (byte)((this.CreationDate >> 24) % 256); + bytes[i++] = (byte)(this.OwnerMask % 256); + bytes[i++] = (byte)((this.OwnerMask >> 8) % 256); + bytes[i++] = (byte)((this.OwnerMask >> 16) % 256); + bytes[i++] = (byte)((this.OwnerMask >> 24) % 256); + bytes[i++] = (byte)(this.NextOwnerMask % 256); + bytes[i++] = (byte)((this.NextOwnerMask >> 8) % 256); + bytes[i++] = (byte)((this.NextOwnerMask >> 16) % 256); + bytes[i++] = (byte)((this.NextOwnerMask >> 24) % 256); + bytes[i++] = (byte)(this.GroupMask % 256); + bytes[i++] = (byte)((this.GroupMask >> 8) % 256); + bytes[i++] = (byte)((this.GroupMask >> 16) % 256); + bytes[i++] = (byte)((this.GroupMask >> 24) % 256); + bytes[i++] = (byte)(this.EveryoneMask % 256); + bytes[i++] = (byte)((this.EveryoneMask >> 8) % 256); + bytes[i++] = (byte)((this.EveryoneMask >> 16) % 256); + bytes[i++] = (byte)((this.EveryoneMask >> 24) % 256); + bytes[i++] = (byte)(this.BaseMask % 256); + bytes[i++] = (byte)((this.BaseMask >> 8) % 256); + bytes[i++] = (byte)((this.BaseMask >> 16) % 256); + bytes[i++] = (byte)((this.BaseMask >> 24) % 256); + Array.Copy(this.Position.GetBytes(), 0, bytes, i, 12); i += 12; + if (this.Rotation == new LLQuaternion(0, 0, 0, 0)) + { + this.Rotation = new LLQuaternion(0, 1, 0, 0); + } + Array.Copy(this.Rotation.GetBytes(), 0, bytes, i, 12); i += 12; + bytes[i++] = (byte)(this.LocalID % 256); + bytes[i++] = (byte)((this.LocalID >> 8) % 256); + bytes[i++] = (byte)((this.LocalID >> 16) % 256); + bytes[i++] = (byte)((this.LocalID >> 24) % 256); + Array.Copy(FullID.GetBytes(), 0, bytes, i, 16); i += 16; + + return bytes; + } + + //public static PrimData DefaultCube() + //{ + // PrimData primData = new PrimData(); + // primData.CreationDate = (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; + // primData.FullID = LLUUID.Random(); + // primData.Scale = new LLVector3(0.5f, 0.5f, 0.5f); + // primData.Rotation = new LLQuaternion(0, 0, 0, 1); + // primData.PCode = 9; + // primData.ParentID = 0; + // primData.PathBegin = 0; + // primData.PathEnd = 0; + // primData.PathScaleX = 0; + // primData.PathScaleY = 0; + // primData.PathShearX = 0; + // primData.PathShearY = 0; + // primData.PathSkew = 0; + // primData.ProfileBegin = 0; + // primData.ProfileEnd = 0; + // primData.PathCurve = 16; + // primData.ProfileCurve = 1; + // primData.ProfileHollow = 0; + // primData.PathRadiusOffset = 0; + // primData.PathRevolutions = 0; + // primData.PathTaperX = 0; + // primData.PathTaperY = 0; + // primData.PathTwist = 0; + // primData.PathTwistBegin = 0; + + // return primData; + //} + } +} diff --git a/OpenSim/Framework/General/Types/PrimitiveBaseShape.cs b/OpenSim/Framework/General/Types/PrimitiveBaseShape.cs new file mode 100644 index 0000000000..ceb234dc8e --- /dev/null +++ b/OpenSim/Framework/General/Types/PrimitiveBaseShape.cs @@ -0,0 +1,194 @@ +using libsecondlife; +using libsecondlife.Packets; + +namespace OpenSim.Framework.Types +{ + public enum ProfileShape : byte + { + Circle = 0, + Square = 1, + IsometricTriangle = 2, + EquilateralTriangle = 3, + RightTriangle = 4, + HalfCircle = 5 + } + + public enum HollowShape : byte + { + Same = 0, + Circle = 16, + Square = 32, + Triangle = 48 + } + + public enum PCodeEnum : byte + { + Primitive = 9, + Avatar = 47 + } + + public enum Extrusion : byte + { + Straight = 16, + Curve1 = 32, + Curve2 = 48, + Flexible = 128 + } + + public class PrimitiveBaseShape + { + private static byte[] m_defaultTextureEntry; + + public byte PCode; + public ushort PathBegin; + public ushort PathEnd; + public byte PathScaleX; + public byte PathScaleY; + public byte PathShearX; + public byte PathShearY; + public sbyte PathSkew; + public ushort ProfileBegin; + public ushort ProfileEnd; + public LLVector3 Scale; + public byte PathCurve; + public byte ProfileCurve; + public ushort ProfileHollow; + public sbyte PathRadiusOffset; + public byte PathRevolutions; + public sbyte PathTaperX; + public sbyte PathTaperY; + public sbyte PathTwist; + public sbyte PathTwistBegin; + public byte[] TextureEntry; // a LL textureEntry in byte[] format + public byte[] ExtraParams; + + public ProfileShape ProfileShape + { + get + { + return (ProfileShape)(ProfileCurve & 0xf); + } + set + { + byte oldValueMasked = (byte)(ProfileCurve & 0xf0); + ProfileCurve = (byte)(oldValueMasked | (byte)value); + } + } + + public HollowShape HollowShape + { + get + { + return (HollowShape)(ProfileHollow & 0xf0); + } + set + { + byte oldValueMasked = (byte)(ProfileHollow & 0xf0); + ProfileHollow = (byte)(oldValueMasked | (byte)value); + } + } + + public LLVector3 PrimScale + { + get + { + return this.Scale; + } + } + + static PrimitiveBaseShape() + { + m_defaultTextureEntry = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-9999-000000000005")).ToBytes(); + } + + public PrimitiveBaseShape() + { + PCode = (byte)PCodeEnum.Primitive; + ExtraParams = new byte[1]; + TextureEntry = m_defaultTextureEntry; + } + + //void returns need to change of course + public virtual void GetMesh() + { + + } + + public PrimitiveBaseShape Copy() + { + return (PrimitiveBaseShape)this.MemberwiseClone(); + } + } + + public class GenericShape : PrimitiveBaseShape + { + public GenericShape() + : base() + { + + } + } + + public class BoxShape : PrimitiveBaseShape + { + public BoxShape() + : base() + { + PathCurve = (byte)Extrusion.Straight; + ProfileShape = ProfileShape.Square; + PathScaleX = 100; + PathScaleY = 100; + } + + public BoxShape(float side) + : this() + { + SetSide(side); + } + + public void SetSide(float side) + { + Scale = new LLVector3(side, side, side); + } + + public static BoxShape Default + { + get + { + BoxShape boxShape = new BoxShape(); + + boxShape.SetSide(0.5f); + + return boxShape; + } + } + } + public class CylinderShape : PrimitiveBaseShape + { + public CylinderShape() + : base() + { + PathCurve = (byte)Extrusion.Straight; + ProfileShape = ProfileShape.Circle; + PathScaleX = 100; + PathScaleY = 100; + } + + public CylinderShape(float radius, float heigth) + : this() + { + SetRadius(radius); + SetHeigth(heigth); + } + + private void SetHeigth(float heigth) + { + Scale.Z = heigth; + } + + private void SetRadius(float radius) + { + Scale.X = Scale.Y = radius * 2f; + } + } +} diff --git a/OpenSim/Framework/General/Types/RegionHandle.cs b/OpenSim/Framework/General/Types/RegionHandle.cs new file mode 100644 index 0000000000..4a055adae8 --- /dev/null +++ b/OpenSim/Framework/General/Types/RegionHandle.cs @@ -0,0 +1,121 @@ +using System; +using System.Net; + +namespace OpenSim.Framework.Types +{ + /// + /// A class for manipulating RegionHandle coordinates + /// + class RegionHandle + { + private UInt64 handle; + + /// + /// Initialises a new grid-aware RegionHandle + /// + /// IP Address of the Grid Server for this region + /// Grid X Coordinate + /// Grid Y Coordinate + public RegionHandle(string ip, short x, short y) + { + IPAddress addr = IPAddress.Parse(ip); + + if (addr.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork) + throw new Exception("Bad RegionHandle Parameter - must be an IPv4 address"); + + uint baseHandle = BitConverter.ToUInt32(addr.GetAddressBytes(), 0); + + // Split the IP address in half + short a = (short)((baseHandle << 16) & 0xFFFF); + short b = (short)((baseHandle << 0) & 0xFFFF); + + // Raise the bounds a little + uint nx = (uint)x; + uint ny = (uint)y; + + // Multiply grid coords to get region coords + nx *= 256; + ny *= 256; + + // Stuff the IP address in too + nx = (uint)a << 16; + ny = (uint)b << 16; + + handle = ((UInt64)nx << 32) | (uint)ny; + } + + /// + /// Initialises a new RegionHandle that is not inter-grid aware + /// + /// Grid X Coordinate + /// Grid Y Coordinate + public RegionHandle(uint x, uint y) + { + handle = ((x * 256) << 32) | (y * 256); + } + + /// + /// Initialises a new RegionHandle from an existing value + /// + /// A U64 RegionHandle + public RegionHandle(UInt64 Region) + { + handle = Region; + } + + /// + /// Returns the Grid Masked RegionHandle - For use in Teleport packets and other packets where sending the grid IP address may be handy. + /// + /// Do not use for SimulatorEnable packets. The client will choke. + /// Region Handle including IP Address encoding + public UInt64 getTeleportHandle() + { + return handle; + } + + /// + /// Returns a RegionHandle which may be used for SimulatorEnable packets. Removes the IP address encoding and returns the lower bounds. + /// + /// A U64 RegionHandle for use in SimulatorEnable packets. + public UInt64 getNeighbourHandle() + { + UInt64 mask = 0x0000FFFF0000FFFF; + + return handle | mask; + } + + /// + /// Returns the IP Address of the GridServer from a Grid-Encoded RegionHandle + /// + /// Grid Server IP Address + public IPAddress getGridIP() + { + uint a = (uint)((handle >> 16) & 0xFFFF); + uint b = (uint)((handle >> 48) & 0xFFFF); + + return new IPAddress((long)(a << 16) | (long)b); + } + + /// + /// Returns the X Coordinate from a Grid-Encoded RegionHandle + /// + /// X Coordinate + public uint getGridX() + { + uint x = (uint)((handle >> 32) & 0xFFFF); + + return x; + } + + /// + /// Returns the Y Coordinate from a Grid-Encoded RegionHandle + /// + /// Y Coordinate + public uint getGridY() + { + uint y = (uint)((handle >> 0) & 0xFFFF); + + return y; + } + } +} diff --git a/OpenSim/Framework/General/Types/RegionInfo.cs b/OpenSim/Framework/General/Types/RegionInfo.cs new file mode 100644 index 0000000000..492ed4dd99 --- /dev/null +++ b/OpenSim/Framework/General/Types/RegionInfo.cs @@ -0,0 +1,280 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Globalization; +using System.Net; +using System.Net.Sockets; +using Nini.Config; +using libsecondlife; +using OpenSim.Framework.Console; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Utilities; + +using OpenSim.Framework.Configuration; + + +namespace OpenSim.Framework.Types +{ + public class RegionInfo + { + public LLUUID SimUUID = new LLUUID(); + public string RegionName = ""; + + private IPEndPoint m_internalEndPoint; + public IPEndPoint InternalEndPoint + { + get + { + return m_internalEndPoint; + } + } + + public IPEndPoint ExternalEndPoint + { + get + { + // Old one defaults to IPv6 + //return new IPEndPoint( Dns.GetHostAddresses( m_externalHostName )[0], m_internalEndPoint.Port ); + + // New method favors IPv4 + IPAddress ia = null; + foreach (IPAddress Adr in Dns.GetHostAddresses(m_externalHostName)) + { + if (ia == null) + ia = Adr; + + if (Adr.AddressFamily == AddressFamily.InterNetwork) + { + ia = Adr; + break; + } + + } + + return new IPEndPoint(ia, m_internalEndPoint.Port); + } + } + + private string m_externalHostName; + public string ExternalHostName + { + get + { + return m_externalHostName; + } + } + + private uint? m_regionLocX; + public uint RegionLocX + { + get + { + return m_regionLocX.Value; + } + } + + private uint? m_regionLocY; + public uint RegionLocY + { + get + { + return m_regionLocY.Value; + } + } + + private ulong? m_regionHandle; + public ulong RegionHandle + { + get + { + if (!m_regionHandle.HasValue) + { + m_regionHandle = Util.UIntsToLong((RegionLocX * 256), (RegionLocY * 256)); + } + + return m_regionHandle.Value; + } + } + + private uint m_remotingPort; + public uint RemotingPort + { + get + { + return m_remotingPort; + } + set + { + m_remotingPort = value; + } + } + public string RemotingAddress; + + public string DataStore = ""; + public bool isSandbox = false; + + public LLUUID MasterAvatarAssignedUUID = new LLUUID(); + public string MasterAvatarFirstName = ""; + public string MasterAvatarLastName = ""; + public string MasterAvatarSandboxPassword = ""; + + public EstateSettings estateSettings; + + public ConfigurationMember configMember; + public RegionInfo(string description, string filename) + { + estateSettings = new EstateSettings(); + configMember = new ConfigurationMember(filename, description, loadConfigurationOptions, handleIncomingConfiguration); + configMember.performConfigurationRetrieve(); + } + + public RegionInfo(uint regionLocX, uint regionLocY, IPEndPoint internalEndPoint, string externalUri) + { + + estateSettings = new EstateSettings(); + m_regionLocX = regionLocX; + m_regionLocY = regionLocY; + + m_internalEndPoint = internalEndPoint; + m_externalHostName = externalUri; + } + + public void LoadFromNiniSource(IConfigSource source) + { + this.LoadFromNiniSource(source, "RegionInfo"); + } + + public void LoadFromNiniSource(IConfigSource source, string sectionName) + { + string errorMessage = ""; + this.SimUUID = new LLUUID(source.Configs[sectionName].GetString("sim_UUID", LLUUID.Random().ToStringHyphenated())); + this.RegionName = source.Configs[sectionName].GetString("sim_name", "OpenSim Test"); + this.m_regionLocX = Convert.ToUInt32(source.Configs[sectionName].GetString("sim_location_x", "1000")); + this.m_regionLocY = Convert.ToUInt32(source.Configs[sectionName].GetString("sim_location_y", "1000")); + this.DataStore = source.Configs[sectionName].GetString("datastore", "OpenSim.db"); + + string ipAddress = source.Configs[sectionName].GetString("internal_ip_address", "0.0.0.0"); + IPAddress ipAddressResult; + if (IPAddress.TryParse(ipAddress, out ipAddressResult)) + { + this.m_internalEndPoint = new IPEndPoint(ipAddressResult, 0); + } + else + { + errorMessage = "needs an IP Address (IPAddress)"; + } + this.m_internalEndPoint.Port = source.Configs[sectionName].GetInt("internal_ip_port",(int) 9000); + + string externalHost = source.Configs[sectionName].GetString("external_host_name", "127.0.0.1"); + if (externalHost != "SYSTEMIP") + { + this.m_externalHostName = externalHost; + } + else + { + this.m_externalHostName = Util.GetLocalHost().ToString(); + } + + this.MasterAvatarFirstName = source.Configs[sectionName].GetString("master_avatar_first", "Test"); + this.MasterAvatarLastName = source.Configs[sectionName].GetString("master_avatar_last", "User"); + this.MasterAvatarSandboxPassword = source.Configs[sectionName].GetString("master_avatar_pass", "test"); + + if (errorMessage != "") + { + // a error + } + } + + public void loadConfigurationOptions() + { + configMember.addConfigurationOption("sim_UUID", ConfigurationOption.ConfigurationTypes.TYPE_LLUUID, "UUID of Simulator (Default is recommended, random UUID)", LLUUID.Random().ToString(), true); + configMember.addConfigurationOption("sim_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Simulator Name", "OpenSim Test", false); + configMember.addConfigurationOption("sim_location_x", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, "Grid Location (X Axis)", "1000", false); + configMember.addConfigurationOption("sim_location_y", ConfigurationOption.ConfigurationTypes.TYPE_UINT32, "Grid Location (Y Axis)", "1000", false); + configMember.addConfigurationOption("datastore", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Filename for local storage", "localworld.yap", false); + configMember.addConfigurationOption("internal_ip_address", ConfigurationOption.ConfigurationTypes.TYPE_IP_ADDRESS, "Internal IP Address for incoming UDP client connections", "0.0.0.0", false); + configMember.addConfigurationOption("internal_ip_port", ConfigurationOption.ConfigurationTypes.TYPE_INT32, "Internal IP Port for incoming UDP client connections", "9000", false); + configMember.addConfigurationOption("external_host_name", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "External Host Name", "127.0.0.1", false); + configMember.addConfigurationOption("master_avatar_first", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "First Name of Master Avatar", "Test", false); + configMember.addConfigurationOption("master_avatar_last", ConfigurationOption.ConfigurationTypes.TYPE_STRING_NOT_EMPTY, "Last Name of Master Avatar", "User", false); + configMember.addConfigurationOption("master_avatar_pass", ConfigurationOption.ConfigurationTypes.TYPE_STRING, "(Sandbox Mode Only)Password for Master Avatar account", "test", false); + + } + + public bool handleIncomingConfiguration(string configuration_key, object configuration_result) + { + switch (configuration_key) + { + case "sim_UUID": + this.SimUUID = (LLUUID)configuration_result; + break; + case "sim_name": + this.RegionName = (string)configuration_result; + break; + case "sim_location_x": + this.m_regionLocX = (uint)configuration_result; + break; + case "sim_location_y": + this.m_regionLocY = (uint)configuration_result; + break; + case "datastore": + this.DataStore = (string)configuration_result; + break; + case "internal_ip_address": + IPAddress address = (IPAddress)configuration_result; + this.m_internalEndPoint = new IPEndPoint(address, 0); + break; + case "internal_ip_port": + this.m_internalEndPoint.Port = (int)configuration_result; + break; + case "external_host_name": + if ((string)configuration_result != "SYSTEMIP") + { + this.m_externalHostName = (string)configuration_result; + } + else + { + this.m_externalHostName = Util.GetLocalHost().ToString(); + } + break; + case "master_avatar_first": + this.MasterAvatarFirstName = (string)configuration_result; + break; + case "master_avatar_last": + this.MasterAvatarLastName = (string)configuration_result; + break; + case "master_avatar_pass": + this.MasterAvatarSandboxPassword = (string)configuration_result; + break; + } + + return true; + } + + } +} diff --git a/OpenSim/Framework/General/Types/UUID.cs b/OpenSim/Framework/General/Types/UUID.cs new file mode 100644 index 0000000000..9cde18e5f8 --- /dev/null +++ b/OpenSim/Framework/General/Types/UUID.cs @@ -0,0 +1,127 @@ +using System; +using libsecondlife; + +namespace OpenSim.Framework.Types +{ + class UUID + { + public LLUUID llUUID; + + public UUID(string uuid) + { + llUUID = new LLUUID(uuid); + } + + public UUID(byte[] uuid) + { + llUUID = new LLUUID(uuid, 0); + } + + public UUID(byte[] uuid, int offset) + { + llUUID = new LLUUID(uuid, offset); + } + + public UUID() + { + llUUID = LLUUID.Zero; + } + + public UUID(ulong uuid) + { + llUUID = new LLUUID(uuid); + } + + public UUID(UInt32 first, UInt32 second, UInt32 third, UInt32 fourth) + { + byte[] uuid = new byte[16]; + + byte[] n = BitConverter.GetBytes(first); + n.CopyTo(uuid, 0); + n = BitConverter.GetBytes(second); + n.CopyTo(uuid, 4); + n = BitConverter.GetBytes(third); + n.CopyTo(uuid, 8); + n = BitConverter.GetBytes(fourth); + n.CopyTo(uuid, 12); + + llUUID = new LLUUID(uuid,0); + } + + public override string ToString() + { + return llUUID.ToString(); + } + + public string ToStringHyphenated() + { + return llUUID.ToStringHyphenated(); + } + + public byte[] GetBytes() + { + return llUUID.GetBytes(); + } + + public UInt32[] GetInts() + { + UInt32[] ints = new UInt32[4]; + ints[0] = BitConverter.ToUInt32(llUUID.Data, 0); + ints[1] = BitConverter.ToUInt32(llUUID.Data, 4); + ints[2] = BitConverter.ToUInt32(llUUID.Data, 8); + ints[3] = BitConverter.ToUInt32(llUUID.Data, 12); + + return ints; + } + + public LLUUID GetLLUUID() + { + return llUUID; + } + + public uint CRC() + { + return llUUID.CRC(); + } + + public override int GetHashCode() + { + return llUUID.GetHashCode(); + } + + public void Combine(UUID other) + { + llUUID.Combine(other.GetLLUUID()); + } + + public void Combine(LLUUID other) + { + llUUID.Combine(other); + } + + public override bool Equals(Object other) + { + return llUUID.Equals(other); + } + + public static bool operator ==(UUID a, UUID b) + { + return a.llUUID.Equals(b.GetLLUUID()); + } + + public static bool operator !=(UUID a, UUID b) + { + return !a.llUUID.Equals(b.GetLLUUID()); + } + + public static bool operator ==(UUID a, LLUUID b) + { + return a.Equals(b); + } + + public static bool operator !=(UUID a, LLUUID b) + { + return !a.Equals(b); + } + } +} diff --git a/OpenSim/Framework/General/UserProfile.cs b/OpenSim/Framework/General/UserProfile.cs new file mode 100644 index 0000000000..243208a422 --- /dev/null +++ b/OpenSim/Framework/General/UserProfile.cs @@ -0,0 +1,87 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Collections.Generic; +using System.Security.Cryptography; +using libsecondlife; +using OpenSim.Framework.Inventory; + +namespace OpenSim.Framework.User +{ + public class UserProfile + { + + public string firstname; + public string lastname; + public ulong homeregionhandle; + public LLVector3 homepos; + public LLVector3 homelookat; + + public bool IsGridGod = false; + public bool IsLocal = true; // will be used in future for visitors from foreign grids + public string AssetURL; + public string MD5passwd; + + public LLUUID CurrentSessionID; + public LLUUID CurrentSecureSessionID; + public LLUUID UUID; + public Dictionary Circuits = new Dictionary(); // tracks circuit codes + + public AgentInventory Inventory; + + public UserProfile() + { + Circuits = new Dictionary(); + Inventory = new AgentInventory(); + homeregionhandle = Helpers.UIntsToLong((1000 * 256), (1000 * 256)); + homepos = new LLVector3(); + homelookat = new LLVector3(); + } + + public void InitSessionData() + { + RNGCryptoServiceProvider rand = new RNGCryptoServiceProvider(); + + byte[] randDataS = new byte[16]; + byte[] randDataSS = new byte[16]; + + rand.GetBytes(randDataS); + rand.GetBytes(randDataSS); + + CurrentSecureSessionID = new LLUUID(randDataSS,0); + CurrentSessionID = new LLUUID(randDataS,0); + + } + + public void AddSimCircuit(uint circuitCode, LLUUID regionUUID) + { + if (this.Circuits.ContainsKey(regionUUID) == false) + this.Circuits.Add(regionUUID, circuitCode); + } + + } +} diff --git a/OpenSim/Framework/General/Util.cs b/OpenSim/Framework/General/Util.cs new file mode 100644 index 0000000000..b4cee6105c --- /dev/null +++ b/OpenSim/Framework/General/Util.cs @@ -0,0 +1,365 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.IO; +using System.Security.Cryptography; +using System.Net; +using System.Text; +using libsecondlife; + +using Nini.Config; + +namespace OpenSim.Framework.Utilities +{ + public class Util + { + private static Random randomClass = new Random(); + private static uint nextXferID = 5000; + private static object XferLock = new object(); + private static Dictionary capsURLS = new Dictionary(); + + public static ulong UIntsToLong(uint X, uint Y) + { + return Helpers.UIntsToLong(X, Y); + } + + public static Random RandomClass + { + get + { + return randomClass; + } + } + + public static uint GetNextXferID() + { + uint id = 0; + lock(XferLock) + { + id = nextXferID; + nextXferID++; + } + return id; + } + + public Util() + { + + } + + public static string GetFileName(string file) + { + // Return just the filename on UNIX platforms + // TODO: this should be customisable with a prefix, but that's something to do later. + if (System.Environment.OSVersion.Platform == PlatformID.Unix) + { + return file; + } + + // Return %APPDATA%/OpenSim/file for 2K/XP/NT/2K3/VISTA + // TODO: Switch this to System.Enviroment.SpecialFolders.ApplicationData + if (System.Environment.OSVersion.Platform == PlatformID.Win32NT) + { + if (!System.IO.Directory.Exists("%APPDATA%\\OpenSim\\")) + { + System.IO.Directory.CreateDirectory("%APPDATA%\\OpenSim"); + } + + return "%APPDATA%\\OpenSim\\" + file; + } + + // Catch all - covers older windows versions + // (but those probably wont work anyway) + return file; + } + + public static bool IsEnvironmentSupported(ref string reason) + { + // Must have .NET 2.0 (Generics / libsl) + if (System.Environment.Version.Major < 2) + { + reason = ".NET 1.0/1.1 lacks components that is used by OpenSim"; + return false; + } + + // Windows 95/98/ME are unsupported + if (System.Environment.OSVersion.Platform == PlatformID.Win32Windows && + System.Environment.OSVersion.Platform != PlatformID.Win32NT) + { + reason = "Windows 95/98/ME will not run OpenSim"; + return false; + } + + // Windows 2000 / Pre-SP2 XP + if (System.Environment.OSVersion.Version.Major == 5 && ( + System.Environment.OSVersion.Version.Minor == 0)) + { + reason = "Please update to Windows XP Service Pack 2 or Server2003"; + return false; + } + + return true; + } + + public static int UnixTimeSinceEpoch() + { + TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1)); + int timestamp = (int)t.TotalSeconds; + return timestamp; + } + + public static string Md5Hash(string pass) + { + MD5 md5 = MD5CryptoServiceProvider.Create(); + byte[] dataMd5 = md5.ComputeHash(Encoding.Default.GetBytes(pass)); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < dataMd5.Length; i++) + sb.AppendFormat("{0:x2}", dataMd5[i]); + return sb.ToString(); + } + + public static string GetRandomCapsPath() + { + LLUUID caps = LLUUID.Random(); + string capsPath = caps.ToStringHyphenated(); + capsPath = capsPath.Remove(capsPath.Length - 4, 4); + return capsPath; + } + + //public static int fast_distance2d(int x, int y) + //{ + // x = System.Math.Abs(x); + // y = System.Math.Abs(y); + + // int min = System.Math.Min(x, y); + + // return (x + y - (min >> 1) - (min >> 2) + (min >> 4)); + //} + + public static string FieldToString(byte[] bytes) + { + return FieldToString(bytes, String.Empty); + } + + /// + /// Convert a variable length field (byte array) to a string, with a + /// field name prepended to each line of the output + /// + /// If the byte array has unprintable characters in it, a + /// hex dump will be put in the string instead + /// The byte array to convert to a string + /// A field name to prepend to each line of output + /// An ASCII string or a string containing a hex dump, minus + /// the null terminator + public static string FieldToString(byte[] bytes, string fieldName) + { + // Check for a common case + if (bytes.Length == 0) return String.Empty; + + StringBuilder output = new StringBuilder(); + bool printable = true; + + for (int i = 0; i < bytes.Length; ++i) + { + // Check if there are any unprintable characters in the array + if ((bytes[i] < 0x20 || bytes[i] > 0x7E) && bytes[i] != 0x09 + && bytes[i] != 0x0D && bytes[i] != 0x0A && bytes[i] != 0x00) + { + printable = false; + break; + } + } + + if (printable) + { + if (fieldName.Length > 0) + { + output.Append(fieldName); + output.Append(": "); + } + + if (bytes[bytes.Length - 1] == 0x00) + output.Append(UTF8Encoding.UTF8.GetString(bytes, 0, bytes.Length - 1)); + else + output.Append(UTF8Encoding.UTF8.GetString(bytes)); + } + else + { + for (int i = 0; i < bytes.Length; i += 16) + { + if (i != 0) + output.Append(Environment.NewLine); + if (fieldName.Length > 0) + { + output.Append(fieldName); + output.Append(": "); + } + + for (int j = 0; j < 16; j++) + { + if ((i + j) < bytes.Length) + output.Append(String.Format("{0:X2} ", bytes[i + j])); + else + output.Append(" "); + } + + for (int j = 0; j < 16 && (i + j) < bytes.Length; j++) + { + if (bytes[i + j] >= 0x20 && bytes[i + j] < 0x7E) + output.Append((char)bytes[i + j]); + else + output.Append("."); + } + } + } + + return output.ToString(); + } + + /// + /// Returns a IP address from a specified DNS, favouring IPv4 addresses. + /// + /// DNS Hostname + /// An IP address, or null + public static IPAddress GetHostFromDNS(string dnsAddress) + { + IPAddress[] hosts = Dns.GetHostEntry(dnsAddress).AddressList; + + foreach (IPAddress host in hosts) + { + if (host.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) + { + return host; + } + } + + if (hosts.Length > 0) + return hosts[0]; + + return null; + } + + public static IPAddress GetLocalHost() + { + string dnsAddress = "localhost"; + + IPAddress[] hosts = Dns.GetHostEntry(dnsAddress).AddressList; + + foreach (IPAddress host in hosts) + { + if (!IPAddress.IsLoopback(host) && host.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) + { + return host; + } + } + + if (hosts.Length > 0) + return hosts[0]; + + return null; + } + + // + // directory locations + // + public static string homeDir() + { + string temp; +// string personal=(Environment.GetFolderPath(Environment.SpecialFolder.Personal)); +// temp = Path.Combine(personal,".OpenSim"); + temp="."; + return temp; + } + + public static string configDir() + { + string temp; + temp = "."; + return temp; + } + + public static string dataDir() + { + string temp; + temp = "."; + return temp; + } + + public static string logDir() + { + string temp; + temp = "."; + return temp; + } + + public static string GetCapsURL(LLUUID userID) + { + if (capsURLS.ContainsKey(userID)) + { + return capsURLS[userID]; + } + return ""; + } + + public static void SetCapsURL(LLUUID userID, string url) + { + if (capsURLS.ContainsKey(userID)) + { + capsURLS[userID] = url; + } + else + { + capsURLS.Add(userID, url); + } + } + + // Nini (config) related Methods + public static IConfigSource ConvertDataRowToXMLConfig(System.Data.DataRow row, string fileName) + { + if(!File.Exists(fileName)) + { + //create new file + } + XmlConfigSource config = new XmlConfigSource(fileName); + AddDataRowToConfig(config, row); + config.Save(); + + return config; + } + + public static void AddDataRowToConfig(IConfigSource config, System.Data.DataRow row) + { + config.Configs.Add((string)row[0]); + for (int i = 0; i < row.Table.Columns.Count; i++) + { + config.Configs[(string)row[0]].Set(row.Table.Columns[i].ColumnName, row[i]); + } + } + } +} diff --git a/OpenSim/Framework/InventoryServiceBase/InventoryServiceBase.cs b/OpenSim/Framework/InventoryServiceBase/InventoryServiceBase.cs new file mode 100644 index 0000000000..9187d624a9 --- /dev/null +++ b/OpenSim/Framework/InventoryServiceBase/InventoryServiceBase.cs @@ -0,0 +1,206 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using libsecondlife; +using OpenSim.Framework.Console; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Data; + +namespace OpenSim.Framework.InventoryServiceBase +{ + public class InventoryServiceBase + { + protected Dictionary m_plugins = new Dictionary(); + //protected IAssetServer m_assetServer; + + public InventoryServiceBase() + { + //m_assetServer = assetServer; + } + + /// + /// Adds a new user server plugin - plugins will be requested in the order they were loaded. + /// + /// The filename to the user server plugin DLL + public void AddPlugin(string FileName) + { + MainLog.Instance.Verbose("Inventory", "Inventorystorage: Attempting to load " + FileName); + Assembly pluginAssembly = Assembly.LoadFrom(FileName); + + foreach (Type pluginType in pluginAssembly.GetTypes()) + { + if (!pluginType.IsAbstract) + { + Type typeInterface = pluginType.GetInterface("IInventoryData", true); + + if (typeInterface != null) + { + IInventoryData plug = (IInventoryData)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); + plug.Initialise(); + this.m_plugins.Add(plug.getName(), plug); + MainLog.Instance.Verbose("Inventorystorage: Added IInventoryData Interface"); + } + + typeInterface = null; + } + } + + pluginAssembly = null; + } + + /// + /// Returns the root folder plus any folders in root (so down one level in the Inventory folders tree) + /// + /// + /// + public List RequestFirstLevelFolders(LLUUID userID) + { + List inventoryList = new List(); + foreach (KeyValuePair plugin in m_plugins) + { + InventoryFolderBase rootFolder = plugin.Value.getUserRootFolder(userID); + if (rootFolder != null) + { + inventoryList = plugin.Value.getInventoryFolders(rootFolder.folderID); + inventoryList.Insert(0, rootFolder); + return inventoryList; + } + } + return inventoryList; + } + + /// + /// + /// + public InventoryFolderBase RequestUsersRoot(LLUUID userID) + { + foreach (KeyValuePair plugin in m_plugins) + { + return plugin.Value.getUserRootFolder(userID); + } + return null; + } + + /// + /// + /// + /// + /// + public List RequestSubFolders(LLUUID parentFolderID) + { + List inventoryList = new List(); + foreach (KeyValuePair plugin in m_plugins) + { + return plugin.Value.getInventoryFolders(parentFolderID); + } + return inventoryList; + } + + public List RequestFolderItems(LLUUID folderID) + { + List itemsList = new List(); + foreach (KeyValuePair plugin in m_plugins) + { + itemsList = plugin.Value.getInventoryInFolder(folderID); + return itemsList; + } + return itemsList; + } + + public void AddFolder(InventoryFolderBase folder) + { + foreach (KeyValuePair plugin in m_plugins) + { + plugin.Value.addInventoryFolder(folder); + } + } + + public void AddItem(InventoryItemBase item) + { + foreach (KeyValuePair plugin in m_plugins) + { + plugin.Value.addInventoryItem(item); + } + } + + public void deleteItem(InventoryItemBase item) + { + foreach (KeyValuePair plugin in m_plugins) + { + plugin.Value.deleteInventoryItem(item); + } + } + + /// + /// + /// + /// + public void AddNewInventorySet(UsersInventory inventory) + { + foreach (InventoryFolderBase folder in inventory.Folders.Values) + { + this.AddFolder(folder); + } + } + + public void CreateNewUserInventory(LLUUID user) + { + UsersInventory inven = new UsersInventory(); + inven.CreateNewInventorySet(user); + this.AddNewInventorySet(inven); + } + + public class UsersInventory + { + public Dictionary Folders = new Dictionary(); + public Dictionary Items = new Dictionary(); + + public UsersInventory() + { + + } + + public virtual void CreateNewInventorySet(LLUUID user) + { + InventoryFolderBase folder = new InventoryFolderBase(); + folder.parentID = LLUUID.Zero; + folder.agentID = user; + folder.folderID = LLUUID.Random(); + folder.name = "My Inventory"; + folder.type = 8; + folder.version = 1; + Folders.Add(folder.folderID, folder); + + LLUUID rootFolder = folder.folderID; + + folder = new InventoryFolderBase(); + folder.parentID = rootFolder; + folder.agentID = user; + folder.folderID = LLUUID.Random(); + folder.name = "Textures"; + folder.type = 0; + folder.version = 1; + Folders.Add(folder.folderID, folder); + + folder = new InventoryFolderBase(); + folder.parentID = rootFolder; + folder.agentID = user; + folder.folderID = LLUUID.Random(); + folder.name = "Objects"; + folder.type = 6; + folder.version = 1; + Folders.Add(folder.folderID, folder); + + folder = new InventoryFolderBase(); + folder.parentID = rootFolder; + folder.agentID = user; + folder.folderID = LLUUID.Random(); + folder.name = "Clothes"; + folder.type = 5; + folder.version = 1; + Folders.Add(folder.folderID, folder); + } + } + } +} \ No newline at end of file diff --git a/OpenSim/Framework/InventoryServiceBase/Properties/AssemblyInfo.cs b/OpenSim/Framework/InventoryServiceBase/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..35cca0728e --- /dev/null +++ b/OpenSim/Framework/InventoryServiceBase/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("InventoryServiceBase")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("InventoryServiceBase")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("7e1fbd0b-4a25-4804-a01f-89b04eb5b349")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Framework/Servers/BaseHttpServer.cs b/OpenSim/Framework/Servers/BaseHttpServer.cs new file mode 100644 index 0000000000..f1c7798ba2 --- /dev/null +++ b/OpenSim/Framework/Servers/BaseHttpServer.cs @@ -0,0 +1,229 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using Nwc.XmlRpc; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.Servers +{ + public class BaseHttpServer + { + protected Thread m_workerThread; + protected HttpListener m_httpListener; + protected Dictionary m_rpcHandlers = new Dictionary(); + protected Dictionary m_streamHandlers = new Dictionary(); + protected int m_port; + protected bool m_firstcaps = true; + + public int Port + { + get { return m_port; } + } + + public BaseHttpServer(int port) + { + m_port = port; + } + + public void AddStreamHandler( IStreamHandler handler) + { + string httpMethod = handler.HttpMethod; + string path = handler.Path; + + string handlerKey = GetHandlerKey(httpMethod, path); + m_streamHandlers.Add(handlerKey, handler); + } + + private static string GetHandlerKey(string httpMethod, string path) + { + return httpMethod + ":" + path; + } + + public bool AddXmlRPCHandler(string method, XmlRpcMethod handler) + { + if (!this.m_rpcHandlers.ContainsKey(method)) + { + this.m_rpcHandlers.Add(method, handler); + return true; + } + + //must already have a handler for that path so return false + return false; + } + + + public virtual void HandleRequest(Object stateinfo) + { + HttpListenerContext context = (HttpListenerContext)stateinfo; + + HttpListenerRequest request = context.Request; + HttpListenerResponse response = context.Response; + + response.KeepAlive = false; + response.SendChunked = false; + + string path = request.RawUrl; + string handlerKey = GetHandlerKey( request.HttpMethod, path ); + + IStreamHandler streamHandler; + + if (TryGetStreamHandler( handlerKey, out streamHandler)) + { + byte[] buffer = streamHandler.Handle(path, request.InputStream); + request.InputStream.Close(); + + response.ContentType = streamHandler.ContentType; + response.ContentLength64 = buffer.LongLength; + response.OutputStream.Write(buffer, 0, buffer.Length); + response.OutputStream.Close(); + } + else + { + HandleXmlRpcRequests(request, response); + } + } + + private bool TryGetStreamHandler(string handlerKey, out IStreamHandler streamHandler) + { + string bestMatch = null; + + foreach (string pattern in m_streamHandlers.Keys) + { + if (handlerKey.StartsWith(pattern)) + { + if (String.IsNullOrEmpty(bestMatch) || pattern.Length > bestMatch.Length) + { + bestMatch = pattern; + } + } + } + + if (String.IsNullOrEmpty(bestMatch)) + { + streamHandler = null; + return false; + } + else + { + streamHandler = m_streamHandlers[bestMatch]; + return true; + } + } + + private void HandleXmlRpcRequests(HttpListenerRequest request, HttpListenerResponse response) + { + Stream requestStream = request.InputStream; + + Encoding encoding = Encoding.UTF8; + StreamReader reader = new StreamReader(requestStream, encoding); + + string requestBody = reader.ReadToEnd(); + reader.Close(); + requestStream.Close(); + + XmlRpcRequest xmlRprcRequest = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(requestBody); + + string methodName = xmlRprcRequest.MethodName; + + XmlRpcResponse xmlRpcResponse; + + XmlRpcMethod method; + if (this.m_rpcHandlers.TryGetValue(methodName, out method)) + { + xmlRpcResponse = method(xmlRprcRequest); + } + else + { + xmlRpcResponse = new XmlRpcResponse(); + Hashtable unknownMethodError = new Hashtable(); + unknownMethodError["reason"] = "XmlRequest"; ; + unknownMethodError["message"] = "Unknown Rpc Request ["+methodName+"]"; + unknownMethodError["login"] = "false"; + xmlRpcResponse.Value = unknownMethodError; + } + + response.AddHeader("Content-type", "text/xml"); + + string responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse); + + byte[] buffer = Encoding.UTF8.GetBytes(responseString); + + response.SendChunked = false; + response.ContentLength64 = buffer.Length; + response.ContentEncoding = Encoding.UTF8; + + response.OutputStream.Write(buffer, 0, buffer.Length); + response.OutputStream.Close(); + } + + public void Start() + { + MainLog.Instance.Verbose("HTTPD", "Starting up HTTP Server"); + + m_workerThread = new Thread(new ThreadStart(StartHTTP)); + m_workerThread.IsBackground = true; + m_workerThread.Start(); + } + + private void StartHTTP() + { + try + { + MainLog.Instance.Status("HTTPD", "Spawned main thread OK"); + m_httpListener = new HttpListener(); + + m_httpListener.Prefixes.Add("http://+:" + m_port + "/"); + m_httpListener.Start(); + + HttpListenerContext context; + while (true) + { + context = m_httpListener.GetContext(); + ThreadPool.QueueUserWorkItem(new WaitCallback(HandleRequest), context); + } + } + catch (Exception e) + { + MainLog.Instance.Warn("HTTPD", "Error - " + e.Message); + } + } + + + public void RemoveStreamHandler(string httpMethod, string path) + { + m_streamHandlers.Remove(GetHandlerKey(httpMethod, path)); + } + } +} diff --git a/OpenSim/Framework/Servers/BaseStreamHandler.cs b/OpenSim/Framework/Servers/BaseStreamHandler.cs new file mode 100644 index 0000000000..0d9c674400 --- /dev/null +++ b/OpenSim/Framework/Servers/BaseStreamHandler.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace OpenSim.Framework.Servers +{ + public abstract class BaseStreamHandler : IStreamHandler + { + virtual public string ContentType + { + get { return "application/xml"; } + } + + private string m_httpMethod; + virtual public string HttpMethod + { + get { return m_httpMethod; } + } + + private string m_path; + virtual public string Path + { + get { return m_path; } + } + + protected string GetParam( string path ) + { + return path.Substring( m_path.Length ); + } + + public abstract byte[] Handle(string path, Stream request); + + protected BaseStreamHandler(string httpMethod, string path) + { + m_httpMethod = httpMethod; + m_path = path; + } + } +} diff --git a/OpenSim/Framework/Servers/BinaryStreamHandler.cs b/OpenSim/Framework/Servers/BinaryStreamHandler.cs new file mode 100644 index 0000000000..7d4e4ce199 --- /dev/null +++ b/OpenSim/Framework/Servers/BinaryStreamHandler.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace OpenSim.Framework.Servers +{ + public delegate string BinaryMethod(byte[] data, string path, string param); + + public class BinaryStreamHandler : BaseStreamHandler + { + BinaryMethod m_method; + + override public byte[] Handle(string path, Stream request) + { + byte[] data = ReadFully(request); + string param = GetParam(path); + string responseString = m_method(data, path, param); + + return Encoding.UTF8.GetBytes(responseString); + } + + public BinaryStreamHandler(string httpMethod, string path, BinaryMethod binaryMethod) + : base(httpMethod, path) + { + m_method = binaryMethod; + } + + private byte[] ReadFully(Stream stream) + { + byte[] buffer = new byte[32768]; + using (MemoryStream ms = new MemoryStream()) + { + while (true) + { + int read = stream.Read(buffer, 0, buffer.Length); + + if (read <= 0) + { + return ms.ToArray(); + } + + ms.Write(buffer, 0, read); + } + } + } + } + +} diff --git a/OpenSim/Framework/Servers/CheckSumServer.cs b/OpenSim/Framework/Servers/CheckSumServer.cs new file mode 100644 index 0000000000..89ec095239 --- /dev/null +++ b/OpenSim/Framework/Servers/CheckSumServer.cs @@ -0,0 +1,127 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +namespace OpenSim.Framework.Servers +{/* + public class CheckSumServer : UDPServerBase + { + //protected ConsoleBase m_log; + + public CheckSumServer(int port) + : base(port) + { + } + + protected override void OnReceivedData(IAsyncResult result) + { + ipeSender = new IPEndPoint(IPAddress.Any, 0); + epSender = (EndPoint)ipeSender; + Packet packet = null; + int numBytes = Server.EndReceiveFrom(result, ref epSender); + int packetEnd = numBytes - 1; + + packet = Packet.BuildPacket(RecvBuffer, ref packetEnd, ZeroBuffer); + + if (packet.Type == PacketType.SecuredTemplateChecksumRequest) + { + SecuredTemplateChecksumRequestPacket checksum = (SecuredTemplateChecksumRequestPacket)packet; + TemplateChecksumReplyPacket checkreply = new TemplateChecksumReplyPacket(); + checkreply.DataBlock.Checksum = 3220703154;//180572585; + checkreply.DataBlock.Flags = 0; + checkreply.DataBlock.MajorVersion = 1; + checkreply.DataBlock.MinorVersion = 15; + checkreply.DataBlock.PatchVersion = 0; + checkreply.DataBlock.ServerVersion = 0; + checkreply.TokenBlock.Token = checksum.TokenBlock.Token; + this.SendPacket(checkreply, epSender); + + /* + //if we wanted to echo the the checksum/ version from the client (so that any client worked) + SecuredTemplateChecksumRequestPacket checkrequest = new SecuredTemplateChecksumRequestPacket(); + checkrequest.TokenBlock.Token = checksum.TokenBlock.Token; + this.SendPacket(checkrequest, epSender); + + } + else if (packet.Type == PacketType.TemplateChecksumReply) + { + //echo back the client checksum reply (Hegemon's method) + TemplateChecksumReplyPacket checksum2 = (TemplateChecksumReplyPacket)packet; + TemplateChecksumReplyPacket checkreply2 = new TemplateChecksumReplyPacket(); + checkreply2.DataBlock.Checksum = checksum2.DataBlock.Checksum; + checkreply2.DataBlock.Flags = checksum2.DataBlock.Flags; + checkreply2.DataBlock.MajorVersion = checksum2.DataBlock.MajorVersion; + checkreply2.DataBlock.MinorVersion = checksum2.DataBlock.MinorVersion; + checkreply2.DataBlock.PatchVersion = checksum2.DataBlock.PatchVersion; + checkreply2.DataBlock.ServerVersion = checksum2.DataBlock.ServerVersion; + checkreply2.TokenBlock.Token = checksum2.TokenBlock.Token; + this.SendPacket(checkreply2, epSender); + } + else + { + } + + Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); + } + + private void SendPacket(Packet Pack, EndPoint endp) + { + if (!Pack.Header.Resent) + { + Pack.Header.Sequence = 1; + } + + byte[] ZeroOutBuffer = new byte[4096]; + byte[] sendbuffer; + sendbuffer = Pack.ToBytes(); + + try + { + if (Pack.Header.Zerocoded) + { + int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer); + this.SendPackTo(ZeroOutBuffer, packetsize, SocketFlags.None, endp); + } + else + { + this.SendPackTo(sendbuffer, sendbuffer.Length, SocketFlags.None, endp); + } + } + catch (Exception) + { + OpenSim.Framework.Console.MainLog.Instance.Warn("OpenSimClient.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection "); + + } + } + + private void SendPackTo(byte[] buffer, int size, SocketFlags flags, EndPoint endp) + { + this.Server.SendTo(buffer, size, flags, endp); + } + * } + */ + +} \ No newline at end of file diff --git a/OpenSim/Framework/Servers/IStreamHandler.cs b/OpenSim/Framework/Servers/IStreamHandler.cs new file mode 100644 index 0000000000..6cab40d06c --- /dev/null +++ b/OpenSim/Framework/Servers/IStreamHandler.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace OpenSim.Framework.Servers +{ + public interface IStreamHandler + { + // Handle request stream, return byte array + byte[] Handle(string path, Stream request ); + + // Return response content type + string ContentType { get; } + + // Return required http method + string HttpMethod { get;} + + // Return path + string Path { get; } + } +} diff --git a/OpenSim/Framework/Servers/RestMethod.cs b/OpenSim/Framework/Servers/RestMethod.cs new file mode 100644 index 0000000000..c6cb230c93 --- /dev/null +++ b/OpenSim/Framework/Servers/RestMethod.cs @@ -0,0 +1,31 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +namespace OpenSim.Framework.Servers +{ + public delegate string RestMethod( string request, string path, string param ); +} diff --git a/OpenSim/Framework/Servers/RestStreamHandler.cs b/OpenSim/Framework/Servers/RestStreamHandler.cs new file mode 100644 index 0000000000..1b3b41c87a --- /dev/null +++ b/OpenSim/Framework/Servers/RestStreamHandler.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace OpenSim.Framework.Servers +{ + public class RestStreamHandler : BaseStreamHandler + { + RestMethod m_restMethod; + + override public byte[] Handle(string path, Stream request ) + { + Encoding encoding = Encoding.UTF8; + StreamReader streamReader = new StreamReader(request, encoding); + + string requestBody = streamReader.ReadToEnd(); + streamReader.Close(); + + string param = GetParam(path); + string responseString = m_restMethod(requestBody, path, param ); + + return Encoding.UTF8.GetBytes(responseString); + } + + public RestStreamHandler(string httpMethod, string path, RestMethod restMethod) : base( httpMethod, path ) + { + m_restMethod = restMethod; + } + } +} diff --git a/OpenSim/Framework/Servers/UDPServerBase.cs b/OpenSim/Framework/Servers/UDPServerBase.cs new file mode 100644 index 0000000000..508eb9d365 --- /dev/null +++ b/OpenSim/Framework/Servers/UDPServerBase.cs @@ -0,0 +1,87 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Net; +using System.Net.Sockets; +using libsecondlife.Packets; + +namespace OpenSim.Framework.Servers +{ + public class UDPServerBase + { + public Socket Server; + protected IPEndPoint ServerIncoming; + protected byte[] RecvBuffer = new byte[4096]; + protected byte[] ZeroBuffer = new byte[8192]; + protected IPEndPoint ipeSender; + protected EndPoint epSender; + protected AsyncCallback ReceivedData; + protected int listenPort; + + public UDPServerBase(int port) + { + listenPort = port; + } + + protected virtual void OnReceivedData(IAsyncResult result) + { + ipeSender = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0); + epSender = (EndPoint)ipeSender; + Packet packet = null; + int numBytes = Server.EndReceiveFrom(result, ref epSender); + int packetEnd = numBytes - 1; + + packet = Packet.BuildPacket(RecvBuffer, ref packetEnd, ZeroBuffer); + + Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); + } + + protected virtual void AddNewClient(Packet packet) + { + } + + public virtual void ServerListener() + { + + ServerIncoming = new IPEndPoint(IPAddress.Parse("0.0.0.0"), listenPort); + Server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + Server.Bind(ServerIncoming); + + ipeSender = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0); + epSender = (EndPoint)ipeSender; + ReceivedData = new AsyncCallback(this.OnReceivedData); + Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); + } + + public virtual void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode) + { + + } + } +} + diff --git a/OpenSim/Framework/Servers/XmlRpcMethod.cs b/OpenSim/Framework/Servers/XmlRpcMethod.cs new file mode 100644 index 0000000000..b76ac51e72 --- /dev/null +++ b/OpenSim/Framework/Servers/XmlRpcMethod.cs @@ -0,0 +1,33 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 Nwc.XmlRpc; + +namespace OpenSim.Framework.Servers +{ + public delegate XmlRpcResponse XmlRpcMethod( XmlRpcRequest request ); +} diff --git a/OpenSim/Framework/UserManager/CAPSService.cs b/OpenSim/Framework/UserManager/CAPSService.cs new file mode 100644 index 0000000000..39af140e3e --- /dev/null +++ b/OpenSim/Framework/UserManager/CAPSService.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using System.Security.Cryptography; +using libsecondlife; +using Nwc.XmlRpc; +using OpenSim.Framework.Console; +using OpenSim.Framework.Data; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Inventory; +using OpenSim.Framework.Utilities; +using OpenSim.Framework.Servers; + +namespace OpenSim.Framework.UserManagement +{ + public class CAPSService + { + private BaseHttpServer m_server; + + public CAPSService(BaseHttpServer httpServer) + { + m_server = httpServer; + this.AddCapsSeedHandler("/CapsSeed/", CapsRequest); + } + + private void AddCapsSeedHandler(string path, RestMethod restMethod) + { + m_server.AddStreamHandler(new RestStreamHandler("POST", path, restMethod)); + } + + public string CapsRequest(string request, string path, string param) + { + System.Console.WriteLine("new caps request " + request +" from path "+ path); + return ""; + } + } +} diff --git a/OpenSim/Framework/UserManager/LoginResponse.cs b/OpenSim/Framework/UserManager/LoginResponse.cs new file mode 100644 index 0000000000..65ad3390e7 --- /dev/null +++ b/OpenSim/Framework/UserManager/LoginResponse.cs @@ -0,0 +1,667 @@ +using System; +using System.Collections; +using libsecondlife; +using Nwc.XmlRpc; +using OpenSim.Framework.Console; + +namespace OpenSim.Framework.UserManagement +{ + + /// + /// A temp class to handle login response. + /// Should make use of UserProfileManager where possible. + /// + + public class LoginResponse + { + private Hashtable loginFlagsHash; + private Hashtable globalTexturesHash; + private Hashtable loginError; + private Hashtable uiConfigHash; + + private ArrayList loginFlags; + private ArrayList globalTextures; + private ArrayList eventCategories; + private ArrayList uiConfig; + private ArrayList classifiedCategories; + private ArrayList inventoryRoot; + private ArrayList initialOutfit; + private ArrayList agentInventory; + private ArrayList inventoryLibraryOwner; + private ArrayList inventoryLibrary; + + private UserInfo userProfile; + + private LLUUID agentID; + private LLUUID sessionID; + private LLUUID secureSessionID; + + // Login Flags + private string dst; + private string stipendSinceLogin; + private string gendered; + private string everLoggedIn; + private string login; + private int simPort; + private string simAddress; + private string agentAccess; + private Int32 circuitCode; + private uint regionX; + private uint regionY; + + // Login + private string firstname; + private string lastname; + + // Global Textures + private string sunTexture; + private string cloudTexture; + private string moonTexture; + + // Error Flags + private string errorReason; + private string errorMessage; + + // Response + private XmlRpcResponse xmlRpcResponse; + private XmlRpcResponse defaultXmlRpcResponse; + + private string welcomeMessage; + private string startLocation; + private string allowFirstLife; + private string home; + private string seedCapability; + private string lookAt; + + public LoginResponse() + { + this.loginFlags = new ArrayList(); + this.globalTextures = new ArrayList(); + this.eventCategories = new ArrayList(); + this.uiConfig = new ArrayList(); + this.classifiedCategories = new ArrayList(); + + this.loginError = new Hashtable(); + this.uiConfigHash = new Hashtable(); + + this.defaultXmlRpcResponse = new XmlRpcResponse(); + this.userProfile = new UserInfo(); + this.inventoryRoot = new ArrayList(); + this.initialOutfit = new ArrayList(); + this.agentInventory = new ArrayList(); + this.inventoryLibrary = new ArrayList(); + this.inventoryLibraryOwner = new ArrayList(); + + this.xmlRpcResponse = new XmlRpcResponse(); + this.defaultXmlRpcResponse = new XmlRpcResponse(); + + this.SetDefaultValues(); + } // LoginServer + + public void SetDefaultValues() + { + this.DST = "N"; + this.StipendSinceLogin = "N"; + this.Gendered = "Y"; + this.EverLoggedIn = "Y"; + this.login = "false"; + this.firstname = "Test"; + this.lastname = "User"; + this.agentAccess = "M"; + this.startLocation = "last"; + this.allowFirstLife = "Y"; + + this.SunTexture = "cce0f112-878f-4586-a2e2-a8f104bba271"; + this.CloudTexture = "fc4b9f0b-d008-45c6-96a4-01dd947ac621"; + this.MoonTexture = "fc4b9f0b-d008-45c6-96a4-01dd947ac621"; + + this.ErrorMessage = "You have entered an invalid name/password combination. Check Caps/lock."; + this.ErrorReason = "key"; + this.welcomeMessage = "Welcome to OpenSim!"; + this.seedCapability = ""; + this.home = "{'region_handle':[r" + (1000 * 256).ToString() + ",r" + (1000 * 256).ToString() + "], 'position':[r" + this.userProfile.homepos.X.ToString() + ",r" + this.userProfile.homepos.Y.ToString() + ",r" + this.userProfile.homepos.Z.ToString() + "], 'look_at':[r" + this.userProfile.homelookat.X.ToString() + ",r" + this.userProfile.homelookat.Y.ToString() + ",r" + this.userProfile.homelookat.Z.ToString() + "]}"; + this.lookAt = "[r0.99949799999999999756,r0.03166859999999999814,r0]"; + this.RegionX = (uint)255232; + this.RegionY = (uint)254976; + + // Classifieds; + this.AddClassifiedCategory((Int32)1, "Shopping"); + this.AddClassifiedCategory((Int32)2, "Land Rental"); + this.AddClassifiedCategory((Int32)3, "Property Rental"); + this.AddClassifiedCategory((Int32)4, "Special Attraction"); + this.AddClassifiedCategory((Int32)5, "New Products"); + this.AddClassifiedCategory((Int32)6, "Employment"); + this.AddClassifiedCategory((Int32)7, "Wanted"); + this.AddClassifiedCategory((Int32)8, "Service"); + this.AddClassifiedCategory((Int32)9, "Personal"); + + + this.SessionID = LLUUID.Random(); + this.SecureSessionID = LLUUID.Random(); + this.AgentID = LLUUID.Random(); + + Hashtable InitialOutfitHash = new Hashtable(); + InitialOutfitHash["folder_name"] = "Nightclub Female"; + InitialOutfitHash["gender"] = "female"; + this.initialOutfit.Add(InitialOutfitHash); + + + } // SetDefaultValues + + #region Login Failure Methods + public XmlRpcResponse GenerateFailureResponse(string reason, string message, string login) + { + // Overwrite any default values; + this.xmlRpcResponse = new XmlRpcResponse(); + + // Ensure Login Failed message/reason; + this.ErrorMessage = message; + this.ErrorReason = reason; + + this.loginError["reason"] = this.ErrorReason; + this.loginError["message"] = this.ErrorMessage; + this.loginError["login"] = login; + this.xmlRpcResponse.Value = this.loginError; + return (this.xmlRpcResponse); + } // GenerateResponse + + public XmlRpcResponse CreateFailedResponse() + { + return (this.CreateLoginFailedResponse()); + } // CreateErrorConnectingToGridResponse() + + public XmlRpcResponse CreateLoginFailedResponse() + { + return (this.GenerateFailureResponse("key", "Could not authenticate your avatar. Please check your username and password, and check the grid if problems persist.", "false")); + } // LoginFailedResponse + + public XmlRpcResponse CreateAlreadyLoggedInResponse() + { + return (this.GenerateFailureResponse("presence", "You appear to be already logged in, if this is not the case please wait for your session to timeout, if this takes longer than a few minutes please contact the grid owner", "false")); + } // CreateAlreadyLoggedInResponse() + + public XmlRpcResponse CreateDeadRegionResponse() + { + return (this.GenerateFailureResponse("key", "The region you are attempting to log into is not responding. Please select another region and try again.", "false")); + } + + public XmlRpcResponse CreateGridErrorResponse() + { + return (this.GenerateFailureResponse("key", "Error connecting to grid. Could not percieve credentials from login XML.", "false")); + } + + #endregion + + public XmlRpcResponse ToXmlRpcResponse() + { + try + { + + Hashtable responseData = new Hashtable(); + + this.loginFlagsHash = new Hashtable(); + this.loginFlagsHash["daylight_savings"] = this.DST; + this.loginFlagsHash["stipend_since_login"] = this.StipendSinceLogin; + this.loginFlagsHash["gendered"] = this.Gendered; + this.loginFlagsHash["ever_logged_in"] = this.EverLoggedIn; + this.loginFlags.Add(this.loginFlagsHash); + + responseData["first_name"] = this.Firstname; + responseData["last_name"] = this.Lastname; + responseData["agent_access"] = this.agentAccess; + + this.globalTexturesHash = new Hashtable(); + this.globalTexturesHash["sun_texture_id"] = this.SunTexture; + this.globalTexturesHash["cloud_texture_id"] = this.CloudTexture; + this.globalTexturesHash["moon_texture_id"] = this.MoonTexture; + this.globalTextures.Add(this.globalTexturesHash); + // this.eventCategories.Add(this.eventCategoriesHash); + + this.AddToUIConfig("allow_first_life", this.allowFirstLife); + this.uiConfig.Add(this.uiConfigHash); + + responseData["sim_port"] =(Int32) this.SimPort; + responseData["sim_ip"] = this.SimAddress; + + responseData["agent_id"] = this.AgentID.ToStringHyphenated(); + responseData["session_id"] = this.SessionID.ToStringHyphenated(); + responseData["secure_session_id"] = this.SecureSessionID.ToStringHyphenated(); + responseData["circuit_code"] = this.CircuitCode; + responseData["seconds_since_epoch"] = (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; + responseData["login-flags"] = this.loginFlags; + responseData["global-textures"] = this.globalTextures; + responseData["seed_capability"] = this.seedCapability; + + responseData["event_categories"] = this.eventCategories; + responseData["event_notifications"] = new ArrayList(); // todo + responseData["classified_categories"] = this.classifiedCategories; + responseData["ui-config"] = this.uiConfig; + + responseData["inventory-skeleton"] = this.agentInventory; + responseData["inventory-skel-lib"] = this.inventoryLibrary; + responseData["inventory-root"] = this.inventoryRoot; + responseData["gestures"] = new ArrayList(); // todo + responseData["inventory-lib-owner"] = this.inventoryLibraryOwner; + responseData["initial-outfit"] = this.initialOutfit; + responseData["start_location"] = this.startLocation; + responseData["seed_capability"] = this.seedCapability; + responseData["home"] = this.home; + responseData["look_at"] = this.lookAt; + responseData["message"] = this.welcomeMessage; + responseData["region_x"] = (Int32)this.RegionX * 256; + responseData["region_y"] = (Int32)this.RegionY * 256; + + //responseData["inventory-lib-root"] = new ArrayList(); // todo + //responseData["buddy-list"] = new ArrayList(); // todo + + responseData["login"] = "true"; + this.xmlRpcResponse.Value = responseData; + + return (this.xmlRpcResponse); + } + catch (Exception e) + { + MainLog.Instance.Warn( + "CLIENT", + "LoginResponse: Error creating XML-RPC Response: " + e.Message + ); + return (this.GenerateFailureResponse("Internal Error", "Error generating Login Response", "false")); + + } + + } // ToXmlRpcResponse + + public void SetEventCategories(string category, string value) + { + // this.eventCategoriesHash[category] = value; + //TODO + } // SetEventCategories + + public void AddToUIConfig(string itemName, string item) + { + this.uiConfigHash[itemName] = item; + } // SetUIConfig + + public void AddClassifiedCategory(Int32 ID, string categoryName) + { + Hashtable hash = new Hashtable(); + hash["category_name"] = categoryName; + hash["category_id"] = ID; + this.classifiedCategories.Add(hash); + // this.classifiedCategoriesHash.Clear(); + } // SetClassifiedCategory + + #region Properties + public string Login + { + get + { + return this.login; + } + set + { + this.login = value; + } + } // Login + + public string DST + { + get + { + return this.dst; + } + set + { + this.dst = value; + } + } // DST + + public string StipendSinceLogin + { + get + { + return this.stipendSinceLogin; + } + set + { + this.stipendSinceLogin = value; + } + } // StipendSinceLogin + + public string Gendered + { + get + { + return this.gendered; + } + set + { + this.gendered = value; + } + } // Gendered + + public string EverLoggedIn + { + get + { + return this.everLoggedIn; + } + set + { + this.everLoggedIn = value; + } + } // EverLoggedIn + + public int SimPort + { + get + { + return this.simPort; + } + set + { + this.simPort = value; + } + } // SimPort + + public string SimAddress + { + get + { + return this.simAddress; + } + set + { + this.simAddress = value; + } + } // SimAddress + + public LLUUID AgentID + { + get + { + return this.agentID; + } + set + { + this.agentID = value; + } + } // AgentID + + public LLUUID SessionID + { + get + { + return this.sessionID; + } + set + { + this.sessionID = value; + } + } // SessionID + + public LLUUID SecureSessionID + { + get + { + return this.secureSessionID; + } + set + { + this.secureSessionID = value; + } + } // SecureSessionID + + public Int32 CircuitCode + { + get + { + return this.circuitCode; + } + set + { + this.circuitCode = value; + } + } // CircuitCode + + public uint RegionX + { + get + { + return this.regionX; + } + set + { + this.regionX = value; + } + } // RegionX + + public uint RegionY + { + get + { + return this.regionY; + } + set + { + this.regionY = value; + } + } // RegionY + + public string SunTexture + { + get + { + return this.sunTexture; + } + set + { + this.sunTexture = value; + } + } // SunTexture + + public string CloudTexture + { + get + { + return this.cloudTexture; + } + set + { + this.cloudTexture = value; + } + } // CloudTexture + + public string MoonTexture + { + get + { + return this.moonTexture; + } + set + { + this.moonTexture = value; + } + } // MoonTexture + + public string Firstname + { + get + { + return this.firstname; + } + set + { + this.firstname = value; + } + } // Firstname + + public string Lastname + { + get + { + return this.lastname; + } + set + { + this.lastname = value; + } + } // Lastname + + public string AgentAccess + { + get + { + return this.agentAccess; + } + set + { + this.agentAccess = value; + } + } + + public string StartLocation + { + get + { + return this.startLocation; + } + set + { + this.startLocation = value; + } + } // StartLocation + + public string LookAt + { + get + { + return this.lookAt; + } + set + { + this.lookAt = value; + } + } + + public string SeedCapability + { + get + { + return this.seedCapability; + } + set + { + this.seedCapability = value; + } + } // SeedCapability + + public string ErrorReason + { + get + { + return this.errorReason; + } + set + { + this.errorReason = value; + } + } // ErrorReason + + public string ErrorMessage + { + get + { + return this.errorMessage; + } + set + { + this.errorMessage = value; + } + } // ErrorMessage + + public ArrayList InventoryRoot + { + get + { + return this.inventoryRoot; + } + set + { + this.inventoryRoot = value; + } + } + + public ArrayList InventorySkeleton + { + get + { + return this.agentInventory; + } + set + { + this.agentInventory = value; + } + } + + public ArrayList InventoryLibrary + { + get + { + return this.inventoryLibrary; + } + set + { + this.inventoryLibrary = value; + } + } + + public ArrayList InventoryLibraryOwner + { + get + { + return this.inventoryLibraryOwner; + } + set + { + this.inventoryLibraryOwner = value; + } + } + + public string Home + { + get + { + return this.home; + } + set + { + this.home = value; + } + } + + public string Message + { + get + { + return this.welcomeMessage; + } + set + { + this.welcomeMessage = value; + } + } + #endregion + + + public class UserInfo + { + public string firstname; + public string lastname; + public ulong homeregionhandle; + public LLVector3 homepos; + public LLVector3 homelookat; + } + } +} + diff --git a/OpenSim/Framework/UserManager/LoginService.cs b/OpenSim/Framework/UserManager/LoginService.cs new file mode 100644 index 0000000000..b75c4fbf0a --- /dev/null +++ b/OpenSim/Framework/UserManager/LoginService.cs @@ -0,0 +1,289 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using System.Security.Cryptography; +using libsecondlife; +using Nwc.XmlRpc; +using OpenSim.Framework.Console; +using OpenSim.Framework.Data; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Inventory; +using OpenSim.Framework.Utilities; + +using OpenSim.Framework.Configuration; +using InventoryFolder = OpenSim.Framework.Inventory.InventoryFolder; + +namespace OpenSim.Framework.UserManagement +{ + public class LoginService + { + protected string m_welcomeMessage = "Welcome to OpenSim"; + protected UserManagerBase m_userManager = null; + + public LoginService(UserManagerBase userManager, string welcomeMess) + { + m_userManager = userManager; + if (welcomeMess != "") + { + m_welcomeMessage = welcomeMess; + } + } + + /// + /// Main user login function + /// + /// The XMLRPC request + /// The response to send + public XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request) + { + + System.Console.WriteLine("Attempting login now..."); + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable requestData = (Hashtable)request.Params[0]; + + bool GoodXML = (requestData.Contains("first") && requestData.Contains("last") && requestData.Contains("passwd")); + bool GoodLogin = false; + string firstname = ""; + string lastname = ""; + string passwd = ""; + + UserProfileData userProfile; + LoginResponse logResponse = new LoginResponse(); + + if (GoodXML) + { + firstname = (string)requestData["first"]; + lastname = (string)requestData["last"]; + passwd = (string)requestData["passwd"]; + + userProfile = GetTheUser(firstname, lastname); + if (userProfile == null) + return logResponse.CreateLoginFailedResponse(); + + GoodLogin = AuthenticateUser(userProfile, passwd); + } + else + { + return logResponse.CreateGridErrorResponse(); + } + + if (!GoodLogin) + { + return logResponse.CreateLoginFailedResponse(); + } + else + { + // If we already have a session... + if (userProfile.currentAgent != null && userProfile.currentAgent.agentOnline) + { + // Reject the login + return logResponse.CreateAlreadyLoggedInResponse(); + } + // Otherwise... + // Create a new agent session + CreateAgent(userProfile, request); + + try + { + LLUUID agentID = userProfile.UUID; + + // Inventory Library Section + InventoryData inventData = this.CreateInventoryData(agentID); + ArrayList AgentInventoryArray = inventData.InventoryArray; + + Hashtable InventoryRootHash = new Hashtable(); + InventoryRootHash["folder_id"] = inventData.RootFolderID.ToStringHyphenated(); + ArrayList InventoryRoot = new ArrayList(); + InventoryRoot.Add(InventoryRootHash); + userProfile.rootInventoryFolderID = inventData.RootFolderID; + + // Circuit Code + uint circode = (uint)(Util.RandomClass.Next()); + + logResponse.Lastname = userProfile.surname; + logResponse.Firstname = userProfile.username; + logResponse.AgentID = agentID.ToStringHyphenated(); + logResponse.SessionID = userProfile.currentAgent.sessionID.ToStringHyphenated(); + logResponse.SecureSessionID = userProfile.currentAgent.secureSessionID.ToStringHyphenated(); + logResponse.InventoryRoot = InventoryRoot; + logResponse.InventorySkeleton = AgentInventoryArray; + logResponse.InventoryLibrary = this.GetInventoryLibrary(); + logResponse.InventoryLibraryOwner = this.GetLibraryOwner(); + logResponse.CircuitCode = (Int32)circode; + //logResponse.RegionX = 0; //overwritten + //logResponse.RegionY = 0; //overwritten + logResponse.Home = "!!null temporary value {home}!!"; // Overwritten + //logResponse.LookAt = "\n[r" + TheUser.homeLookAt.X.ToString() + ",r" + TheUser.homeLookAt.Y.ToString() + ",r" + TheUser.homeLookAt.Z.ToString() + "]\n"; + //logResponse.SimAddress = "127.0.0.1"; //overwritten + //logResponse.SimPort = 0; //overwritten + logResponse.Message = this.GetMessage(); + + try + { + this.CustomiseResponse(logResponse, userProfile); + } + catch (Exception e) + { + System.Console.WriteLine(e.ToString()); + return logResponse.CreateDeadRegionResponse(); + //return logResponse.ToXmlRpcResponse(); + } + CommitAgent(ref userProfile); + return logResponse.ToXmlRpcResponse(); + + } + + catch (Exception E) + { + System.Console.WriteLine(E.ToString()); + } + //} + } + return response; + + } + + /// + /// Customises the login response and fills in missing values. + /// + /// The existing response + /// The user profile + public virtual void CustomiseResponse(LoginResponse response, UserProfileData theUser) + { + } + + /// + /// Saves a target agent to the database + /// + /// The users profile + /// Successful? + public bool CommitAgent(ref UserProfileData profile) + { + // Saves the agent to database + return true; + } + + + /// + /// Checks a user against it's password hash + /// + /// The users profile + /// The supplied password + /// Authenticated? + public virtual bool AuthenticateUser(UserProfileData profile, string password) + { + MainLog.Instance.Verbose( + "Authenticating " + profile.username + " " + profile.surname); + + password = password.Remove(0, 3); //remove $1$ + + string s = Util.Md5Hash(password + ":" + profile.passwordSalt); + + return profile.passwordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase); + } + + /// + /// + /// + /// + /// + public void CreateAgent(UserProfileData profile, XmlRpcRequest request) + { + this.m_userManager.CreateAgent(profile, request); + } + + /// + /// + /// + /// + /// + /// + public virtual UserProfileData GetTheUser(string firstname, string lastname) + { + return this.m_userManager.getUserProfile(firstname, lastname); + } + + /// + /// + /// + /// + public virtual string GetMessage() + { + return m_welcomeMessage; + } + + /// + /// + /// + /// + protected virtual ArrayList GetInventoryLibrary() + { + //return new ArrayList(); + Hashtable TempHash = new Hashtable(); + TempHash["name"] = "OpenSim Library"; + TempHash["parent_id"] = LLUUID.Zero.ToStringHyphenated(); + TempHash["version"] = "1"; + TempHash["type_default"] = "-1"; + TempHash["folder_id"] = "00000112-000f-0000-0000-000100bba000"; + ArrayList temp = new ArrayList(); + temp.Add(TempHash); + + TempHash = new Hashtable(); + TempHash["name"] = "Texture Library"; + TempHash["parent_id"] = "00000112-000f-0000-0000-000100bba000"; + TempHash["version"] = "1"; + TempHash["type_default"] = "-1"; + TempHash["folder_id"] = "00000112-000f-0000-0000-000100bba001"; + temp.Add(TempHash); + return temp; + } + + /// + /// + /// + /// + protected virtual ArrayList GetLibraryOwner() + { + //for now create random inventory library owner + Hashtable TempHash = new Hashtable(); + TempHash["agent_id"] = "11111111-1111-0000-0000-000100bba000"; + ArrayList inventoryLibOwner = new ArrayList(); + inventoryLibOwner.Add(TempHash); + return inventoryLibOwner; + } + + protected virtual InventoryData CreateInventoryData(LLUUID userID) + { + AgentInventory userInventory = new AgentInventory(); + userInventory.CreateRootFolder(userID, false); + + ArrayList AgentInventoryArray = new ArrayList(); + Hashtable TempHash; + foreach (InventoryFolder InvFolder in userInventory.InventoryFolders.Values) + { + TempHash = new Hashtable(); + TempHash["name"] = InvFolder.FolderName; + TempHash["parent_id"] = InvFolder.ParentID.ToStringHyphenated(); + TempHash["version"] = (Int32)InvFolder.Version; + TempHash["type_default"] = (Int32)InvFolder.DefaultType; + TempHash["folder_id"] = InvFolder.FolderID.ToStringHyphenated(); + AgentInventoryArray.Add(TempHash); + } + + return new InventoryData(AgentInventoryArray, userInventory.InventoryRoot.FolderID); + } + + public class InventoryData + { + public ArrayList InventoryArray = null; + public LLUUID RootFolderID = LLUUID.Zero; + + public InventoryData(ArrayList invList, LLUUID rootID) + { + InventoryArray = invList; + RootFolderID = rootID; + } + } + } +} diff --git a/OpenSim/Framework/UserManager/UserManagerBase.cs b/OpenSim/Framework/UserManager/UserManagerBase.cs new file mode 100644 index 0000000000..dee7aed815 --- /dev/null +++ b/OpenSim/Framework/UserManager/UserManagerBase.cs @@ -0,0 +1,374 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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; +using System.Collections.Generic; +using System.Reflection; +using System.Security.Cryptography; +using libsecondlife; +using Nwc.XmlRpc; +using OpenSim.Framework.Console; +using OpenSim.Framework.Data; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Inventory; +using OpenSim.Framework.Utilities; + +using OpenSim.Framework.Configuration; +using InventoryFolder = OpenSim.Framework.Inventory.InventoryFolder; + +namespace OpenSim.Framework.UserManagement +{ + public abstract class UserManagerBase + { + public UserConfig _config; + Dictionary _plugins = new Dictionary(); + + /// + /// Adds a new user server plugin - user servers will be requested in the order they were loaded. + /// + /// The filename to the user server plugin DLL + public void AddPlugin(string FileName) + { + MainLog.Instance.Verbose( "Userstorage: Attempting to load " + FileName); + Assembly pluginAssembly = Assembly.LoadFrom(FileName); + + MainLog.Instance.Verbose( "Userstorage: Found " + pluginAssembly.GetTypes().Length + " interfaces."); + foreach (Type pluginType in pluginAssembly.GetTypes()) + { + if (!pluginType.IsAbstract) + { + Type typeInterface = pluginType.GetInterface("IUserData", true); + + if (typeInterface != null) + { + IUserData plug = (IUserData)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); + plug.Initialise(); + this._plugins.Add(plug.getName(), plug); + MainLog.Instance.Verbose( "Userstorage: Added IUserData Interface"); + } + + typeInterface = null; + } + } + + pluginAssembly = null; + } + + #region Get UserProfile + /// + /// Loads a user profile from a database by UUID + /// + /// The target UUID + /// A user profile + public UserProfileData getUserProfile(LLUUID uuid) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + UserProfileData profile = plugin.Value.getUserByUUID(uuid); + profile.currentAgent = getUserAgent(profile.UUID); + return profile; + } + catch (Exception e) + { + MainLog.Instance.Verbose( "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + + return null; + } + + + /// + /// Loads a user profile by name + /// + /// The target name + /// A user profile + public UserProfileData getUserProfile(string name) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + UserProfileData profile = plugin.Value.getUserByName(name); + profile.currentAgent = getUserAgent(profile.UUID); + return profile; + } + catch (Exception e) + { + System.Console.WriteLine("EEK!"); + MainLog.Instance.Verbose( "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + + return null; + } + + /// + /// Loads a user profile by name + /// + /// First name + /// Last name + /// A user profile + public UserProfileData getUserProfile(string fname, string lname) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + UserProfileData profile = plugin.Value.getUserByName(fname,lname); + + profile.currentAgent = getUserAgent(profile.UUID); + + return profile; + } + catch (Exception e) + { + MainLog.Instance.Verbose( "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + + return null; + } + + /// + /// Set's user profile from object + /// + /// First name + /// Last name + /// A user profile + public bool setUserProfile(UserProfileData data) + { + foreach (KeyValuePair plugin in _plugins) + { + try { + plugin.Value.updateUserProfile(data); + return true; + } catch (Exception e) { + MainLog.Instance.Verbose( "Unable to set user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + + return false; + } + + #endregion + + #region Get UserAgent + /// + /// Loads a user agent by uuid (not called directly) + /// + /// The agents UUID + /// Agent profiles + public UserAgentData getUserAgent(LLUUID uuid) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + return plugin.Value.getAgentByUUID(uuid); + } + catch (Exception e) + { + MainLog.Instance.Verbose( "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + + return null; + } + + /// + /// Loads a user agent by name (not called directly) + /// + /// The agents name + /// A user agent + public UserAgentData getUserAgent(string name) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + return plugin.Value.getAgentByName(name); + } + catch (Exception e) + { + MainLog.Instance.Verbose( "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + + return null; + } + + // TODO: document + public void clearUserAgent(LLUUID agentID) + { + UserProfileData profile = getUserProfile(agentID); + profile.currentAgent = null; + setUserProfile(profile); + } + + + /// + /// Loads a user agent by name (not called directly) + /// + /// The agents firstname + /// The agents lastname + /// A user agent + public UserAgentData getUserAgent(string fname, string lname) + { + foreach (KeyValuePair plugin in _plugins) + { + try + { + return plugin.Value.getAgentByName(fname,lname); + } + catch (Exception e) + { + MainLog.Instance.Verbose( "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + + return null; + } + + #endregion + + #region CreateAgent + /// + /// Creates and initialises a new user agent - make sure to use CommitAgent when done to submit to the DB + /// + /// The users profile + /// The users loginrequest + public void CreateAgent(UserProfileData profile, XmlRpcRequest request) + { + Hashtable requestData = (Hashtable)request.Params[0]; + + UserAgentData agent = new UserAgentData(); + + // User connection + agent.agentOnline = true; + + // Generate sessions + RNGCryptoServiceProvider rand = new RNGCryptoServiceProvider(); + byte[] randDataS = new byte[16]; + byte[] randDataSS = new byte[16]; + rand.GetBytes(randDataS); + rand.GetBytes(randDataSS); + + agent.secureSessionID = new LLUUID(randDataSS, 0); + agent.sessionID = new LLUUID(randDataS, 0); + + // Profile UUID + agent.UUID = profile.UUID; + + // Current position (from Home) + agent.currentHandle = profile.homeRegion; + agent.currentPos = profile.homeLocation; + + // If user specified additional start, use that + if (requestData.ContainsKey("start")) + { + string startLoc = ((string)requestData["start"]).Trim(); + if (!(startLoc == "last" || startLoc == "home")) + { + // Format: uri:Ahern&162&213&34 + try + { + string[] parts = startLoc.Remove(0, 4).Split('&'); + string region = parts[0]; + + //////////////////////////////////////////////////// + //SimProfile SimInfo = new SimProfile(); + //SimInfo = SimInfo.LoadFromGrid(theUser.currentAgent.currentHandle, _config.GridServerURL, _config.GridSendKey, _config.GridRecvKey); + } + catch (Exception) + { + + } + } + } + + // What time did the user login? + agent.loginTime = Util.UnixTimeSinceEpoch(); + agent.logoutTime = 0; + + // Current location + agent.regionID = new LLUUID(); // Fill in later + agent.currentRegion = new LLUUID(); // Fill in later + + profile.currentAgent = agent; + } + + /// + /// Saves a target agent to the database + /// + /// The users profile + /// Successful? + public bool CommitAgent(ref UserProfileData profile) + { + // Saves the agent to database + return true; + } + + #endregion + + /// + /// + /// + /// + public void AddUserProfile(string firstName, string lastName, string pass, uint regX, uint regY) + { + UserProfileData user = new UserProfileData(); + user.homeLocation = new LLVector3(128, 128, 100); + user.UUID = LLUUID.Random(); + user.username = firstName; + user.surname = lastName; + user.passwordHash = pass; + user.passwordSalt = ""; + user.created = Util.UnixTimeSinceEpoch(); + user.homeLookAt = new LLVector3(100, 100, 100); + user.homeRegion = Util.UIntsToLong((regX * 256), (regY * 256)); + + foreach (KeyValuePair plugin in _plugins) + { + try + { + plugin.Value.addNewUserProfile(user); + + } + catch (Exception e) + { + MainLog.Instance.Verbose("Unable to add user via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + } + + // Rest and XML-RPC methods. (have moved them to a sub class in the user server) + } +} diff --git a/OpenSim/Grid/AssetServer/Main.cs b/OpenSim/Grid/AssetServer/Main.cs new file mode 100644 index 0000000000..c7caf2da55 --- /dev/null +++ b/OpenSim/Grid/AssetServer/Main.cs @@ -0,0 +1,355 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.IO; +using System.Text; +using Db4objects.Db4o; +using libsecondlife; +using OpenSim.Framework.Console; +using OpenSim.Framework.Types; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Utilities; + +namespace OpenSim.Grid.AssetServer +{ + /// + /// An asset server + /// + public class OpenAsset_Main : conscmd_callback + { + private IObjectContainer db; + + public static OpenAsset_Main assetserver; + + private LogBase m_console; + + [STAThread] + public static void Main(string[] args) + { + Console.WriteLine("Starting...\n"); + + assetserver = new OpenAsset_Main(); + assetserver.Startup(); + + assetserver.Work(); + } + + private void Work() + { + m_console.Notice("Enter help for a list of commands"); + + while (true) + { + m_console.MainLogPrompt(); + } + } + + private OpenAsset_Main() + { + if(!Directory.Exists(Util.logDir())) + { + Directory.CreateDirectory(Util.logDir()); + } + m_console = new LogBase((Path.Combine(Util.logDir(),"opengrid-AssetServer-console.log")), "OpenAsset", this, false); + MainLog.Instance = m_console; + } + + public void Startup() + { + m_console.Verbose("ASSET", "Setting up asset DB"); + setupDB(); + + m_console.Verbose("ASSET", "Starting HTTP process"); + BaseHttpServer httpServer = new BaseHttpServer(8003); + + httpServer.AddStreamHandler( new GetAssetStreamHandler(this)); + httpServer.AddStreamHandler(new PostAssetStreamHandler( this )); + + httpServer.Start(); + + } + + public byte[] GetAssetData(LLUUID assetID, bool isTexture) + { + bool found = false; + AssetStorage foundAsset = null; + + IObjectSet result = db.Get(new AssetStorage(assetID)); + if (result.Count > 0) + { + foundAsset = (AssetStorage)result.Next(); + found = true; + } + + if (found) + { + return foundAsset.Data; + } + else + { + return null; + } + } + + public void setupDB() + { + string yappath=(Path.Combine(Util.dataDir(),"gridassets.yap")); + bool yapfile = File.Exists(yappath); + try + { + db = Db4oFactory.OpenFile(yappath); + MainLog.Instance.Verbose("storage", "Main.cs:setupDB() - creation"); + } + catch (Exception e) + { + db.Close(); + MainLog.Instance.Warn("storage", "Main.cs:setupDB() - Exception occured"); + MainLog.Instance.Warn("storage", e.ToString()); + } + if (!yapfile) + { + this.LoadDB(); + } + } + + public void LoadDB() + { + try + { + + Console.WriteLine("setting up Asset database"); + + AssetBase Image = new AssetBase(); + Image.FullID = new LLUUID("00000000-0000-0000-9999-000000000001"); + Image.Name = "Bricks"; + this.LoadAsset(Image, true, "bricks.jp2"); + AssetStorage store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + Image = new AssetBase(); + Image.FullID = new LLUUID("00000000-0000-0000-9999-000000000002"); + Image.Name = "Plywood"; + this.LoadAsset(Image, true, "plywood.jp2"); + store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + Image = new AssetBase(); + Image.FullID = new LLUUID("00000000-0000-0000-9999-000000000003"); + Image.Name = "Rocks"; + this.LoadAsset(Image, true, "rocks.jp2"); + store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + Image = new AssetBase(); + Image.FullID = new LLUUID("00000000-0000-0000-9999-000000000004"); + Image.Name = "Granite"; + this.LoadAsset(Image, true, "granite.jp2"); + store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + Image = new AssetBase(); + Image.FullID = new LLUUID("00000000-0000-0000-9999-000000000005"); + Image.Name = "Hardwood"; + this.LoadAsset(Image, true, "hardwood.jp2"); + store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + Image = new AssetBase(); + Image.FullID = new LLUUID("00000000-0000-0000-5005-000000000005"); + Image.Name = "Prim Base Texture"; + this.LoadAsset(Image, true, "plywood.jp2"); + store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + Image = new AssetBase(); + Image.FullID = new LLUUID("13371337-1337-1337-1337-133713371337"); + Image.Name = "Peaches"; + this.LoadAsset(Image, true, "peaches.jp2"); + store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + Image = new AssetBase(); + Image.FullID = new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73"); + Image.Name = "Shape"; + this.LoadAsset(Image, false, "base_shape.dat"); + store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + } + catch (Exception e) + { + Console.WriteLine(e.Message); + } + } + + private void LoadAsset(AssetBase info, bool image, string filename) + { + + + string dataPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "assets"); //+ folder; + string fileName = Path.Combine(dataPath, filename); + FileInfo fInfo = new FileInfo(fileName); + long numBytes = fInfo.Length; + FileStream fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read); + byte[] idata = new byte[numBytes]; + BinaryReader br = new BinaryReader(fStream); + idata = br.ReadBytes((int)numBytes); + br.Close(); + fStream.Close(); + info.Data = idata; + //info.loaded=true; + } + + public void CreateAsset(LLUUID assetId, byte[] assetData) + { + AssetBase asset = new AssetBase(); + asset.Name = ""; + asset.FullID = assetId; + asset.Data = assetData; + + AssetStorage store = new AssetStorage(); + store.Data = asset.Data; + store.Name = asset.Name; + store.UUID = asset.FullID; + db.Set(store); + db.Commit(); + } + + public void RunCmd(string cmd, string[] cmdparams) + { + switch (cmd) + { + case "help": + m_console.Notice("shutdown - shutdown this asset server (USE CAUTION!)"); + break; + + case "shutdown": + m_console.Close(); + Environment.Exit(0); + break; + } + } + + public void Show(string ShowWhat) + { + } + } + + public class GetAssetStreamHandler : BaseStreamHandler + { + OpenAsset_Main m_assetManager; + + override public byte[] Handle(string path, Stream request) + { + string param = GetParam(path); + + byte[] assetdata = m_assetManager.GetAssetData(new LLUUID(param), false); + if (assetdata != null) + { + return assetdata; + } + else + { + return new byte[]{}; + } + } + + public GetAssetStreamHandler(OpenAsset_Main assetManager):base( "/assets/", "GET") + { + m_assetManager = assetManager; + } + } + + public class PostAssetStreamHandler : BaseStreamHandler + { + OpenAsset_Main m_assetManager; + + override public byte[] Handle(string path, Stream request) + { + string param = GetParam(path); + LLUUID assetId = new LLUUID(param); + byte[] txBuffer = new byte[4096]; + + using( BinaryReader binReader = new BinaryReader( request ) ) + { + using (MemoryStream memoryStream = new MemoryStream(4096)) + { + int count; + while ((count = binReader.Read(txBuffer, 0, 4096)) > 0) + { + memoryStream.Write(txBuffer, 0, count); + } + + byte[] assetData = memoryStream.ToArray(); + + m_assetManager.CreateAsset(assetId, assetData); + } + } + + return new byte[]{}; + } + + public PostAssetStreamHandler( OpenAsset_Main assetManager ) + : base("/assets/", "POST") + { + m_assetManager = assetManager; + } + } +} diff --git a/OpenSim/Grid/AssetServer/Properties/AssemblyInfo.cs b/OpenSim/Grid/AssetServer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..dc39ce21b9 --- /dev/null +++ b/OpenSim/Grid/AssetServer/Properties/AssemblyInfo.cs @@ -0,0 +1,58 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OGS-AssetServer")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OGS-AssetServer")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("b541b244-3d1d-4625-9003-bc2a3a6a39a4")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Grid/Framework.Manager/GridManagementAgent.cs b/OpenSim/Grid/Framework.Manager/GridManagementAgent.cs new file mode 100644 index 0000000000..6c916a24dd --- /dev/null +++ b/OpenSim/Grid/Framework.Manager/GridManagementAgent.cs @@ -0,0 +1,138 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Collections; +using libsecondlife; +using Nwc.XmlRpc; +using OpenSim.Framework.Servers; + +namespace OpenSim.Framework.Manager +{ + /// + /// Used to pass messages to the gridserver + /// + /// Pass this argument + public delegate void GridManagerCallback(string param); + + /// + /// Serverside listener for grid commands + /// + public class GridManagementAgent + { + /// + /// Passes grid server messages + /// + private GridManagerCallback thecallback; + + /// + /// Security keys + /// + private string sendkey; + private string recvkey; + + /// + /// Our component type + /// + private string component_type; + + /// + /// List of active sessions + /// + private static ArrayList Sessions; + + /// + /// Initialises a new GridManagementAgent + /// + /// HTTP Daemon for this server + /// What component type are we? + /// Security send key + /// Security recieve key + /// Message callback + public GridManagementAgent(BaseHttpServer app_httpd, string component_type, string sendkey, string recvkey, GridManagerCallback thecallback) + { + this.sendkey = sendkey; + this.recvkey = recvkey; + this.component_type = component_type; + this.thecallback = thecallback; + Sessions = new ArrayList(); + + app_httpd.AddXmlRPCHandler("manager_login", XmlRpcLoginMethod); + + switch (component_type) + { + case "gridserver": + GridServerManager.sendkey = this.sendkey; + GridServerManager.recvkey = this.recvkey; + GridServerManager.thecallback = thecallback; + app_httpd.AddXmlRPCHandler("shutdown", GridServerManager.XmlRpcShutdownMethod); + break; + } + } + + /// + /// Checks if a session exists + /// + /// The session ID + /// Exists? + public static bool SessionExists(LLUUID sessionID) + { + return Sessions.Contains(sessionID); + } + + /// + /// Logs a new session to the grid manager + /// + /// the XMLRPC request + /// An XMLRPC reply + public static XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request) + { + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable requestData = (Hashtable)request.Params[0]; + Hashtable responseData = new Hashtable(); + + // TODO: Switch this over to using OpenSim.Framework.Data + if (requestData["username"].Equals("admin") && requestData["password"].Equals("supersecret")) + { + response.IsFault = false; + LLUUID new_session = LLUUID.Random(); + Sessions.Add(new_session); + responseData["session_id"] = new_session.ToString(); + responseData["msg"] = "Login OK"; + } + else + { + response.IsFault = true; + responseData["error"] = "Invalid username or password"; + } + + response.Value = responseData; + return response; + + } + + } +} diff --git a/OpenSim/Grid/Framework.Manager/GridServerManager.cs b/OpenSim/Grid/Framework.Manager/GridServerManager.cs new file mode 100644 index 0000000000..67cd35dc30 --- /dev/null +++ b/OpenSim/Grid/Framework.Manager/GridServerManager.cs @@ -0,0 +1,93 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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; +using System.Threading; +using libsecondlife; +using Nwc.XmlRpc; + +namespace OpenSim.Framework.Manager { + + /// + /// A remote management system for the grid server + /// + public class GridServerManager + { + /// + /// Triggers events from the grid manager + /// + public static GridManagerCallback thecallback; + + /// + /// Security keys + /// + public static string sendkey; + public static string recvkey; + + /// + /// Disconnects the grid server and shuts it down + /// + /// XmlRpc Request + /// An XmlRpc response containing either a "msg" or an "error" + public static XmlRpcResponse XmlRpcShutdownMethod(XmlRpcRequest request) + { + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable requestData = (Hashtable)request.Params[0]; + Hashtable responseData = new Hashtable(); + + if(requestData.ContainsKey("session_id")) { + if(GridManagementAgent.SessionExists(new LLUUID((string)requestData["session_id"]))) { + responseData["msg"]="Shutdown command accepted"; + (new Thread(new ThreadStart(ShutdownServer))).Start(); + } else { + response.IsFault=true; + responseData["error"]="bad session ID"; + } + } else { + response.IsFault=true; + responseData["error"]="no session ID"; + } + + response.Value = responseData; + return response; + } + + /// + /// Shuts down the grid server + /// + public static void ShutdownServer() + { + Console.WriteLine("Shutting down the grid server - recieved a grid manager request"); + Console.WriteLine("Terminating in three seconds..."); + Thread.Sleep(3000); + thecallback("shutdown"); + } + } +} + diff --git a/OpenSim/Grid/GridServer.Config/AssemblyInfo.cs b/OpenSim/Grid/GridServer.Config/AssemblyInfo.cs new file mode 100644 index 0000000000..39c9e8f429 --- /dev/null +++ b/OpenSim/Grid/GridServer.Config/AssemblyInfo.cs @@ -0,0 +1,56 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Reflection; +using System.Runtime.InteropServices; +// Information about this assembly is defined by the following +// attributes. +// +// change them to the information which is associated with the assembly +// you compile. + +[assembly: AssemblyTitle("GridConfig")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("GridConfig")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. +[assembly: ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all values by your own or you can build default build and revision +// numbers with the '*' character (the default): + +[assembly: AssemblyVersion("1.0.*")] diff --git a/OpenSim/Grid/GridServer.Config/DbGridConfig.cs b/OpenSim/Grid/GridServer.Config/DbGridConfig.cs new file mode 100644 index 0000000000..4acf81d7d0 --- /dev/null +++ b/OpenSim/Grid/GridServer.Config/DbGridConfig.cs @@ -0,0 +1,160 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 Db4objects.Db4o; +using OpenSim.Framework.Console; +using OpenSim.Framework.Interfaces; + +namespace OpenGrid.Config.GridConfigDb4o +{ + /// + /// A grid configuration interface for returning the DB4o Config Provider + /// + public class Db40ConfigPlugin: IGridConfig + { + /// + /// Loads and returns a configuration objeect + /// + /// A grid configuration object + public GridConfig GetConfigObject() + { + MainLog.Instance.Verbose("Loading Db40Config dll"); + return ( new DbGridConfig()); + } + } + + /// + /// A DB4o based Gridserver configuration object + /// + public class DbGridConfig : GridConfig + { + /// + /// The DB4o Database + /// + private IObjectContainer db; + + /// + /// User configuration for the Grid Config interfaces + /// + public void LoadDefaults() { + MainLog.Instance.Notice("Config.cs:LoadDefaults() - Please press enter to retain default or enter new settings"); + + // About the grid options + this.GridOwner = MainLog.Instance.CmdPrompt("Grid owner", "OGS development team"); + + // Asset Options + this.DefaultAssetServer = MainLog.Instance.CmdPrompt("Default asset server","http://127.0.0.1:8003/"); + this.AssetSendKey = MainLog.Instance.CmdPrompt("Key to send to asset server","null"); + this.AssetRecvKey = MainLog.Instance.CmdPrompt("Key to expect from asset server","null"); + + // User Server Options + this.DefaultUserServer = MainLog.Instance.CmdPrompt("Default user server","http://127.0.0.1:8002/"); + this.UserSendKey = MainLog.Instance.CmdPrompt("Key to send to user server","null"); + this.UserRecvKey = MainLog.Instance.CmdPrompt("Key to expect from user server","null"); + + // Region Server Options + this.SimSendKey = MainLog.Instance.CmdPrompt("Key to send to sims","null"); + this.SimRecvKey = MainLog.Instance.CmdPrompt("Key to expect from sims","null"); + } + + /// + /// Initialises a new configuration object + /// + public override void InitConfig() { + try { + // Perform Db4o initialisation + db = Db4oFactory.OpenFile("opengrid.yap"); + + // Locate the grid configuration object + IObjectSet result = db.Get(typeof(DbGridConfig)); + // Found? + if(result.Count==1) { + MainLog.Instance.Verbose("Config.cs:InitConfig() - Found a GridConfig object in the local database, loading"); + foreach (DbGridConfig cfg in result) { + // Import each setting into this class + // Grid Settings + this.GridOwner=cfg.GridOwner; + // Asset Settings + this.DefaultAssetServer=cfg.DefaultAssetServer; + this.AssetSendKey=cfg.AssetSendKey; + this.AssetRecvKey=cfg.AssetRecvKey; + // User Settings + this.DefaultUserServer=cfg.DefaultUserServer; + this.UserSendKey=cfg.UserSendKey; + this.UserRecvKey=cfg.UserRecvKey; + // Region Settings + this.SimSendKey=cfg.SimSendKey; + this.SimRecvKey=cfg.SimRecvKey; + } + // Create a new configuration object from this class + } else { + MainLog.Instance.Verbose("Config.cs:InitConfig() - Could not find object in database, loading precompiled defaults"); + + // Load default settings into this class + LoadDefaults(); + + // Saves to the database file... + MainLog.Instance.Verbose( "Writing out default settings to local database"); + db.Set(this); + + // Closes file locks + db.Close(); + } + } catch(Exception e) { + MainLog.Instance.Warn("Config.cs:InitConfig() - Exception occured"); + MainLog.Instance.Warn(e.ToString()); + } + + // Grid Settings + MainLog.Instance.Verbose("Grid settings loaded:"); + MainLog.Instance.Verbose("Grid owner: " + this.GridOwner); + + // Asset Settings + MainLog.Instance.Verbose("Default asset server: " + this.DefaultAssetServer); + MainLog.Instance.Verbose("Key to send to asset server: " + this.AssetSendKey); + MainLog.Instance.Verbose("Key to expect from asset server: " + this.AssetRecvKey); + + // User Settings + MainLog.Instance.Verbose("Default user server: " + this.DefaultUserServer); + MainLog.Instance.Verbose("Key to send to user server: " + this.UserSendKey); + MainLog.Instance.Verbose("Key to expect from user server: " + this.UserRecvKey); + + // Region Settings + MainLog.Instance.Verbose("Key to send to sims: " + this.SimSendKey); + MainLog.Instance.Verbose("Key to expect from sims: " + this.SimRecvKey); + } + + /// + /// Closes down the database and releases filesystem locks + /// + public void Shutdown() { + db.Close(); + } + } + +} diff --git a/OpenSim/Grid/GridServer/GridManager.cs b/OpenSim/Grid/GridServer/GridManager.cs new file mode 100644 index 0000000000..18d8112ef2 --- /dev/null +++ b/OpenSim/Grid/GridServer/GridManager.cs @@ -0,0 +1,720 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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; +using System.Collections.Generic; +using System.Net; +using System.Reflection; +using System.Xml; +using libsecondlife; +using Nwc.XmlRpc; +using OpenSim.Framework.Console; +using OpenSim.Framework.Data; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Utilities; + +using OpenSim.Framework.Configuration; + +namespace OpenSim.Grid.GridServer +{ + class GridManager + { + Dictionary _plugins = new Dictionary(); + Dictionary _logplugins = new Dictionary(); + + public GridConfig config; + + /// + /// Adds a new grid server plugin - grid servers will be requested in the order they were loaded. + /// + /// The filename to the grid server plugin DLL + public void AddPlugin(string FileName) + { + MainLog.Instance.Verbose("Storage: Attempting to load " + FileName); + Assembly pluginAssembly = Assembly.LoadFrom(FileName); + + MainLog.Instance.Verbose("Storage: Found " + pluginAssembly.GetTypes().Length + " interfaces."); + foreach (Type pluginType in pluginAssembly.GetTypes()) + { + if (!pluginType.IsAbstract) + { + // Regions go here + Type typeInterface = pluginType.GetInterface("IGridData", true); + + if (typeInterface != null) + { + IGridData plug = (IGridData)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); + plug.Initialise(); + this._plugins.Add(plug.getName(), plug); + MainLog.Instance.Verbose("Storage: Added IGridData Interface"); + } + + typeInterface = null; + + // Logs go here + typeInterface = pluginType.GetInterface("ILogData", true); + + if (typeInterface != null) + { + ILogData plug = (ILogData)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); + plug.Initialise(); + this._logplugins.Add(plug.getName(), plug); + MainLog.Instance.Verbose( "Storage: Added ILogData Interface"); + } + + typeInterface = null; + } + } + + pluginAssembly = null; + } + + /// + /// Logs a piece of information to the database + /// + /// What you were operating on (in grid server, this will likely be the region UUIDs) + /// Which method is being called? + /// What arguments are being passed? + /// How high priority is this? 1 = Max, 6 = Verbose + /// The message to log + private void logToDB(string target, string method, string args, int priority, string message) + { + foreach (KeyValuePair kvp in _logplugins) + { + try + { + kvp.Value.saveLog("Gridserver", target, method, args, priority, message); + } + catch (Exception) + { + MainLog.Instance.Warn("storage", "Unable to write log via " + kvp.Key); + } + } + } + + /// + /// Returns a region by argument + /// + /// A UUID key of the region to return + /// A SimProfileData for the region + public SimProfileData getRegion(LLUUID uuid) + { + foreach(KeyValuePair kvp in _plugins) { + try + { + return kvp.Value.GetProfileByLLUUID(uuid); + } + catch (Exception e) + { + MainLog.Instance.Warn("storage", "getRegion - " + e.Message); + } + } + return null; + } + + /// + /// Returns a region by argument + /// + /// A regionHandle of the region to return + /// A SimProfileData for the region + public SimProfileData getRegion(ulong handle) + { + foreach (KeyValuePair kvp in _plugins) + { + try + { + return kvp.Value.GetProfileByHandle(handle); + } + catch + { + MainLog.Instance.Warn("storage", "Unable to find region " + handle.ToString() + " via " + kvp.Key); + } + } + return null; + } + + public Dictionary getRegions(uint xmin, uint ymin, uint xmax, uint ymax) + { + Dictionary regions = new Dictionary(); + + SimProfileData[] neighbours; + + foreach (KeyValuePair kvp in _plugins) + { + try + { + neighbours = kvp.Value.GetProfilesInRange(xmin, ymin, xmax, ymax); + foreach (SimProfileData neighbour in neighbours) + { + regions[neighbour.regionHandle] = neighbour; + } + } + catch + { + MainLog.Instance.Warn("storage", "Unable to query regionblock via " + kvp.Key); + } + } + + return regions; + } + + + + /// + /// Returns a XML String containing a list of the neighbouring regions + /// + /// The regionhandle for the center sim + /// An XML string containing neighbour entities + public string GetXMLNeighbours(ulong reqhandle) + { + string response = ""; + SimProfileData central_region = getRegion(reqhandle); + SimProfileData neighbour; + for (int x = -1; x < 2; x++) for (int y = -1; y < 2; y++) + { + if (getRegion(Util.UIntsToLong((uint)((central_region.regionLocX + x) * 256), (uint)(central_region.regionLocY + y) * 256)) != null) + { + neighbour = getRegion(Util.UIntsToLong((uint)((central_region.regionLocX + x) * 256), (uint)(central_region.regionLocY + y) * 256)); + response += ""; + response += "" + neighbour.serverIP + ""; + response += "" + neighbour.serverPort.ToString() + ""; + response += "" + neighbour.regionLocX.ToString() + ""; + response += "" + neighbour.regionLocY.ToString() + ""; + response += "" + neighbour.regionHandle.ToString() + ""; + response += ""; + + } + } + return response; + } + + /// + /// Performed when a region connects to the grid server initially. + /// + /// The XMLRPC Request + /// Startup parameters + public XmlRpcResponse XmlRpcSimulatorLoginMethod(XmlRpcRequest request) + { + + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable responseData = new Hashtable(); + response.Value = responseData; + + SimProfileData TheSim = null; + Hashtable requestData = (Hashtable)request.Params[0]; + string myword; + if (requestData.ContainsKey("UUID")) + { + TheSim = getRegion(new LLUUID((string)requestData["UUID"])); + +// logToDB((new LLUUID((string)requestData["UUID"])).ToStringHyphenated(),"XmlRpcSimulatorLoginMethod","", 5,"Region attempting login with UUID."); + } + else if (requestData.ContainsKey("region_handle")) + { + +// TheSim = getRegion((ulong)Convert.ToUInt64(requestData["region_handle"])); +// logToDB((string)requestData["region_handle"], "XmlRpcSimulatorLoginMethod", "", 5, "Region attempting login with regionHandle."); + } + else + { + responseData["error"] = "No UUID or region_handle passed to grid server - unable to connect you"; + return response; + } + + if (TheSim == null) // Shouldnt this be in the REST Simulator Set method? + { + Console.WriteLine("NEW SIM"); + myword = "creation"; + } + else + { + myword = "connection"; + } + + TheSim = new SimProfileData(); + + TheSim.regionRecvKey = config.SimRecvKey; + TheSim.regionSendKey = config.SimSendKey; + TheSim.regionSecret = config.SimRecvKey; + TheSim.regionDataURI = ""; + TheSim.regionAssetURI = config.DefaultAssetServer; + TheSim.regionAssetRecvKey = config.AssetRecvKey; + TheSim.regionAssetSendKey = config.AssetSendKey; + TheSim.regionUserURI = config.DefaultUserServer; + TheSim.regionUserSendKey = config.UserSendKey; + TheSim.regionUserRecvKey = config.UserRecvKey; + + TheSim.serverIP = (string)requestData["sim_ip"]; + TheSim.serverPort = Convert.ToUInt32((string)requestData["sim_port"]); + TheSim.httpPort = Convert.ToUInt32((string)requestData["http_port"]); + TheSim.remotingPort = Convert.ToUInt32((string)requestData["remoting_port"]); + TheSim.regionLocX = Convert.ToUInt32((string)requestData["region_locx"]); + TheSim.regionLocY = Convert.ToUInt32((string)requestData["region_locy"]); + TheSim.regionLocZ = 0; + TheSim.regionMapTextureID = new LLUUID((string)requestData["map-image-id"]); + + TheSim.regionHandle = Helpers.UIntsToLong((TheSim.regionLocX * 256), (TheSim.regionLocY * 256)); + System.Console.WriteLine("adding region " + TheSim.regionLocX + " , " + TheSim.regionLocY + " , " + TheSim.serverURI); + TheSim.serverURI = "http://" + TheSim.serverIP + ":" + TheSim.serverPort + "/"; + TheSim.httpServerURI = "http://" + TheSim.serverIP + ":" + TheSim.httpPort + "/"; + + + TheSim.regionName = (string)requestData["sim_name"]; + TheSim.UUID = new LLUUID((string)requestData["UUID"]); + + foreach (KeyValuePair kvp in _plugins) + { + try + { + DataResponse insertResponse = kvp.Value.AddProfile(TheSim); + switch(insertResponse) + { + case DataResponse.RESPONSE_OK: + OpenSim.Framework.Console.MainLog.Instance.Verbose("grid", "New sim " + myword + " successful: " + TheSim.regionName); + break; + case DataResponse.RESPONSE_ERROR: + OpenSim.Framework.Console.MainLog.Instance.Warn("storage", "New sim creation failed (Error): " + TheSim.regionName); + break; + case DataResponse.RESPONSE_INVALIDCREDENTIALS: + OpenSim.Framework.Console.MainLog.Instance.Warn("storage", "New sim creation failed (Invalid Credentials): " + TheSim.regionName); + break; + case DataResponse.RESPONSE_AUTHREQUIRED: + OpenSim.Framework.Console.MainLog.Instance.Warn("storage", "New sim creation failed (Authentication Required): " + TheSim.regionName); + break; + } + + } + catch (Exception e) + { + OpenSim.Framework.Console.MainLog.Instance.Warn("storage", "Unable to add region " + TheSim.UUID.ToStringHyphenated() + " via " + kvp.Key); + OpenSim.Framework.Console.MainLog.Instance.Warn("storage", e.ToString()); + } + + + + if (getRegion(TheSim.regionHandle) == null) + { + responseData["error"] = "Unable to add new region"; + return response; + } + } + + + ArrayList SimNeighboursData = new ArrayList(); + + SimProfileData neighbour; + Hashtable NeighbourBlock; + + bool fastMode = false; // Only compatible with MySQL right now + + if (fastMode) + { + Dictionary neighbours = getRegions(TheSim.regionLocX - 1, TheSim.regionLocY - 1, TheSim.regionLocX + 1, TheSim.regionLocY + 1); + + foreach (KeyValuePair aSim in neighbours) + { + NeighbourBlock = new Hashtable(); + NeighbourBlock["sim_ip"] = Util.GetHostFromDNS(aSim.Value.serverIP.ToString()).ToString(); + NeighbourBlock["sim_port"] = aSim.Value.serverPort.ToString(); + NeighbourBlock["region_locx"] = aSim.Value.regionLocX.ToString(); + NeighbourBlock["region_locy"] = aSim.Value.regionLocY.ToString(); + NeighbourBlock["UUID"] = aSim.Value.UUID.ToString(); + + if (aSim.Value.UUID != TheSim.UUID) + SimNeighboursData.Add(NeighbourBlock); + } + } + else + { + for (int x = -1; x < 2; x++) for (int y = -1; y < 2; y++) + { + if (getRegion(Helpers.UIntsToLong((uint)((TheSim.regionLocX + x) * 256), (uint)(TheSim.regionLocY + y) * 256)) != null) + { + neighbour = getRegion(Helpers.UIntsToLong((uint)((TheSim.regionLocX + x) * 256), (uint)(TheSim.regionLocY + y) * 256)); + + NeighbourBlock = new Hashtable(); + NeighbourBlock["sim_ip"] = Util.GetHostFromDNS(neighbour.serverIP).ToString(); + NeighbourBlock["sim_port"] = neighbour.serverPort.ToString(); + NeighbourBlock["region_locx"] = neighbour.regionLocX.ToString(); + NeighbourBlock["region_locy"] = neighbour.regionLocY.ToString(); + NeighbourBlock["UUID"] = neighbour.UUID.ToString(); + + if (neighbour.UUID != TheSim.UUID) SimNeighboursData.Add(NeighbourBlock); + } + } + } + + responseData["UUID"] = TheSim.UUID.ToString(); + responseData["region_locx"] = TheSim.regionLocX.ToString(); + responseData["region_locy"] = TheSim.regionLocY.ToString(); + responseData["regionname"] = TheSim.regionName; + responseData["estate_id"] = "1"; + responseData["neighbours"] = SimNeighboursData; + + responseData["sim_ip"] = TheSim.serverIP; + responseData["sim_port"] = TheSim.serverPort.ToString(); + responseData["asset_url"] = TheSim.regionAssetURI; + responseData["asset_sendkey"] = TheSim.regionAssetSendKey; + responseData["asset_recvkey"] = TheSim.regionAssetRecvKey; + responseData["user_url"] = TheSim.regionUserURI; + responseData["user_sendkey"] = TheSim.regionUserSendKey; + responseData["user_recvkey"] = TheSim.regionUserRecvKey; + responseData["authkey"] = TheSim.regionSecret; + + // New! If set, use as URL to local sim storage (ie http://remotehost/region.yap) + responseData["data_uri"] = TheSim.regionDataURI; + + + return response; + } + + public XmlRpcResponse XmlRpcSimulatorDataRequestMethod(XmlRpcRequest request) + { + Hashtable requestData = (Hashtable)request.Params[0]; + Hashtable responseData = new Hashtable(); + SimProfileData simData = null; + if (requestData.ContainsKey("region_UUID")) + { + simData = getRegion(new LLUUID((string)requestData["region_UUID"])); + } + else if (requestData.ContainsKey("region_handle")) + { + Console.WriteLine("requesting data for region " + (string)requestData["region_handle"]); + simData = getRegion(Convert.ToUInt64((string)requestData["region_handle"])); + } + + if (simData == null) + { + //Sim does not exist + Console.WriteLine("region not found"); + responseData["error"] = "Sim does not exist"; + } + else + { + Console.WriteLine("found region"); + responseData["sim_ip"] = Util.GetHostFromDNS(simData.serverIP).ToString(); + responseData["sim_port"] = simData.serverPort.ToString(); + responseData["http_port"] = simData.httpPort.ToString(); + responseData["remoting_port"] = simData.remotingPort.ToString(); + responseData["region_locx"] = simData.regionLocX.ToString() ; + responseData["region_locy"] = simData.regionLocY.ToString(); + responseData["region_UUID"] = simData.UUID.UUID.ToString(); + responseData["region_name"] = simData.regionName; + } + + XmlRpcResponse response = new XmlRpcResponse(); + response.Value = responseData; + return response; + } + + public XmlRpcResponse XmlRpcMapBlockMethod(XmlRpcRequest request) + { + int xmin=980, ymin=980, xmax=1020, ymax=1020; + + Hashtable requestData = (Hashtable)request.Params[0]; + if (requestData.ContainsKey("xmin")) + { + xmin = (Int32)requestData["xmin"]; + } + if (requestData.ContainsKey("ymin")) + { + ymin = (Int32)requestData["ymin"]; + } + if (requestData.ContainsKey("xmax")) + { + xmax = (Int32)requestData["xmax"]; + } + if (requestData.ContainsKey("ymax")) + { + ymax = (Int32)requestData["ymax"]; + } + + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable responseData = new Hashtable(); + response.Value = responseData; + IList simProfileList = new ArrayList(); + + bool fastMode = false; // MySQL Only + + if (fastMode) + { + Dictionary neighbours = getRegions((uint)xmin, (uint)ymin, (uint)xmax, (uint)ymax); + + foreach (KeyValuePair aSim in neighbours) + { + Hashtable simProfileBlock = new Hashtable(); + simProfileBlock["x"] = aSim.Value.regionLocX.ToString(); + simProfileBlock["y"] = aSim.Value.regionLocY.ToString(); + System.Console.WriteLine("send neighbour info for " + aSim.Value.regionLocX.ToString() + " , " + aSim.Value.regionLocY.ToString()); + simProfileBlock["name"] = aSim.Value.regionName; + simProfileBlock["access"] = 21; + simProfileBlock["region-flags"] = 512; + simProfileBlock["water-height"] = 0; + simProfileBlock["agents"] = 1; + simProfileBlock["map-image-id"] = aSim.Value.regionMapTextureID.ToString(); + + // For Sugilite compatibility + simProfileBlock["regionhandle"] = aSim.Value.regionHandle.ToString(); + simProfileBlock["sim_ip"] = aSim.Value.serverIP.ToString(); + simProfileBlock["sim_port"] = aSim.Value.serverPort.ToString(); + simProfileBlock["sim_uri"] = aSim.Value.serverURI.ToString(); + simProfileBlock["uuid"] = aSim.Value.UUID.ToStringHyphenated(); + + simProfileList.Add(simProfileBlock); + } + MainLog.Instance.Verbose("World map request processed, returned " + simProfileList.Count.ToString() + " region(s) in range via FastMode"); + } + else + { + SimProfileData simProfile; + for (int x = xmin; x < xmax+1; x++) + { + for (int y = ymin; y < ymax+1; y++) + { + ulong regHandle = Helpers.UIntsToLong((uint)(x * 256), (uint)(y * 256)); + simProfile = getRegion(regHandle); + if (simProfile != null) + { + Hashtable simProfileBlock = new Hashtable(); + simProfileBlock["x"] = x; + simProfileBlock["y"] = y; + simProfileBlock["name"] = simProfile.regionName; + simProfileBlock["access"] = 0; + simProfileBlock["region-flags"] = 0; + simProfileBlock["water-height"] = 20; + simProfileBlock["agents"] = 1; + simProfileBlock["map-image-id"] = simProfile.regionMapTextureID.ToStringHyphenated(); + + // For Sugilite compatibility + simProfileBlock["regionhandle"] = simProfile.regionHandle.ToString(); + simProfileBlock["sim_ip"] = simProfile.serverIP.ToString(); + simProfileBlock["sim_port"] = simProfile.serverPort.ToString(); + simProfileBlock["sim_uri"] = simProfile.serverURI.ToString(); + simProfileBlock["uuid"] = simProfile.UUID.ToStringHyphenated(); + + simProfileList.Add(simProfileBlock); + } + } + } + MainLog.Instance.Verbose("World map request processed, returned " + simProfileList.Count.ToString() + " region(s) in range via Standard Mode"); + } + + responseData["sim-profiles"] = simProfileList; + + return response; + } + + + + /// + /// Performs a REST Get Operation + /// + /// + /// + /// + /// + public string RestGetRegionMethod(string request, string path, string param) + { + return RestGetSimMethod("", "/sims/", param); + } + + /// + /// Performs a REST Set Operation + /// + /// + /// + /// + /// + public string RestSetRegionMethod(string request, string path, string param) + { + return RestSetSimMethod("", "/sims/", param); + } + + /// + /// Returns information about a sim via a REST Request + /// + /// + /// + /// + /// Information about the sim in XML + public string RestGetSimMethod(string request, string path, string param) + { + string respstring = String.Empty; + + SimProfileData TheSim; + LLUUID UUID = new LLUUID(param); + TheSim = getRegion(UUID); + + if (!(TheSim == null)) + { + respstring = ""; + respstring += "" + TheSim.regionSendKey + ""; + respstring += ""; + respstring += "" + TheSim.UUID.ToString() + ""; + respstring += "" + TheSim.regionName + ""; + respstring += "" + Util.GetHostFromDNS(TheSim.serverIP).ToString() + ""; + respstring += "" + TheSim.serverPort.ToString() + ""; + respstring += "" + TheSim.regionLocX.ToString() + ""; + respstring += "" + TheSim.regionLocY.ToString() + ""; + respstring += "1"; + respstring += ""; + respstring += ""; + } + + return respstring; + } + + /// + /// Creates or updates a sim via a REST Method Request + /// BROKEN with SQL Update + /// + /// + /// + /// + /// "OK" or an error + public string RestSetSimMethod(string request, string path, string param) + { + Console.WriteLine("Processing region update via REST method"); + SimProfileData TheSim; + TheSim = getRegion(new LLUUID(param)); + if ((TheSim) == null) + { + TheSim = new SimProfileData(); + LLUUID UUID = new LLUUID(param); + TheSim.UUID = UUID; + TheSim.regionRecvKey = config.SimRecvKey; + } + + XmlDocument doc = new XmlDocument(); + doc.LoadXml(request); + XmlNode rootnode = doc.FirstChild; + XmlNode authkeynode = rootnode.ChildNodes[0]; + if (authkeynode.Name != "authkey") + { + return "ERROR! bad XML - expected authkey tag"; + } + + XmlNode simnode = rootnode.ChildNodes[1]; + if (simnode.Name != "sim") + { + return "ERROR! bad XML - expected sim tag"; + } + + //TheSim.regionSendKey = Cfg; + TheSim.regionRecvKey = config.SimRecvKey; + TheSim.regionSendKey = config.SimSendKey; + TheSim.regionSecret = config.SimRecvKey; + TheSim.regionDataURI = ""; + TheSim.regionAssetURI = config.DefaultAssetServer; + TheSim.regionAssetRecvKey = config.AssetRecvKey; + TheSim.regionAssetSendKey = config.AssetSendKey; + TheSim.regionUserURI = config.DefaultUserServer; + TheSim.regionUserSendKey = config.UserSendKey; + TheSim.regionUserRecvKey = config.UserRecvKey; + + + for (int i = 0; i < simnode.ChildNodes.Count; i++) + { + switch (simnode.ChildNodes[i].Name) + { + case "regionname": + TheSim.regionName = simnode.ChildNodes[i].InnerText; + break; + + case "sim_ip": + TheSim.serverIP = simnode.ChildNodes[i].InnerText; + break; + + case "sim_port": + TheSim.serverPort = Convert.ToUInt32(simnode.ChildNodes[i].InnerText); + break; + + case "region_locx": + TheSim.regionLocX = Convert.ToUInt32((string)simnode.ChildNodes[i].InnerText); + TheSim.regionHandle = Helpers.UIntsToLong((TheSim.regionLocX * 256), (TheSim.regionLocY * 256)); + break; + + case "region_locy": + TheSim.regionLocY = Convert.ToUInt32((string)simnode.ChildNodes[i].InnerText); + TheSim.regionHandle = Helpers.UIntsToLong((TheSim.regionLocX * 256), (TheSim.regionLocY * 256)); + break; + } + } + + TheSim.serverURI = "http://" + TheSim.serverIP + ":" + TheSim.serverPort + "/"; + + bool requirePublic = false; + bool requireValid = true; + + if (requirePublic && (TheSim.serverIP.StartsWith("172.16") || TheSim.serverIP.StartsWith("192.168") || TheSim.serverIP.StartsWith("10.") || TheSim.serverIP.StartsWith("0.") || TheSim.serverIP.StartsWith("255."))) + { + return "ERROR! Servers must register with public addresses."; + } + + if (requireValid && (TheSim.serverIP.StartsWith("0."))) + { + return "ERROR! 0.*.*.* Addresses are invalid, please check your server config and try again"; + } + + + try + { + MainLog.Instance.Verbose("Updating / adding via " + _plugins.Count + " storage provider(s) registered."); + foreach (KeyValuePair kvp in _plugins) + { + try + { + //Check reservations + ReservationData reserveData = kvp.Value.GetReservationAtPoint(TheSim.regionLocX, TheSim.regionLocY); + if ((reserveData != null && reserveData.gridRecvKey == TheSim.regionRecvKey) || (reserveData == null && authkeynode.InnerText != TheSim.regionRecvKey)) + { + kvp.Value.AddProfile(TheSim); + MainLog.Instance.Verbose("grid", "New sim added to grid (" + TheSim.regionName + ")"); + logToDB(TheSim.UUID.ToStringHyphenated(), "RestSetSimMethod", "", 5, "Region successfully updated and connected to grid."); + } + else + { + MainLog.Instance.Warn("grid", "Unable to update region (RestSetSimMethod): Incorrect reservation auth key.");// Wanted: " + reserveData.gridRecvKey + ", Got: " + TheSim.regionRecvKey + "."); + return "Unable to update region (RestSetSimMethod): Incorrect auth key."; + } + } + catch (Exception e) + { + MainLog.Instance.Verbose("getRegionPlugin Handle " + kvp.Key + " unable to add new sim: " + e.ToString()); + } + } + return "OK"; + } + catch (Exception e) + { + return "ERROR! Could not save to database! (" + e.ToString() + ")"; + } + } + + } +} diff --git a/OpenSim/Grid/GridServer/Main.cs b/OpenSim/Grid/GridServer/Main.cs new file mode 100644 index 0000000000..c3d84eb71f --- /dev/null +++ b/OpenSim/Grid/GridServer/Main.cs @@ -0,0 +1,228 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.IO; +using System.Reflection; +using System.Threading; +using System.Timers; +using OpenSim.Framework.Console; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Configuration; +using OpenSim.Framework.Utilities; + +using Timer=System.Timers.Timer; + +namespace OpenSim.Grid.GridServer +{ + /// + /// + public class OpenGrid_Main : conscmd_callback + { + public GridConfig Cfg; + + public static OpenGrid_Main thegrid; + + public static bool setuponly; + + //public LLUUID highestUUID; + + // private SimProfileManager m_simProfileManager; + + private GridManager m_gridManager; + + private LogBase m_console; + + [STAThread] + public static void Main(string[] args) + { + if (args.Length > 0) + { + if (args[0] == "-setuponly") setuponly = true; + } + Console.WriteLine("Starting...\n"); + + thegrid = new OpenGrid_Main(); + thegrid.Startup(); + + thegrid.Work(); + } + + private void Work() + { + m_console.Notice("Enter help for a list of commands\n"); + + while (true) + { + m_console.MainLogPrompt(); + } + } + + private OpenGrid_Main() + { + if (!Directory.Exists(Util.logDir())) + { + Directory.CreateDirectory(Util.logDir()); + } + m_console = new LogBase((Path.Combine(Util.logDir(),"opengrid-gridserver-console.log")), "OpenGrid", this, false); + MainLog.Instance = m_console; + + + } + + public void managercallback(string cmd) + { + switch (cmd) + { + case "shutdown": + RunCmd("shutdown", new string[0]); + break; + } + } + + + public void Startup() + { + + this.Cfg = new GridConfig("GRID SERVER",(Path.Combine(Util.configDir(),"GridServer_Config.xml"))); //Yeah srsly, that's it. + if (setuponly) Environment.Exit(0); + + m_console.Verbose( "Main.cs:Startup() - Connecting to Storage Server"); + m_gridManager = new GridManager(); + m_gridManager.AddPlugin(Cfg.DatabaseProvider); // Made of win + m_gridManager.config = Cfg; + + m_console.Verbose( "Main.cs:Startup() - Starting HTTP process"); + BaseHttpServer httpServer = new BaseHttpServer(8001); + //GridManagementAgent GridManagerAgent = new GridManagementAgent(httpServer, "gridserver", Cfg.SimSendKey, Cfg.SimRecvKey, managercallback); + + httpServer.AddXmlRPCHandler("simulator_login", m_gridManager.XmlRpcSimulatorLoginMethod); + httpServer.AddXmlRPCHandler("simulator_data_request", m_gridManager.XmlRpcSimulatorDataRequestMethod); + httpServer.AddXmlRPCHandler("map_block", m_gridManager.XmlRpcMapBlockMethod); + + httpServer.AddStreamHandler(new RestStreamHandler("GET", "/sims/", m_gridManager.RestGetSimMethod )); + httpServer.AddStreamHandler(new RestStreamHandler("POST", "/sims/", m_gridManager.RestSetSimMethod )); + + httpServer.AddStreamHandler( new RestStreamHandler("GET", "/regions/", m_gridManager.RestGetRegionMethod )); + httpServer.AddStreamHandler( new RestStreamHandler("POST","/regions/", m_gridManager.RestSetRegionMethod )); + + //httpServer.AddRestHandler("GET", "/sims/", m_gridManager.RestGetSimMethod); + //httpServer.AddRestHandler("POST", "/sims/", m_gridManager.RestSetSimMethod); + //httpServer.AddRestHandler("GET", "/regions/", m_gridManager.RestGetRegionMethod); + //httpServer.AddRestHandler("POST", "/regions/", m_gridManager.RestSetRegionMethod); + + httpServer.Start(); + + m_console.Verbose( "Main.cs:Startup() - Starting sim status checker"); + + Timer simCheckTimer = new Timer(3600000 * 3); // 3 Hours between updates. + simCheckTimer.Elapsed += new ElapsedEventHandler(CheckSims); + simCheckTimer.Enabled = true; + } + + public void CheckSims(object sender, ElapsedEventArgs e) + { + /* + foreach (SimProfileBase sim in m_simProfileManager.SimProfiles.Values) + { + string SimResponse = ""; + try + { + WebRequest CheckSim = WebRequest.Create("http://" + sim.sim_ip + ":" + sim.sim_port.ToString() + "/checkstatus/"); + CheckSim.Method = "GET"; + CheckSim.ContentType = "text/plaintext"; + CheckSim.ContentLength = 0; + + StreamWriter stOut = new StreamWriter(CheckSim.GetRequestStream(), System.Text.Encoding.ASCII); + stOut.Write(""); + stOut.Close(); + + StreamReader stIn = new StreamReader(CheckSim.GetResponse().GetResponseStream()); + SimResponse = stIn.ReadToEnd(); + stIn.Close(); + } + catch + { + } + + if (SimResponse == "OK") + { + m_simProfileManager.SimProfiles[sim.UUID].online = true; + } + else + { + m_simProfileManager.SimProfiles[sim.UUID].online = false; + } + } + */ + } + + public void RunCmd(string cmd, string[] cmdparams) + { + switch (cmd) + { + case "help": + m_console.Notice("shutdown - shutdown the grid (USE CAUTION!)"); + break; + + case "shutdown": + m_console.Close(); + Environment.Exit(0); + break; + } + } + + public void Show(string ShowWhat) + { + } + + /*private void ConfigDB(IGenericConfig configData) + { + try + { + string attri = ""; + attri = configData.GetAttribute("DataBaseProvider"); + if (attri == "") + { + GridDll = "OpenSim.Framework.Data.DB4o.dll"; + configData.SetAttribute("DataBaseProvider", "OpenSim.Framework.Data.DB4o.dll"); + } + else + { + GridDll = attri; + } + configData.Commit(); + } + catch + { + + } + }*/ + } +} diff --git a/OpenSim/Grid/GridServer/Properties/AssemblyInfo.cs b/OpenSim/Grid/GridServer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..62a68a8d8e --- /dev/null +++ b/OpenSim/Grid/GridServer/Properties/AssemblyInfo.cs @@ -0,0 +1,58 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OGS-GridServer")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OGS-GridServer")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("b541b244-3d1d-4625-9003-bc2a3a6a39a4")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Grid/InventoryServer/InventoryManager.cs b/OpenSim/Grid/InventoryServer/InventoryManager.cs new file mode 100644 index 0000000000..9ca9b5e749 --- /dev/null +++ b/OpenSim/Grid/InventoryServer/InventoryManager.cs @@ -0,0 +1,125 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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; +using System.Collections.Generic; +using System.Text; +using OpenGrid.Framework.Data; +using libsecondlife; +using System.Reflection; + +using System.Xml; +using Nwc.XmlRpc; +using OpenSim.Framework.Sims; +using OpenSim.Framework.Inventory; +using OpenSim.Framework.Utilities; + +using System.Security.Cryptography; + +namespace OpenGridServices.InventoryServer +{ + class InventoryManager + { + Dictionary _plugins = new Dictionary(); + + /// + /// Adds a new inventory server plugin - user servers will be requested in the order they were loaded. + /// + /// The filename to the inventory server plugin DLL + public void AddPlugin(string FileName) + { + OpenSim.Framework.Console.MainConsole.Instance.Verbose( "Invenstorage: Attempting to load " + FileName); + Assembly pluginAssembly = Assembly.LoadFrom(FileName); + + OpenSim.Framework.Console.MainConsole.Instance.Verbose( "Invenstorage: Found " + pluginAssembly.GetTypes().Length + " interfaces."); + foreach (Type pluginType in pluginAssembly.GetTypes()) + { + if (!pluginType.IsAbstract) + { + Type typeInterface = pluginType.GetInterface("IInventoryData", true); + + if (typeInterface != null) + { + IInventoryData plug = (IInventoryData)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); + plug.Initialise(); + this._plugins.Add(plug.getName(), plug); + OpenSim.Framework.Console.MainConsole.Instance.Verbose( "Invenstorage: Added IUserData Interface"); + } + + typeInterface = null; + } + } + + pluginAssembly = null; + } + + public List getRootFolders(LLUUID user) + { + foreach (KeyValuePair kvp in _plugins) + { + try + { + return kvp.Value.getUserRootFolders(user); + } + catch (Exception e) + { + OpenSim.Framework.Console.MainConsole.Instance.Notice("Unable to get root folders via " + kvp.Key + " (" + e.ToString() + ")"); + } + } + return null; + } + + public XmlRpcResponse XmlRpcInventoryRequest(XmlRpcRequest request) + { + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable requestData = (Hashtable)request.Params[0]; + + Hashtable responseData = new Hashtable(); + + // Stuff happens here + + if (requestData.ContainsKey("Access-type")) + { + if (requestData["access-type"] == "rootfolders") + { +// responseData["rootfolders"] = + } + } + else + { + responseData["error"] = "No access-type specified."; + } + + + // Stuff stops happening here + + response.Value = responseData; + return response; + } + } +} diff --git a/OpenSim/Grid/InventoryServer/Main.cs b/OpenSim/Grid/InventoryServer/Main.cs new file mode 100644 index 0000000000..f479a79b7c --- /dev/null +++ b/OpenSim/Grid/InventoryServer/Main.cs @@ -0,0 +1,87 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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; +using System.Collections.Generic; +using System.Reflection; +using System.IO; +using System.Text; +using libsecondlife; +using OpenSim.Framework.User; +using OpenSim.Framework.Sims; +using OpenSim.Framework.Inventory; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Console; +using OpenSim.Servers; +using OpenSim.Framework.Utilities; + +namespace OpenGridServices.InventoryServer +{ + public class OpenInventory_Main : BaseServer, conscmd_callback + { + ConsoleBase m_console; + InventoryManager m_inventoryManager; + + public static void Main(string[] args) + { + } + + public OpenInventory_Main() + { + m_console = new ConsoleBase("opengrid-inventory-console.log", "OpenInventory", this, false); + MainConsole.Instance = m_console; + } + + public void Startup() + { + MainConsole.Instance.Notice("Initialising inventory manager..."); + m_inventoryManager = new InventoryManager(); + + MainConsole.Instance.Notice("Starting HTTP server"); + BaseHttpServer httpServer = new BaseHttpServer(8004); + + httpServer.AddXmlRPCHandler("rootfolders", m_inventoryManager.XmlRpcInventoryRequest); + //httpServer.AddRestHandler("GET","/rootfolders/",Rest + } + + public void RunCmd(string cmd, string[] cmdparams) + { + switch (cmd) + { + case "shutdown": + m_console.Close(); + Environment.Exit(0); + break; + } + } + + public void Show(string ShowWhat) + { + } + } +} diff --git a/OpenSim/Grid/Manager/OpenGridServices.Manager.mds b/OpenSim/Grid/Manager/OpenGridServices.Manager.mds new file mode 100644 index 0000000000..1a5740de19 --- /dev/null +++ b/OpenSim/Grid/Manager/OpenGridServices.Manager.mds @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OpenSim/Grid/Manager/OpenGridServices.Manager.userprefs b/OpenSim/Grid/Manager/OpenGridServices.Manager.userprefs new file mode 100644 index 0000000000..00e7f64634 --- /dev/null +++ b/OpenSim/Grid/Manager/OpenGridServices.Manager.userprefs @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OpenSim/Grid/Manager/OpenGridServices.Manager.usertasks b/OpenSim/Grid/Manager/OpenGridServices.Manager.usertasks new file mode 100644 index 0000000000..590716dd00 --- /dev/null +++ b/OpenSim/Grid/Manager/OpenGridServices.Manager.usertasks @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/OpenSim/Grid/Manager/OpenGridServices.Manager/AssemblyInfo.cs b/OpenSim/Grid/Manager/OpenGridServices.Manager/AssemblyInfo.cs new file mode 100644 index 0000000000..dbacda112e --- /dev/null +++ b/OpenSim/Grid/Manager/OpenGridServices.Manager/AssemblyInfo.cs @@ -0,0 +1,32 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following +// attributes. +// +// change them to the information which is associated with the assembly +// you compile. + +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all values by your own or you can build default build and revision +// numbers with the '*' character (the default): + +[assembly: AssemblyVersion("1.0.*")] + +// The following attributes specify the key for the sign of your assembly. See the +// .NET Framework documentation for more information about signing. +// This is not required, if you don't want signing let these attributes like they're. +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] diff --git a/OpenSim/Grid/Manager/OpenGridServices.Manager/BlockingQueue.cs b/OpenSim/Grid/Manager/OpenGridServices.Manager/BlockingQueue.cs new file mode 100644 index 0000000000..83685fc3c9 --- /dev/null +++ b/OpenSim/Grid/Manager/OpenGridServices.Manager/BlockingQueue.cs @@ -0,0 +1,33 @@ +using System; +using System.Threading; +using System.Collections.Generic; +using System.Text; + +namespace OpenGridServices.Manager +{ + public class BlockingQueue + { + private Queue _queue = new Queue(); + private object _queueSync = new object(); + + public void Enqueue(T value) + { + lock (_queueSync) + { + _queue.Enqueue(value); + Monitor.Pulse(_queueSync); + } + } + + public T Dequeue() + { + lock (_queueSync) + { + if (_queue.Count < 1) + Monitor.Wait(_queueSync); + + return _queue.Dequeue(); + } + } + } +} diff --git a/OpenSim/Grid/Manager/OpenGridServices.Manager/ConnectToGridServer.cs b/OpenSim/Grid/Manager/OpenGridServices.Manager/ConnectToGridServer.cs new file mode 100644 index 0000000000..909cb8afca --- /dev/null +++ b/OpenSim/Grid/Manager/OpenGridServices.Manager/ConnectToGridServer.cs @@ -0,0 +1,16 @@ + +using System; + +namespace OpenGridServices.Manager +{ + + + public partial class Connect to grid server : Gtk.Dialog + { + + public Connect to grid server() + { + this.Build(); + } + } +} diff --git a/OpenSim/Grid/Manager/OpenGridServices.Manager/ConnectToGridServerDialog.cs b/OpenSim/Grid/Manager/OpenGridServices.Manager/ConnectToGridServerDialog.cs new file mode 100644 index 0000000000..49a6dda1b0 --- /dev/null +++ b/OpenSim/Grid/Manager/OpenGridServices.Manager/ConnectToGridServerDialog.cs @@ -0,0 +1,29 @@ +using Gtk; +using System; + +namespace OpenGridServices.Manager { + public partial class ConnectToGridServerDialog : Gtk.Dialog + { + + public ConnectToGridServerDialog() + { + this.Build(); + } + + protected virtual void OnResponse(object o, Gtk.ResponseArgs args) + { + switch(args.ResponseId) { + case Gtk.ResponseType.Ok: + MainClass.PendingOperations.Enqueue("connect_to_gridserver " + this.entry1.Text + " " + this.entry2.Text + " " + this.entry3.Text); + break; + + case Gtk.ResponseType.Cancel: + break; + } + this.Hide(); + + } + + } + +} \ No newline at end of file diff --git a/OpenSim/Grid/Manager/OpenGridServices.Manager/GridServerConnectionManager.cs b/OpenSim/Grid/Manager/OpenGridServices.Manager/GridServerConnectionManager.cs new file mode 100644 index 0000000000..354acb6e93 --- /dev/null +++ b/OpenSim/Grid/Manager/OpenGridServices.Manager/GridServerConnectionManager.cs @@ -0,0 +1,106 @@ +using Nwc.XmlRpc; +using System; +using System.Net; +using System.IO; +using System.Xml; +using System.Collections; +using System.Collections.Generic; +using libsecondlife; + +namespace OpenGridServices.Manager +{ + public class GridServerConnectionManager + { + private string ServerURL; + public LLUUID SessionID; + public bool connected=false; + + public RegionBlock[][] WorldMap; + + public bool Connect(string GridServerURL, string username, string password) + { + try { + this.ServerURL=GridServerURL; + Hashtable LoginParamsHT = new Hashtable(); + LoginParamsHT["username"]=username; + LoginParamsHT["password"]=password; + ArrayList LoginParams = new ArrayList(); + LoginParams.Add(LoginParamsHT); + XmlRpcRequest GridLoginReq = new XmlRpcRequest("manager_login",LoginParams); + XmlRpcResponse GridResp = GridLoginReq.Send(ServerURL,3000); + if(GridResp.IsFault) { + connected=false; + return false; + } else { + Hashtable gridrespData = (Hashtable)GridResp.Value; + this.SessionID = new LLUUID((string)gridrespData["session_id"]); + connected=true; + return true; + } + } catch(Exception e) { + Console.WriteLine(e.ToString()); + connected=false; + return false; + } + } + + public void DownloadMap() + { + System.Net.WebClient mapdownloader = new WebClient(); + Stream regionliststream = mapdownloader.OpenRead(ServerURL + "/regionlist"); + + RegionBlock TempRegionData; + + XmlDocument doc = new XmlDocument(); + doc.Load(regionliststream); + regionliststream.Close(); + XmlNode rootnode = doc.FirstChild; + if (rootnode.Name != "regions") + { + // TODO - ERROR! + } + + for(int i=0; i<=rootnode.ChildNodes.Count; i++) + { + if(rootnode.ChildNodes.Item(i).Name != "region") { + // TODO - ERROR! + } else { + TempRegionData = new RegionBlock(); + + + } + } + } + + public bool RestartServer() + { + return true; + } + + public bool ShutdownServer() + { + try { + Hashtable ShutdownParamsHT = new Hashtable(); + ArrayList ShutdownParams = new ArrayList(); + ShutdownParamsHT["session_id"]=this.SessionID.ToString(); + ShutdownParams.Add(ShutdownParamsHT); + XmlRpcRequest GridShutdownReq = new XmlRpcRequest("shutdown",ShutdownParams); + XmlRpcResponse GridResp = GridShutdownReq.Send(this.ServerURL,3000); + if(GridResp.IsFault) { + return false; + } else { + connected=false; + return true; + } + } catch(Exception e) { + Console.WriteLine(e.ToString()); + return false; + } + } + + public void DisconnectServer() + { + this.connected=false; + } + } +} diff --git a/OpenSim/Grid/Manager/OpenGridServices.Manager/Main.cs b/OpenSim/Grid/Manager/OpenGridServices.Manager/Main.cs new file mode 100644 index 0000000000..8b9e4403a3 --- /dev/null +++ b/OpenSim/Grid/Manager/OpenGridServices.Manager/Main.cs @@ -0,0 +1,96 @@ +// project created on 5/14/2007 at 2:04 PM +using System; +using System.Threading; +using Gtk; + +namespace OpenGridServices.Manager +{ + class MainClass + { + + public static bool QuitReq=false; + public static BlockingQueue PendingOperations = new BlockingQueue(); + + private static Thread OperationsRunner; + + private static GridServerConnectionManager gridserverConn; + + private static MainWindow win; + + public static void DoMainLoop() + { + while(!QuitReq) + { + Application.RunIteration(); + } + } + + public static void RunOperations() + { + string operation; + string cmd; + char[] sep = new char[1]; + sep[0]=' '; + while(!QuitReq) + { + operation=PendingOperations.Dequeue(); + Console.WriteLine(operation); + cmd = operation.Split(sep)[0]; + switch(cmd) { + case "connect_to_gridserver": + win.SetStatus("Connecting to grid server..."); + if(gridserverConn.Connect(operation.Split(sep)[1],operation.Split(sep)[2],operation.Split(sep)[3])) { + win.SetStatus("Connected OK with session ID:" + gridserverConn.SessionID); + win.SetGridServerConnected(true); + Thread.Sleep(3000); + win.SetStatus("Downloading region maps..."); + gridserverConn.DownloadMap(); + } else { + win.SetStatus("Could not connect"); + } + break; + + case "restart_gridserver": + win.SetStatus("Restarting grid server..."); + if(gridserverConn.RestartServer()) { + win.SetStatus("Restarted server OK"); + Thread.Sleep(3000); + win.SetStatus(""); + } else { + win.SetStatus("Error restarting grid server!!!"); + } + break; + + case "shutdown_gridserver": + win.SetStatus("Shutting down grid server..."); + if(gridserverConn.ShutdownServer()) { + win.SetStatus("Grid server shutdown"); + win.SetGridServerConnected(false); + Thread.Sleep(3000); + win.SetStatus(""); + } else { + win.SetStatus("Could not shutdown grid server!!!"); + } + break; + + case "disconnect_gridserver": + gridserverConn.DisconnectServer(); + win.SetGridServerConnected(false); + break; + } + } + } + + public static void Main (string[] args) + { + gridserverConn = new GridServerConnectionManager(); + Application.Init (); + win = new MainWindow (); + win.Show (); + OperationsRunner = new Thread(new ThreadStart(RunOperations)); + OperationsRunner.IsBackground=true; + OperationsRunner.Start(); + DoMainLoop(); + } + } +} \ No newline at end of file diff --git a/OpenSim/Grid/Manager/OpenGridServices.Manager/MainWindow.cs b/OpenSim/Grid/Manager/OpenGridServices.Manager/MainWindow.cs new file mode 100644 index 0000000000..84a746a0e5 --- /dev/null +++ b/OpenSim/Grid/Manager/OpenGridServices.Manager/MainWindow.cs @@ -0,0 +1,76 @@ +using System; +using Gtk; + +namespace OpenGridServices.Manager { + public partial class MainWindow: Gtk.Window + { + public MainWindow (): base (Gtk.WindowType.Toplevel) + { + Build (); + } + + public void SetStatus(string statustext) + { + this.statusbar1.Pop(0); + this.statusbar1.Push(0,statustext); + } + + public void DrawGrid(RegionBlock[][] regions) + { + for(int x=0; x<=regions.GetUpperBound(0); x++) { + for(int y=0; y<=regions.GetUpperBound(1); y++) { + Gdk.Image themap = new Gdk.Image(Gdk.ImageType.Fastest,Gdk.Visual.System,256,256); + this.drawingarea1.GdkWindow.DrawImage(new Gdk.GC(this.drawingarea1.GdkWindow),themap,0,0,x*256,y*256,256,256); + } + } + } + + public void SetGridServerConnected(bool connected) + { + if(connected) { + this.ConnectToGridserver.Visible=false; + this.DisconnectFromGridServer.Visible=true; + } else { + this.ConnectToGridserver.Visible=true; + this.DisconnectFromGridServer.Visible=false; + } + } + + protected void OnDeleteEvent (object sender, DeleteEventArgs a) + { + Application.Quit (); + MainClass.QuitReq=true; + a.RetVal = true; + } + + protected virtual void QuitMenu(object sender, System.EventArgs e) + { + MainClass.QuitReq=true; + Application.Quit(); + } + + protected virtual void ConnectToGridServerMenu(object sender, System.EventArgs e) + { + ConnectToGridServerDialog griddialog = new ConnectToGridServerDialog (); + griddialog.Show(); + } + + protected virtual void RestartGridserverMenu(object sender, System.EventArgs e) + { + MainClass.PendingOperations.Enqueue("restart_gridserver"); + } + + protected virtual void ShutdownGridserverMenu(object sender, System.EventArgs e) + { + MainClass.PendingOperations.Enqueue("shutdown_gridserver"); + } + + protected virtual void DisconnectGridServerMenu(object sender, System.EventArgs e) + { + MainClass.PendingOperations.Enqueue("disconnect_gridserver"); + } + + } +} + + \ No newline at end of file diff --git a/OpenSim/Grid/Manager/OpenGridServices.Manager/OpenGridServices.Manager.mdp b/OpenSim/Grid/Manager/OpenGridServices.Manager/OpenGridServices.Manager.mdp new file mode 100644 index 0000000000..86c9370a57 --- /dev/null +++ b/OpenSim/Grid/Manager/OpenGridServices.Manager/OpenGridServices.Manager.mdp @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OpenSim/Grid/Manager/OpenGridServices.Manager/OpenGridServices.Manager.pidb b/OpenSim/Grid/Manager/OpenGridServices.Manager/OpenGridServices.Manager.pidb new file mode 100644 index 0000000000..44e7a619a3 Binary files /dev/null and b/OpenSim/Grid/Manager/OpenGridServices.Manager/OpenGridServices.Manager.pidb differ diff --git a/OpenSim/Grid/Manager/OpenGridServices.Manager/RegionBlock.cs b/OpenSim/Grid/Manager/OpenGridServices.Manager/RegionBlock.cs new file mode 100644 index 0000000000..d06e47b11d --- /dev/null +++ b/OpenSim/Grid/Manager/OpenGridServices.Manager/RegionBlock.cs @@ -0,0 +1,37 @@ +using System; +using System.Xml; +using libsecondlife; +using OpenSim.Framework.Utilities; + +namespace OpenGridServices.Manager +{ + + + public class RegionBlock + { + public uint regloc_x; + public uint regloc_y; + + public string httpd_url; + + public string region_name; + + public ulong regionhandle { + get { return Util.UIntsToLong(regloc_x*256,regloc_y*256); } + } + + public Gdk.Pixbuf MiniMap; + + public RegionBlock() + { + } + + public void LoadFromXmlNode(XmlNode sourcenode) + { + this.regloc_x=Convert.ToUInt32(sourcenode.Attributes.GetNamedItem("loc_x").Value); + this.regloc_y=Convert.ToUInt32(sourcenode.Attributes.GetNamedItem("loc_y").Value); + this.region_name=sourcenode.Attributes.GetNamedItem("region_name").Value; + this.httpd_url=sourcenode.Attributes.GetNamedItem("httpd_url").Value; + } + } +} diff --git a/OpenSim/Grid/Manager/OpenGridServices.Manager/Util.cs b/OpenSim/Grid/Manager/OpenGridServices.Manager/Util.cs new file mode 100644 index 0000000000..5bf7ff9126 --- /dev/null +++ b/OpenSim/Grid/Manager/OpenGridServices.Manager/Util.cs @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.Text; +using libsecondlife; +using libsecondlife.Packets; + +namespace OpenSim.Framework.Utilities +{ + public class Util + { + private static Random randomClass = new Random(); + private static uint nextXferID = 5000; + private static object XferLock = new object(); + + public static ulong UIntsToLong(uint X, uint Y) + { + return Helpers.UIntsToLong(X, Y); + } + + public static Random RandomClass + { + get + { + return randomClass; + } + } + + public static uint GetNextXferID() + { + uint id = 0; + lock(XferLock) + { + id = nextXferID; + nextXferID++; + } + return id; + } + + //public static int fast_distance2d(int x, int y) + //{ + // x = System.Math.Abs(x); + // y = System.Math.Abs(y); + + // int min = System.Math.Min(x, y); + + // return (x + y - (min >> 1) - (min >> 2) + (min >> 4)); + //} + + public static string FieldToString(byte[] bytes) + { + return FieldToString(bytes, String.Empty); + } + + /// + /// Convert a variable length field (byte array) to a string, with a + /// field name prepended to each line of the output + /// + /// If the byte array has unprintable characters in it, a + /// hex dump will be put in the string instead + /// The byte array to convert to a string + /// A field name to prepend to each line of output + /// An ASCII string or a string containing a hex dump, minus + /// the null terminator + public static string FieldToString(byte[] bytes, string fieldName) + { + // Check for a common case + if (bytes.Length == 0) return String.Empty; + + StringBuilder output = new StringBuilder(); + bool printable = true; + + for (int i = 0; i < bytes.Length; ++i) + { + // Check if there are any unprintable characters in the array + if ((bytes[i] < 0x20 || bytes[i] > 0x7E) && bytes[i] != 0x09 + && bytes[i] != 0x0D && bytes[i] != 0x0A && bytes[i] != 0x00) + { + printable = false; + break; + } + } + + if (printable) + { + if (fieldName.Length > 0) + { + output.Append(fieldName); + output.Append(": "); + } + + if (bytes[bytes.Length - 1] == 0x00) + output.Append(UTF8Encoding.UTF8.GetString(bytes, 0, bytes.Length - 1)); + else + output.Append(UTF8Encoding.UTF8.GetString(bytes)); + } + else + { + for (int i = 0; i < bytes.Length; i += 16) + { + if (i != 0) + output.Append(Environment.NewLine); + if (fieldName.Length > 0) + { + output.Append(fieldName); + output.Append(": "); + } + + for (int j = 0; j < 16; j++) + { + if ((i + j) < bytes.Length) + output.Append(String.Format("{0:X2} ", bytes[i + j])); + else + output.Append(" "); + } + + for (int j = 0; j < 16 && (i + j) < bytes.Length; j++) + { + if (bytes[i + j] >= 0x20 && bytes[i + j] < 0x7E) + output.Append((char)bytes[i + j]); + else + output.Append("."); + } + } + } + + return output.ToString(); + } + public Util() + { + + } + } +} diff --git a/OpenSim/Grid/Manager/OpenGridServices.Manager/gtk-gui/OpenGridServices.Manager.ConnectToGridServerDialog.cs b/OpenSim/Grid/Manager/OpenGridServices.Manager/gtk-gui/OpenGridServices.Manager.ConnectToGridServerDialog.cs new file mode 100644 index 0000000000..7746c97434 --- /dev/null +++ b/OpenSim/Grid/Manager/OpenGridServices.Manager/gtk-gui/OpenGridServices.Manager.ConnectToGridServerDialog.cs @@ -0,0 +1,226 @@ +// ------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Mono Runtime Version: 2.0.50727.42 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ + +namespace OpenGridServices.Manager { + + + public partial class ConnectToGridServerDialog { + + private Gtk.VBox vbox2; + + private Gtk.VBox vbox3; + + private Gtk.HBox hbox1; + + private Gtk.Label label1; + + private Gtk.Entry entry1; + + private Gtk.HBox hbox2; + + private Gtk.Label label2; + + private Gtk.Entry entry2; + + private Gtk.HBox hbox3; + + private Gtk.Label label3; + + private Gtk.Entry entry3; + + private Gtk.Button button2; + + private Gtk.Button button8; + + protected virtual void Build() { + Stetic.Gui.Initialize(); + // Widget OpenGridServices.Manager.ConnectToGridServerDialog + this.Events = ((Gdk.EventMask)(256)); + this.Name = "OpenGridServices.Manager.ConnectToGridServerDialog"; + this.Title = Mono.Unix.Catalog.GetString("Connect to Grid server"); + this.WindowPosition = ((Gtk.WindowPosition)(4)); + this.HasSeparator = false; + // Internal child OpenGridServices.Manager.ConnectToGridServerDialog.VBox + Gtk.VBox w1 = this.VBox; + w1.Events = ((Gdk.EventMask)(256)); + w1.Name = "dialog_VBox"; + w1.BorderWidth = ((uint)(2)); + // Container child dialog_VBox.Gtk.Box+BoxChild + this.vbox2 = new Gtk.VBox(); + this.vbox2.Name = "vbox2"; + // Container child vbox2.Gtk.Box+BoxChild + this.vbox3 = new Gtk.VBox(); + this.vbox3.Name = "vbox3"; + // Container child vbox3.Gtk.Box+BoxChild + this.hbox1 = new Gtk.HBox(); + this.hbox1.Name = "hbox1"; + // Container child hbox1.Gtk.Box+BoxChild + this.label1 = new Gtk.Label(); + this.label1.Name = "label1"; + this.label1.Xalign = 1F; + this.label1.LabelProp = Mono.Unix.Catalog.GetString("Grid server URL: "); + this.label1.Justify = ((Gtk.Justification)(1)); + this.hbox1.Add(this.label1); + Gtk.Box.BoxChild w2 = ((Gtk.Box.BoxChild)(this.hbox1[this.label1])); + w2.Position = 0; + // Container child hbox1.Gtk.Box+BoxChild + this.entry1 = new Gtk.Entry(); + this.entry1.CanFocus = true; + this.entry1.Name = "entry1"; + this.entry1.Text = Mono.Unix.Catalog.GetString("http://gridserver:8001"); + this.entry1.IsEditable = true; + this.entry1.MaxLength = 255; + this.entry1.InvisibleChar = '•'; + this.hbox1.Add(this.entry1); + Gtk.Box.BoxChild w3 = ((Gtk.Box.BoxChild)(this.hbox1[this.entry1])); + w3.Position = 1; + this.vbox3.Add(this.hbox1); + Gtk.Box.BoxChild w4 = ((Gtk.Box.BoxChild)(this.vbox3[this.hbox1])); + w4.Position = 0; + w4.Expand = false; + w4.Fill = false; + // Container child vbox3.Gtk.Box+BoxChild + this.hbox2 = new Gtk.HBox(); + this.hbox2.Name = "hbox2"; + // Container child hbox2.Gtk.Box+BoxChild + this.label2 = new Gtk.Label(); + this.label2.Name = "label2"; + this.label2.Xalign = 1F; + this.label2.LabelProp = Mono.Unix.Catalog.GetString("Username:"); + this.label2.Justify = ((Gtk.Justification)(1)); + this.hbox2.Add(this.label2); + Gtk.Box.BoxChild w5 = ((Gtk.Box.BoxChild)(this.hbox2[this.label2])); + w5.Position = 0; + // Container child hbox2.Gtk.Box+BoxChild + this.entry2 = new Gtk.Entry(); + this.entry2.CanFocus = true; + this.entry2.Name = "entry2"; + this.entry2.IsEditable = true; + this.entry2.InvisibleChar = '•'; + this.hbox2.Add(this.entry2); + Gtk.Box.BoxChild w6 = ((Gtk.Box.BoxChild)(this.hbox2[this.entry2])); + w6.Position = 1; + this.vbox3.Add(this.hbox2); + Gtk.Box.BoxChild w7 = ((Gtk.Box.BoxChild)(this.vbox3[this.hbox2])); + w7.Position = 1; + w7.Expand = false; + w7.Fill = false; + // Container child vbox3.Gtk.Box+BoxChild + this.hbox3 = new Gtk.HBox(); + this.hbox3.Name = "hbox3"; + // Container child hbox3.Gtk.Box+BoxChild + this.label3 = new Gtk.Label(); + this.label3.Name = "label3"; + this.label3.Xalign = 1F; + this.label3.LabelProp = Mono.Unix.Catalog.GetString("Password:"); + this.label3.Justify = ((Gtk.Justification)(1)); + this.hbox3.Add(this.label3); + Gtk.Box.BoxChild w8 = ((Gtk.Box.BoxChild)(this.hbox3[this.label3])); + w8.Position = 0; + // Container child hbox3.Gtk.Box+BoxChild + this.entry3 = new Gtk.Entry(); + this.entry3.CanFocus = true; + this.entry3.Name = "entry3"; + this.entry3.IsEditable = true; + this.entry3.InvisibleChar = '•'; + this.hbox3.Add(this.entry3); + Gtk.Box.BoxChild w9 = ((Gtk.Box.BoxChild)(this.hbox3[this.entry3])); + w9.Position = 1; + this.vbox3.Add(this.hbox3); + Gtk.Box.BoxChild w10 = ((Gtk.Box.BoxChild)(this.vbox3[this.hbox3])); + w10.Position = 2; + w10.Expand = false; + w10.Fill = false; + this.vbox2.Add(this.vbox3); + Gtk.Box.BoxChild w11 = ((Gtk.Box.BoxChild)(this.vbox2[this.vbox3])); + w11.Position = 2; + w11.Expand = false; + w11.Fill = false; + w1.Add(this.vbox2); + Gtk.Box.BoxChild w12 = ((Gtk.Box.BoxChild)(w1[this.vbox2])); + w12.Position = 0; + // Internal child OpenGridServices.Manager.ConnectToGridServerDialog.ActionArea + Gtk.HButtonBox w13 = this.ActionArea; + w13.Events = ((Gdk.EventMask)(256)); + w13.Name = "OpenGridServices.Manager.ConnectToGridServerDialog_ActionArea"; + w13.Spacing = 6; + w13.BorderWidth = ((uint)(5)); + w13.LayoutStyle = ((Gtk.ButtonBoxStyle)(4)); + // Container child OpenGridServices.Manager.ConnectToGridServerDialog_ActionArea.Gtk.ButtonBox+ButtonBoxChild + this.button2 = new Gtk.Button(); + this.button2.CanDefault = true; + this.button2.CanFocus = true; + this.button2.Name = "button2"; + this.button2.UseUnderline = true; + // Container child button2.Gtk.Container+ContainerChild + Gtk.Alignment w14 = new Gtk.Alignment(0.5F, 0.5F, 0F, 0F); + w14.Name = "GtkAlignment"; + // Container child GtkAlignment.Gtk.Container+ContainerChild + Gtk.HBox w15 = new Gtk.HBox(); + w15.Name = "GtkHBox"; + w15.Spacing = 2; + // Container child GtkHBox.Gtk.Container+ContainerChild + Gtk.Image w16 = new Gtk.Image(); + w16.Name = "image1"; + w16.Pixbuf = Gtk.IconTheme.Default.LoadIcon("gtk-apply", 16, 0); + w15.Add(w16); + // Container child GtkHBox.Gtk.Container+ContainerChild + Gtk.Label w18 = new Gtk.Label(); + w18.Name = "GtkLabel"; + w18.LabelProp = Mono.Unix.Catalog.GetString("Connect"); + w18.UseUnderline = true; + w15.Add(w18); + w14.Add(w15); + this.button2.Add(w14); + this.AddActionWidget(this.button2, -5); + Gtk.ButtonBox.ButtonBoxChild w22 = ((Gtk.ButtonBox.ButtonBoxChild)(w13[this.button2])); + w22.Expand = false; + w22.Fill = false; + // Container child OpenGridServices.Manager.ConnectToGridServerDialog_ActionArea.Gtk.ButtonBox+ButtonBoxChild + this.button8 = new Gtk.Button(); + this.button8.CanDefault = true; + this.button8.CanFocus = true; + this.button8.Name = "button8"; + this.button8.UseUnderline = true; + // Container child button8.Gtk.Container+ContainerChild + Gtk.Alignment w23 = new Gtk.Alignment(0.5F, 0.5F, 0F, 0F); + w23.Name = "GtkAlignment1"; + // Container child GtkAlignment1.Gtk.Container+ContainerChild + Gtk.HBox w24 = new Gtk.HBox(); + w24.Name = "GtkHBox1"; + w24.Spacing = 2; + // Container child GtkHBox1.Gtk.Container+ContainerChild + Gtk.Image w25 = new Gtk.Image(); + w25.Name = "image2"; + w25.Pixbuf = Gtk.IconTheme.Default.LoadIcon("gtk-cancel", 16, 0); + w24.Add(w25); + // Container child GtkHBox1.Gtk.Container+ContainerChild + Gtk.Label w27 = new Gtk.Label(); + w27.Name = "GtkLabel1"; + w27.LabelProp = Mono.Unix.Catalog.GetString("Cancel"); + w27.UseUnderline = true; + w24.Add(w27); + w23.Add(w24); + this.button8.Add(w23); + this.AddActionWidget(this.button8, -6); + Gtk.ButtonBox.ButtonBoxChild w31 = ((Gtk.ButtonBox.ButtonBoxChild)(w13[this.button8])); + w31.Position = 1; + w31.Expand = false; + w31.Fill = false; + if ((this.Child != null)) { + this.Child.ShowAll(); + } + this.DefaultWidth = 476; + this.DefaultHeight = 137; + this.Show(); + this.Response += new Gtk.ResponseHandler(this.OnResponse); + } + } +} diff --git a/OpenSim/Grid/Manager/OpenGridServices.Manager/gtk-gui/OpenGridServices.Manager.MainWindow.cs b/OpenSim/Grid/Manager/OpenGridServices.Manager/gtk-gui/OpenGridServices.Manager.MainWindow.cs new file mode 100644 index 0000000000..23a172430f --- /dev/null +++ b/OpenSim/Grid/Manager/OpenGridServices.Manager/gtk-gui/OpenGridServices.Manager.MainWindow.cs @@ -0,0 +1,256 @@ +// ------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Mono Runtime Version: 2.0.50727.42 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ + +namespace OpenGridServices.Manager { + + + public partial class MainWindow { + + private Gtk.Action Grid; + + private Gtk.Action User; + + private Gtk.Action Asset; + + private Gtk.Action Region; + + private Gtk.Action Services; + + private Gtk.Action ConnectToGridserver; + + private Gtk.Action RestartWholeGrid; + + private Gtk.Action ShutdownWholeGrid; + + private Gtk.Action ExitGridManager; + + private Gtk.Action ConnectToUserserver; + + private Gtk.Action AccountManagment; + + private Gtk.Action GlobalNotice; + + private Gtk.Action DisableAllLogins; + + private Gtk.Action DisableNonGodUsersOnly; + + private Gtk.Action ShutdownUserServer; + + private Gtk.Action ShutdownGridserverOnly; + + private Gtk.Action RestartGridserverOnly; + + private Gtk.Action DefaultLocalGridUserserver; + + private Gtk.Action CustomUserserver; + + private Gtk.Action RemoteGridDefaultUserserver; + + private Gtk.Action DisconnectFromGridServer; + + private Gtk.Action UploadAsset; + + private Gtk.Action AssetManagement; + + private Gtk.Action ConnectToAssetServer; + + private Gtk.Action ConnectToDefaultAssetServerForGrid; + + private Gtk.Action DefaultForLocalGrid; + + private Gtk.Action DefaultForRemoteGrid; + + private Gtk.Action CustomAssetServer; + + private Gtk.VBox vbox1; + + private Gtk.MenuBar menubar2; + + private Gtk.HBox hbox1; + + private Gtk.ScrolledWindow scrolledwindow1; + + private Gtk.DrawingArea drawingarea1; + + private Gtk.TreeView treeview1; + + private Gtk.Statusbar statusbar1; + + protected virtual void Build() { + Stetic.Gui.Initialize(); + // Widget OpenGridServices.Manager.MainWindow + Gtk.UIManager w1 = new Gtk.UIManager(); + Gtk.ActionGroup w2 = new Gtk.ActionGroup("Default"); + this.Grid = new Gtk.Action("Grid", Mono.Unix.Catalog.GetString("Grid"), null, null); + this.Grid.HideIfEmpty = false; + this.Grid.ShortLabel = Mono.Unix.Catalog.GetString("Grid"); + w2.Add(this.Grid, "g"); + this.User = new Gtk.Action("User", Mono.Unix.Catalog.GetString("User"), null, null); + this.User.HideIfEmpty = false; + this.User.ShortLabel = Mono.Unix.Catalog.GetString("User"); + w2.Add(this.User, null); + this.Asset = new Gtk.Action("Asset", Mono.Unix.Catalog.GetString("Asset"), null, null); + this.Asset.HideIfEmpty = false; + this.Asset.ShortLabel = Mono.Unix.Catalog.GetString("Asset"); + w2.Add(this.Asset, null); + this.Region = new Gtk.Action("Region", Mono.Unix.Catalog.GetString("Region"), null, null); + this.Region.ShortLabel = Mono.Unix.Catalog.GetString("Region"); + w2.Add(this.Region, null); + this.Services = new Gtk.Action("Services", Mono.Unix.Catalog.GetString("Services"), null, null); + this.Services.ShortLabel = Mono.Unix.Catalog.GetString("Services"); + w2.Add(this.Services, null); + this.ConnectToGridserver = new Gtk.Action("ConnectToGridserver", Mono.Unix.Catalog.GetString("Connect to gridserver..."), null, "gtk-connect"); + this.ConnectToGridserver.HideIfEmpty = false; + this.ConnectToGridserver.ShortLabel = Mono.Unix.Catalog.GetString("Connect to gridserver"); + w2.Add(this.ConnectToGridserver, null); + this.RestartWholeGrid = new Gtk.Action("RestartWholeGrid", Mono.Unix.Catalog.GetString("Restart whole grid"), null, "gtk-refresh"); + this.RestartWholeGrid.ShortLabel = Mono.Unix.Catalog.GetString("Restart whole grid"); + w2.Add(this.RestartWholeGrid, null); + this.ShutdownWholeGrid = new Gtk.Action("ShutdownWholeGrid", Mono.Unix.Catalog.GetString("Shutdown whole grid"), null, "gtk-stop"); + this.ShutdownWholeGrid.ShortLabel = Mono.Unix.Catalog.GetString("Shutdown whole grid"); + w2.Add(this.ShutdownWholeGrid, null); + this.ExitGridManager = new Gtk.Action("ExitGridManager", Mono.Unix.Catalog.GetString("Exit grid manager"), null, "gtk-close"); + this.ExitGridManager.ShortLabel = Mono.Unix.Catalog.GetString("Exit grid manager"); + w2.Add(this.ExitGridManager, null); + this.ConnectToUserserver = new Gtk.Action("ConnectToUserserver", Mono.Unix.Catalog.GetString("Connect to userserver"), null, "gtk-connect"); + this.ConnectToUserserver.ShortLabel = Mono.Unix.Catalog.GetString("Connect to userserver"); + w2.Add(this.ConnectToUserserver, null); + this.AccountManagment = new Gtk.Action("AccountManagment", Mono.Unix.Catalog.GetString("Account managment"), null, "gtk-properties"); + this.AccountManagment.ShortLabel = Mono.Unix.Catalog.GetString("Account managment"); + w2.Add(this.AccountManagment, null); + this.GlobalNotice = new Gtk.Action("GlobalNotice", Mono.Unix.Catalog.GetString("Global notice"), null, "gtk-network"); + this.GlobalNotice.ShortLabel = Mono.Unix.Catalog.GetString("Global notice"); + w2.Add(this.GlobalNotice, null); + this.DisableAllLogins = new Gtk.Action("DisableAllLogins", Mono.Unix.Catalog.GetString("Disable all logins"), null, "gtk-no"); + this.DisableAllLogins.ShortLabel = Mono.Unix.Catalog.GetString("Disable all logins"); + w2.Add(this.DisableAllLogins, null); + this.DisableNonGodUsersOnly = new Gtk.Action("DisableNonGodUsersOnly", Mono.Unix.Catalog.GetString("Disable non-god users only"), null, "gtk-no"); + this.DisableNonGodUsersOnly.ShortLabel = Mono.Unix.Catalog.GetString("Disable non-god users only"); + w2.Add(this.DisableNonGodUsersOnly, null); + this.ShutdownUserServer = new Gtk.Action("ShutdownUserServer", Mono.Unix.Catalog.GetString("Shutdown user server"), null, "gtk-stop"); + this.ShutdownUserServer.ShortLabel = Mono.Unix.Catalog.GetString("Shutdown user server"); + w2.Add(this.ShutdownUserServer, null); + this.ShutdownGridserverOnly = new Gtk.Action("ShutdownGridserverOnly", Mono.Unix.Catalog.GetString("Shutdown gridserver only"), null, "gtk-stop"); + this.ShutdownGridserverOnly.ShortLabel = Mono.Unix.Catalog.GetString("Shutdown gridserver only"); + w2.Add(this.ShutdownGridserverOnly, null); + this.RestartGridserverOnly = new Gtk.Action("RestartGridserverOnly", Mono.Unix.Catalog.GetString("Restart gridserver only"), null, "gtk-refresh"); + this.RestartGridserverOnly.ShortLabel = Mono.Unix.Catalog.GetString("Restart gridserver only"); + w2.Add(this.RestartGridserverOnly, null); + this.DefaultLocalGridUserserver = new Gtk.Action("DefaultLocalGridUserserver", Mono.Unix.Catalog.GetString("Default local grid userserver"), null, null); + this.DefaultLocalGridUserserver.ShortLabel = Mono.Unix.Catalog.GetString("Default local grid userserver"); + w2.Add(this.DefaultLocalGridUserserver, null); + this.CustomUserserver = new Gtk.Action("CustomUserserver", Mono.Unix.Catalog.GetString("Custom userserver..."), null, null); + this.CustomUserserver.ShortLabel = Mono.Unix.Catalog.GetString("Custom userserver"); + w2.Add(this.CustomUserserver, null); + this.RemoteGridDefaultUserserver = new Gtk.Action("RemoteGridDefaultUserserver", Mono.Unix.Catalog.GetString("Remote grid default userserver..."), null, null); + this.RemoteGridDefaultUserserver.ShortLabel = Mono.Unix.Catalog.GetString("Remote grid default userserver"); + w2.Add(this.RemoteGridDefaultUserserver, null); + this.DisconnectFromGridServer = new Gtk.Action("DisconnectFromGridServer", Mono.Unix.Catalog.GetString("Disconnect from grid server"), null, "gtk-disconnect"); + this.DisconnectFromGridServer.ShortLabel = Mono.Unix.Catalog.GetString("Disconnect from grid server"); + this.DisconnectFromGridServer.Visible = false; + w2.Add(this.DisconnectFromGridServer, null); + this.UploadAsset = new Gtk.Action("UploadAsset", Mono.Unix.Catalog.GetString("Upload asset"), null, null); + this.UploadAsset.ShortLabel = Mono.Unix.Catalog.GetString("Upload asset"); + w2.Add(this.UploadAsset, null); + this.AssetManagement = new Gtk.Action("AssetManagement", Mono.Unix.Catalog.GetString("Asset management"), null, null); + this.AssetManagement.ShortLabel = Mono.Unix.Catalog.GetString("Asset management"); + w2.Add(this.AssetManagement, null); + this.ConnectToAssetServer = new Gtk.Action("ConnectToAssetServer", Mono.Unix.Catalog.GetString("Connect to asset server"), null, null); + this.ConnectToAssetServer.ShortLabel = Mono.Unix.Catalog.GetString("Connect to asset server"); + w2.Add(this.ConnectToAssetServer, null); + this.ConnectToDefaultAssetServerForGrid = new Gtk.Action("ConnectToDefaultAssetServerForGrid", Mono.Unix.Catalog.GetString("Connect to default asset server for grid"), null, null); + this.ConnectToDefaultAssetServerForGrid.ShortLabel = Mono.Unix.Catalog.GetString("Connect to default asset server for grid"); + w2.Add(this.ConnectToDefaultAssetServerForGrid, null); + this.DefaultForLocalGrid = new Gtk.Action("DefaultForLocalGrid", Mono.Unix.Catalog.GetString("Default for local grid"), null, null); + this.DefaultForLocalGrid.ShortLabel = Mono.Unix.Catalog.GetString("Default for local grid"); + w2.Add(this.DefaultForLocalGrid, null); + this.DefaultForRemoteGrid = new Gtk.Action("DefaultForRemoteGrid", Mono.Unix.Catalog.GetString("Default for remote grid..."), null, null); + this.DefaultForRemoteGrid.ShortLabel = Mono.Unix.Catalog.GetString("Default for remote grid..."); + w2.Add(this.DefaultForRemoteGrid, null); + this.CustomAssetServer = new Gtk.Action("CustomAssetServer", Mono.Unix.Catalog.GetString("Custom asset server..."), null, null); + this.CustomAssetServer.ShortLabel = Mono.Unix.Catalog.GetString("Custom asset server..."); + w2.Add(this.CustomAssetServer, null); + w1.InsertActionGroup(w2, 0); + this.AddAccelGroup(w1.AccelGroup); + this.WidthRequest = 800; + this.HeightRequest = 600; + this.Name = "OpenGridServices.Manager.MainWindow"; + this.Title = Mono.Unix.Catalog.GetString("Open Grid Services Manager"); + this.Icon = Gtk.IconTheme.Default.LoadIcon("gtk-network", 48, 0); + // Container child OpenGridServices.Manager.MainWindow.Gtk.Container+ContainerChild + this.vbox1 = new Gtk.VBox(); + this.vbox1.Name = "vbox1"; + // Container child vbox1.Gtk.Box+BoxChild + w1.AddUiFromString(""); + this.menubar2 = ((Gtk.MenuBar)(w1.GetWidget("/menubar2"))); + this.menubar2.HeightRequest = 25; + this.menubar2.Name = "menubar2"; + this.vbox1.Add(this.menubar2); + Gtk.Box.BoxChild w3 = ((Gtk.Box.BoxChild)(this.vbox1[this.menubar2])); + w3.Position = 0; + w3.Expand = false; + w3.Fill = false; + // Container child vbox1.Gtk.Box+BoxChild + this.hbox1 = new Gtk.HBox(); + this.hbox1.Name = "hbox1"; + // Container child hbox1.Gtk.Box+BoxChild + this.scrolledwindow1 = new Gtk.ScrolledWindow(); + this.scrolledwindow1.CanFocus = true; + this.scrolledwindow1.Name = "scrolledwindow1"; + this.scrolledwindow1.VscrollbarPolicy = ((Gtk.PolicyType)(1)); + this.scrolledwindow1.HscrollbarPolicy = ((Gtk.PolicyType)(1)); + // Container child scrolledwindow1.Gtk.Container+ContainerChild + Gtk.Viewport w4 = new Gtk.Viewport(); + w4.Name = "GtkViewport"; + w4.ShadowType = ((Gtk.ShadowType)(0)); + // Container child GtkViewport.Gtk.Container+ContainerChild + this.drawingarea1 = new Gtk.DrawingArea(); + this.drawingarea1.Name = "drawingarea1"; + w4.Add(this.drawingarea1); + this.scrolledwindow1.Add(w4); + this.hbox1.Add(this.scrolledwindow1); + Gtk.Box.BoxChild w7 = ((Gtk.Box.BoxChild)(this.hbox1[this.scrolledwindow1])); + w7.Position = 1; + // Container child hbox1.Gtk.Box+BoxChild + this.treeview1 = new Gtk.TreeView(); + this.treeview1.CanFocus = true; + this.treeview1.Name = "treeview1"; + this.hbox1.Add(this.treeview1); + Gtk.Box.BoxChild w8 = ((Gtk.Box.BoxChild)(this.hbox1[this.treeview1])); + w8.Position = 2; + this.vbox1.Add(this.hbox1); + Gtk.Box.BoxChild w9 = ((Gtk.Box.BoxChild)(this.vbox1[this.hbox1])); + w9.Position = 1; + // Container child vbox1.Gtk.Box+BoxChild + this.statusbar1 = new Gtk.Statusbar(); + this.statusbar1.Name = "statusbar1"; + this.statusbar1.Spacing = 5; + this.vbox1.Add(this.statusbar1); + Gtk.Box.BoxChild w10 = ((Gtk.Box.BoxChild)(this.vbox1[this.statusbar1])); + w10.PackType = ((Gtk.PackType)(1)); + w10.Position = 2; + w10.Expand = false; + w10.Fill = false; + this.Add(this.vbox1); + if ((this.Child != null)) { + this.Child.ShowAll(); + } + this.DefaultWidth = 800; + this.DefaultHeight = 800; + this.Show(); + this.DeleteEvent += new Gtk.DeleteEventHandler(this.OnDeleteEvent); + this.ConnectToGridserver.Activated += new System.EventHandler(this.ConnectToGridServerMenu); + this.ExitGridManager.Activated += new System.EventHandler(this.QuitMenu); + this.ShutdownGridserverOnly.Activated += new System.EventHandler(this.ShutdownGridserverMenu); + this.RestartGridserverOnly.Activated += new System.EventHandler(this.RestartGridserverMenu); + this.DisconnectFromGridServer.Activated += new System.EventHandler(this.DisconnectGridServerMenu); + } + } +} diff --git a/OpenSim/Grid/Manager/OpenGridServices.Manager/gtk-gui/generated.cs b/OpenSim/Grid/Manager/OpenGridServices.Manager/gtk-gui/generated.cs new file mode 100644 index 0000000000..6e4ff5d369 --- /dev/null +++ b/OpenSim/Grid/Manager/OpenGridServices.Manager/gtk-gui/generated.cs @@ -0,0 +1,35 @@ +// ------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Mono Runtime Version: 2.0.50727.42 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +// ------------------------------------------------------------------------------ + +namespace Stetic { + + + internal class Gui { + + private static bool initialized; + + internal static void Initialize() { + if ((Stetic.Gui.initialized == false)) { + Stetic.Gui.initialized = true; + } + } + } + + internal class ActionGroups { + + public static Gtk.ActionGroup GetActionGroup(System.Type type) { + return Stetic.ActionGroups.GetActionGroup(type.FullName); + } + + public static Gtk.ActionGroup GetActionGroup(string name) { + return null; + } + } +} diff --git a/OpenSim/Grid/Manager/OpenGridServices.Manager/gtk-gui/gui.stetic b/OpenSim/Grid/Manager/OpenGridServices.Manager/gtk-gui/gui.stetic new file mode 100644 index 0000000000..3a34965220 --- /dev/null +++ b/OpenSim/Grid/Manager/OpenGridServices.Manager/gtk-gui/gui.stetic @@ -0,0 +1,502 @@ + + + + + + Action + <Alt><Mod2>g + False + Grid + Grid + + + Action + False + User + User + + + Action + False + Asset + Asset + + + Action + Region + Region + + + Action + Services + Services + + + Action + False + Connect to gridserver... + Connect to gridserver + gtk-connect + + + + Action + Restart whole grid + Restart whole grid + gtk-refresh + + + Action + Shutdown whole grid + Shutdown whole grid + gtk-stop + + + Action + Exit grid manager + Exit grid manager + gtk-close + + + + Action + Connect to userserver + Connect to userserver + gtk-connect + + + Action + Account managment + Account managment + gtk-properties + + + Action + Global notice + Global notice + gtk-network + + + Action + Disable all logins + Disable all logins + gtk-no + + + Action + Disable non-god users only + Disable non-god users only + gtk-no + + + Action + Shutdown user server + Shutdown user server + gtk-stop + + + Action + Shutdown gridserver only + Shutdown gridserver only + gtk-stop + + + + Action + Restart gridserver only + Restart gridserver only + gtk-refresh + + + + Action + Default local grid userserver + Default local grid userserver + + + Action + Custom userserver... + Custom userserver + + + Action + Remote grid default userserver... + Remote grid default userserver + + + Action + Disconnect from grid server + Disconnect from grid server + gtk-disconnect + False + + + + Action + Upload asset + Upload asset + + + Action + Asset management + Asset management + + + Action + Connect to asset server + Connect to asset server + + + Action + Connect to default asset server for grid + Connect to default asset server for grid + + + Action + Default for local grid + Default for local grid + + + Action + Default for remote grid... + Default for remote grid... + + + Action + Custom asset server... + Custom asset server... + + + + 800 + 600 + Open Grid Services Manager + stock:gtk-network Dialog + + + + + + + + 25 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + False + False + False + + + + + + + + + + + + True + Automatic + Automatic + + + + None + + + + + + + + + + 1 + True + + + + + + True + + + 2 + True + + + + + 1 + True + + + + + statusBar1 + 5 + + + + + + + + + End + 2 + False + False + False + + + + + + + + ButtonPressMask + Connect to Grid server + CenterOnParent + 2 + False + False + + + + + ButtonPressMask + 2 + + + + + + + + + + + + + + + + + + + 1 + Grid server URL: + Right + + + 0 + False + + + + + + True + http://gridserver:8001 + True + 255 + • + + + 1 + False + + + + + + + + 0 + True + False + False + + + + + + + + + 1 + Username: + Right + + + 0 + False + + + + + + True + True + • + + + 1 + True + + + + + + + + 1 + False + False + False + + + + + + + + + 1 + Password: + Right + + + 0 + False + + + + + + True + True + • + + + 1 + True + + + + + + + + 2 + True + False + False + + + + + 2 + True + False + False + + + + + 0 + True + + + + + + + + ButtonPressMask + 6 + 5 + 2 + End + + + + True + True + TextAndIcon + stock:gtk-apply Menu + Connect + True + True + -5 + + + False + False + + + + + + True + True + TextAndIcon + stock:gtk-cancel Menu + Cancel + True + True + -6 + + + 1 + False + False + + + + + + \ No newline at end of file diff --git a/OpenSim/Grid/UserServer.Config/AssemblyInfo.cs b/OpenSim/Grid/UserServer.Config/AssemblyInfo.cs new file mode 100644 index 0000000000..15298e84f1 --- /dev/null +++ b/OpenSim/Grid/UserServer.Config/AssemblyInfo.cs @@ -0,0 +1,56 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Reflection; +using System.Runtime.InteropServices; +// Information about this assembly is defined by the following +// attributes. +// +// change them to the information which is associated with the assembly +// you compile. + +[assembly: AssemblyTitle("UserConfig")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("UserConfig")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. +[assembly: ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all values by your own or you can build default build and revision +// numbers with the '*' character (the default): + +[assembly: AssemblyVersion("1.0.*")] diff --git a/OpenSim/Grid/UserServer.Config/DbUserConfig.cs b/OpenSim/Grid/UserServer.Config/DbUserConfig.cs new file mode 100644 index 0000000000..c7f82551b4 --- /dev/null +++ b/OpenSim/Grid/UserServer.Config/DbUserConfig.cs @@ -0,0 +1,95 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 Db4objects.Db4o; +using OpenSim.Framework.Console; +using OpenSim.Framework.Interfaces; + +namespace OpenUser.Config.UserConfigDb4o +{ + public class Db4oConfigPlugin: IUserConfig + { + public UserConfig GetConfigObject() + { + MainLog.Instance.Verbose("Loading Db40Config dll"); + return ( new DbUserConfig()); + } + } + + public class DbUserConfig : UserConfig + { + private IObjectContainer db; + + public void LoadDefaults() { + MainLog.Instance.Notice("Config.cs:LoadDefaults() - Please press enter to retain default or enter new settings"); + + this.DefaultStartupMsg = MainLog.Instance.CmdPrompt("Default startup message", "Welcome to OGS"); + + this.GridServerURL = MainLog.Instance.CmdPrompt("Grid server URL","http://127.0.0.1:8001/"); + this.GridSendKey = MainLog.Instance.CmdPrompt("Key to send to grid server","null"); + this.GridRecvKey = MainLog.Instance.CmdPrompt("Key to expect from grid server","null"); + } + + public override void InitConfig() { + try { + db = Db4oFactory.OpenFile("openuser.yap"); + IObjectSet result = db.Get(typeof(DbUserConfig)); + if(result.Count==1) { + MainLog.Instance.Verbose("Config.cs:InitConfig() - Found a UserConfig object in the local database, loading"); + foreach (DbUserConfig cfg in result) { + this.GridServerURL=cfg.GridServerURL; + this.GridSendKey=cfg.GridSendKey; + this.GridRecvKey=cfg.GridRecvKey; + this.DefaultStartupMsg=cfg.DefaultStartupMsg; + } + } else { + MainLog.Instance.Verbose("Config.cs:InitConfig() - Could not find object in database, loading precompiled defaults"); + LoadDefaults(); + MainLog.Instance.Verbose("Writing out default settings to local database"); + db.Set(this); + db.Close(); + } + } catch(Exception e) { + MainLog.Instance.Warn("Config.cs:InitConfig() - Exception occured"); + MainLog.Instance.Warn(e.ToString()); + } + + MainLog.Instance.Verbose("User settings loaded:"); + MainLog.Instance.Verbose("Default startup message: " + this.DefaultStartupMsg); + MainLog.Instance.Verbose("Grid server URL: " + this.GridServerURL); + MainLog.Instance.Verbose("Key to send to grid: " + this.GridSendKey); + MainLog.Instance.Verbose("Key to expect from grid: " + this.GridRecvKey); + } + + + public void Shutdown() { + db.Close(); + } + } + +} diff --git a/OpenSim/Grid/UserServer/Main.cs b/OpenSim/Grid/UserServer/Main.cs new file mode 100644 index 0000000000..16223e44e1 --- /dev/null +++ b/OpenSim/Grid/UserServer/Main.cs @@ -0,0 +1,184 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.IO; +using System.Reflection; +using libsecondlife; +using OpenSim.Framework.Console; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Servers; +using OpenSim.Framework.User; +using OpenSim.Framework.Utilities; +using OpenSim.Framework.Configuration; + +namespace OpenSim.Grid.UserServer +{ + /// + /// + public class OpenUser_Main : conscmd_callback + { + private UserConfig Cfg; + + public UserManager m_userManager; + public UserLoginService m_loginService; + + public Dictionary UserSessions = new Dictionary(); + + LogBase m_console; + + [STAThread] + public static void Main(string[] args) + { + Console.WriteLine("Launching UserServer..."); + + OpenUser_Main userserver = new OpenUser_Main(); + + userserver.Startup(); + userserver.Work(); + } + + private OpenUser_Main() + { + if (!Directory.Exists(Util.logDir())) + { + Directory.CreateDirectory(Util.logDir()); + } + m_console = new LogBase((Path.Combine(Util.logDir(),"opengrid-userserver-console.log")), "OpenUser", this , false); + MainLog.Instance = m_console; + } + + private void Work() + { + m_console.Notice("Enter help for a list of commands\n"); + + while (true) + { + m_console.MainLogPrompt(); + } + } + + public void Startup() + { + this.Cfg = new UserConfig("USER SERVER", (Path.Combine(Util.configDir(), "UserServer_Config.xml"))); + + MainLog.Instance.Verbose("Main.cs:Startup() - Establishing data connection"); + m_userManager = new UserManager(); + m_userManager._config = Cfg; + m_userManager.AddPlugin(Cfg.DatabaseProvider); + + m_loginService = new UserLoginService(m_userManager, Cfg, Cfg.DefaultStartupMsg); + + MainLog.Instance.Verbose("Main.cs:Startup() - Starting HTTP process"); + BaseHttpServer httpServer = new BaseHttpServer(8002); + + httpServer.AddXmlRPCHandler("login_to_simulator", m_loginService.XmlRpcLoginMethod); + + httpServer.AddXmlRPCHandler("get_user_by_name", m_userManager.XmlRPCGetUserMethodName); + httpServer.AddXmlRPCHandler("get_user_by_uuid", m_userManager.XmlRPCGetUserMethodUUID); + + httpServer.AddStreamHandler( new RestStreamHandler("DELETE", "/usersessions/", m_userManager.RestDeleteUserSessionMethod )); + + httpServer.Start(); + m_console.Status("SERVER", "Userserver 0.3 - Startup complete"); + } + + + public void do_create(string what) + { + switch (what) + { + case "user": + string tempfirstname; + string templastname; + string tempMD5Passwd; + uint regX = 1000; + uint regY = 1000; + + tempfirstname = m_console.CmdPrompt("First name"); + templastname = m_console.CmdPrompt("Last name"); + tempMD5Passwd = m_console.PasswdPrompt("Password"); + regX = Convert.ToUInt32(m_console.CmdPrompt("Start Region X")); + regY = Convert.ToUInt32(m_console.CmdPrompt("Start Region Y")); + + tempMD5Passwd = Util.Md5Hash(Util.Md5Hash(tempMD5Passwd) + ":" + ""); + + m_userManager.AddUserProfile(tempfirstname, templastname, tempMD5Passwd, regX, regY); + break; + } + } + + public void RunCmd(string cmd, string[] cmdparams) + { + switch (cmd) + { + case "help": + m_console.Notice("create user - create a new user"); + m_console.Notice("shutdown - shutdown the grid (USE CAUTION!)"); + break; + + case "create": + do_create(cmdparams[0]); + break; + + case "shutdown": + m_console.Close(); + Environment.Exit(0); + break; + } + } + + /*private void ConfigDB(IGenericConfig configData) + { + try + { + string attri = ""; + attri = configData.GetAttribute("DataBaseProvider"); + if (attri == "") + { + StorageDll = "OpenSim.Framework.Data.DB4o.dll"; + configData.SetAttribute("DataBaseProvider", "OpenSim.Framework.Data.DB4o.dll"); + } + else + { + StorageDll = attri; + } + configData.Commit(); + } + catch + { + + } + }*/ + + public void Show(string ShowWhat) + { + } + } +} diff --git a/OpenSim/Grid/UserServer/Properties/AssemblyInfo.cs b/OpenSim/Grid/UserServer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..a0a6f3cdb8 --- /dev/null +++ b/OpenSim/Grid/UserServer/Properties/AssemblyInfo.cs @@ -0,0 +1,31 @@ +using System.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OGS-UserServer")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OGS-UserServer")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("e266513a-090b-4d38-80f6-8599eef68c8c")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Grid/UserServer/UserLoginService.cs b/OpenSim/Grid/UserServer/UserLoginService.cs new file mode 100644 index 0000000000..57652b0cdf --- /dev/null +++ b/OpenSim/Grid/UserServer/UserLoginService.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections; +using System.Net; +using Nwc.XmlRpc; +using OpenSim.Framework.Data; +using OpenSim.Framework.UserManagement; +using OpenSim.Framework.Utilities; +using OpenSim.Framework.Configuration; + +namespace OpenSim.Grid.UserServer +{ + public class UserLoginService : LoginService + { + public UserConfig m_config; + + public UserLoginService(UserManagerBase userManager, UserConfig config, string welcomeMess) + : base(userManager, welcomeMess) + { + m_config = config; + } + + /// + /// Customises the login response and fills in missing values. + /// + /// The existing response + /// The user profile + public override void CustomiseResponse(LoginResponse response, UserProfileData theUser) + { + // Load information from the gridserver + SimProfileData SimInfo = new SimProfileData(); + SimInfo = SimInfo.RequestSimProfileData(theUser.currentAgent.currentHandle, m_config.GridServerURL, m_config.GridSendKey, m_config.GridRecvKey); + + // Customise the response + // Home Location + response.Home = "{'region_handle':[r" + (SimInfo.regionLocX * 256).ToString() + ",r" + (SimInfo.regionLocY * 256).ToString() + "], " + + "'position':[r" + theUser.homeLocation.X.ToString() + ",r" + theUser.homeLocation.Y.ToString() + ",r" + theUser.homeLocation.Z.ToString() + "], " + + "'look_at':[r" + theUser.homeLocation.X.ToString() + ",r" + theUser.homeLocation.Y.ToString() + ",r" + theUser.homeLocation.Z.ToString() + "]}"; + + // Destination + Console.WriteLine("CUSTOMISERESPONSE: Region X: " + SimInfo.regionLocX + "; Region Y: " + SimInfo.regionLocY); + response.SimAddress = Util.GetHostFromDNS(SimInfo.serverIP).ToString(); + response.SimPort = (Int32)SimInfo.serverPort; + response.RegionX = SimInfo.regionLocX; + response.RegionY = SimInfo.regionLocY; + + //Not sure if the + "/CAPS/" should in fact be +"CAPS/" depending if there is already a / as part of httpServerURI + string capsPath = Util.GetRandomCapsPath(); + response.SeedCapability = SimInfo.httpServerURI + "CAPS/" + capsPath + "0000/"; + + // Notify the target of an incoming user + Console.WriteLine("Notifying " + SimInfo.regionName + " (" + SimInfo.serverURI + ")"); + + // Prepare notification + Hashtable SimParams = new Hashtable(); + SimParams["session_id"] = theUser.currentAgent.sessionID.ToString(); + SimParams["secure_session_id"] = theUser.currentAgent.secureSessionID.ToString(); + SimParams["firstname"] = theUser.username; + SimParams["lastname"] = theUser.surname; + SimParams["agent_id"] = theUser.UUID.ToString(); + SimParams["circuit_code"] = (Int32)Convert.ToUInt32(response.CircuitCode); + SimParams["startpos_x"] = theUser.currentAgent.currentPos.X.ToString(); + SimParams["startpos_y"] = theUser.currentAgent.currentPos.Y.ToString(); + SimParams["startpos_z"] = theUser.currentAgent.currentPos.Z.ToString(); + SimParams["regionhandle"] = theUser.currentAgent.currentHandle.ToString(); + SimParams["caps_path"] = capsPath; + ArrayList SendParams = new ArrayList(); + SendParams.Add(SimParams); + + // Update agent with target sim + theUser.currentAgent.currentRegion = SimInfo.UUID; + theUser.currentAgent.currentHandle = SimInfo.regionHandle; + + System.Console.WriteLine("Informing region --> " + SimInfo.httpServerURI); + // Send + XmlRpcRequest GridReq = new XmlRpcRequest("expect_user", SendParams); + XmlRpcResponse GridResp = GridReq.Send(SimInfo.httpServerURI, 3000); + } + } +} + diff --git a/OpenSim/Grid/UserServer/UserManager.cs b/OpenSim/Grid/UserServer/UserManager.cs new file mode 100644 index 0000000000..049b8dc4be --- /dev/null +++ b/OpenSim/Grid/UserServer/UserManager.cs @@ -0,0 +1,163 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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; +using System.Net; +using Nwc.XmlRpc; +using OpenSim.Framework.Data; +using OpenSim.Framework.UserManagement; +using OpenSim.Framework.Utilities; +using libsecondlife; + +namespace OpenSim.Grid.UserServer +{ + public class UserManager : UserManagerBase + { + public UserManager() + { + } + + + /// + /// Deletes an active agent session + /// + /// The request + /// The path (eg /bork/narf/test) + /// Parameters sent + /// Success "OK" else error + public string RestDeleteUserSessionMethod(string request, string path, string param) + { + // TODO! Important! + + return "OK"; + } + + /// + /// 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 XmlRpcResponse CreateUnknownUserErrorResponse() + { + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable responseData = new Hashtable(); + responseData["error_type"] = "unknown_user"; + responseData["error_desc"] = "The user requested is not in the database"; + + response.Value = responseData; + return response; + } + + /// + /// Converts a user profile to an XML element which can be returned + /// + /// The user profile + /// A string containing an XML Document of the user profile + public XmlRpcResponse ProfileToXmlRPCResponse(UserProfileData profile) + { + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable responseData = new Hashtable(); + + // Account information + responseData["firstname"] = profile.username; + responseData["lastname"] = profile.surname; + responseData["uuid"] = profile.UUID.ToStringHyphenated(); + // Server Information + responseData["server_inventory"] = profile.userInventoryURI; + responseData["server_asset"] = profile.userAssetURI; + // Profile Information + 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 + responseData["home_coordinates_x"] = profile.homeLocation.X.ToString(); + responseData["home_coordinates_y"] = profile.homeLocation.Y.ToString(); + responseData["home_coordinates_z"] = profile.homeLocation.Z.ToString(); + + responseData["home_region"] = profile.homeRegion.ToString(); + + responseData["home_look_x"] = profile.homeLookAt.X.ToString(); + responseData["home_look_y"] = profile.homeLookAt.Y.ToString(); + responseData["home_look_z"] = profile.homeLookAt.Z.ToString(); + response.Value = responseData; + + return response; + } + + #region XMLRPC User Methods + + public XmlRpcResponse XmlRPCGetUserMethodName(XmlRpcRequest request) + { + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable requestData = (Hashtable)request.Params[0]; + UserProfileData userProfile; + if (requestData.Contains("avatar_name")) + { + userProfile = getUserProfile((string)requestData["avatar_name"]); + if (userProfile == null) + { + return CreateUnknownUserErrorResponse(); + } + } + else + { + return CreateUnknownUserErrorResponse(); + } + + return ProfileToXmlRPCResponse(userProfile); + } + + public XmlRpcResponse XmlRPCGetUserMethodUUID(XmlRpcRequest request) + { + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable requestData = (Hashtable)request.Params[0]; + UserProfileData userProfile; + System.Console.WriteLine("METHOD BY UUID CALLED"); + if (requestData.Contains("avatar_uuid")) + { + userProfile = getUserProfile((LLUUID)(string)requestData["avatar_uuid"]); + if (userProfile == null) + { + return CreateUnknownUserErrorResponse(); + } + } + else + { + return CreateUnknownUserErrorResponse(); + } + + + return ProfileToXmlRPCResponse(userProfile); + } + #endregion + } +} diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs new file mode 100644 index 0000000000..a4871a2d95 --- /dev/null +++ b/OpenSim/Region/Application/Application.cs @@ -0,0 +1,79 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 OpenSim.Framework.Console; +using OpenSim.Region.Environment.Scenes; +using Nini.Config; + +namespace OpenSim +{ + public class Application + { + //could move our main function into OpenSimMain and kill this class + [STAThread] + public static void Main(string[] args) + { + + Console.WriteLine("OpenSim " + VersionInfo.Version + "\n"); + + + Console.Write("Performing compatibility checks... "); + string supported = ""; + if (OpenSim.Framework.Utilities.Util.IsEnvironmentSupported(ref supported)) + { + Console.WriteLine(" Environment is compatible.\n"); + } + else + { + Console.WriteLine(" Environment is unsupported (" + supported + ")\n"); + } + + Console.WriteLine("Starting...\n"); + + // Set current culture + + System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(""); // en + + ArgvConfigSource configSource = new ArgvConfigSource(args); + + configSource.AddSwitch("Startup", "inifile"); + configSource.AddSwitch("Startup", "gridmode"); + configSource.AddSwitch("Startup", "physics"); + configSource.AddSwitch("Startup", "noverbose"); + + OpenSimMain sim = new OpenSimMain(configSource); + + sim.StartUp(); + + while (true) + { + MainLog.Instance.MainLogPrompt(); + } + } + } +} diff --git a/OpenSim/Region/Application/OpenSimMain.cs b/OpenSim/Region/Application/OpenSimMain.cs new file mode 100644 index 0000000000..453f31b55a --- /dev/null +++ b/OpenSim/Region/Application/OpenSimMain.cs @@ -0,0 +1,482 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.IO; +using libsecondlife; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Console; +using OpenSim.Framework.Data; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Types; +using OpenSim.Framework.Configuration; +using OpenSim.Physics.Manager; + +using OpenSim.Region.ClientStack; +using OpenSim.Region.Communications.Local; +using OpenSim.Region.Communications.OGS1; +using OpenSim.Framework.Communications.Caches; +using OpenSim.Region.Environment.Scenes; +using OpenSim.Region.Environment; +using System.Text; +using System.Collections.Generic; +using OpenSim.Framework.Utilities; + +namespace OpenSim +{ + public delegate void ConsoleCommand(string comParams); + + public class OpenSimMain : RegionApplicationBase, conscmd_callback + { + public string m_physicsEngine; + public bool m_sandbox; + public bool user_accounts; + public bool m_gridLocalAsset; + + protected string m_storageDLL = "OpenSim.DataStore.NullStorage.dll"; + + protected string m_startupCommandsFile = ""; + + protected List m_udpServers = new List(); + protected List m_regionData = new List(); + protected List m_localScenes = new List(); + + private bool m_silent; + private string m_logFilename = ("region-console.log"); + + private bool standaloneAuthenticate = false; + private string standaloneWelcomeMessage = null; + private string standaloneInventoryPlugin = ""; + private string standaloneUserPlugin = ""; + + public ConsoleCommand CreateAccount = null; + + public OpenSimMain(IConfigSource configSource) + : base() + { + IConfigSource startupSource = configSource; + string iniFile = startupSource.Configs["Startup"].GetString("inifile", "OpenSim.ini"); + + //check for .INI file (either default or name passed in command line) + string iniFilePath = Path.Combine(Util.configDir(), iniFile); + if (File.Exists(iniFilePath)) + { + startupSource = new IniConfigSource(iniFilePath); + + //enable following line, if we want the original config source(normally commandline args) merged with ini file settings. + //in this case we have it so that if both sources have the same named setting, the command line value will overwrite the ini file value. + //(as if someone has bothered to enter a command line arg, we should take notice of it) + startupSource.Merge(configSource); + } + + ReadConfigSettings(startupSource); + } + + protected void ReadConfigSettings(IConfigSource configSource) + { + m_networkServersInfo = new NetworkServersInfo(); + m_sandbox = !configSource.Configs["Startup"].GetBoolean("gridmode", false); + m_physicsEngine = configSource.Configs["Startup"].GetString("physics", "basicphysics"); + m_silent = configSource.Configs["Startup"].GetBoolean("noverbose", false); + + m_storageDLL = configSource.Configs["Startup"].GetString("storage_plugin", "OpenSim.DataStore.NullStorage.dll"); + + m_startupCommandsFile = configSource.Configs["Startup"].GetString("startup_console_commands_file", ""); + + standaloneAuthenticate = configSource.Configs["StandAlone"].GetBoolean("accounts_authenticate", false); + standaloneWelcomeMessage = configSource.Configs["StandAlone"].GetString("welcome_message", "Welcome to OpenSim"); + standaloneInventoryPlugin = configSource.Configs["StandAlone"].GetString("inventory_plugin", "OpenSim.Framework.Data.SQLite.dll"); + standaloneUserPlugin = configSource.Configs["StandAlone"].GetString("userDatabase_plugin", "OpenSim.Framework.Data.DB4o.dll"); + + m_networkServersInfo.loadFromConfiguration(configSource); + } + + /// + /// Performs initialisation of the scene, such as loading configuration from disk. + /// + public override void StartUp() + { + if (!Directory.Exists(Util.logDir())) + { + Directory.CreateDirectory(Util.logDir()); + } + + m_log = new LogBase(Path.Combine(Util.logDir(), m_logFilename), "Region", this, m_silent); + MainLog.Instance = m_log; + + base.StartUp(); + + if (m_sandbox) + { + CommunicationsLocal.LocalSettings settings = new CommunicationsLocal.LocalSettings(standaloneWelcomeMessage, standaloneAuthenticate, standaloneInventoryPlugin, standaloneUserPlugin); + CommunicationsLocal localComms = new CommunicationsLocal(m_networkServersInfo, m_httpServer, m_assetCache, settings); + m_commsManager = localComms; + if (standaloneAuthenticate) + { + this.CreateAccount = localComms.doCreate; + } + } + else + { + m_commsManager = new CommunicationsOGS1(m_networkServersInfo, m_httpServer, m_assetCache); + m_httpServer.AddStreamHandler(new SimStatusHandler()); + } + + string regionConfigPath = Path.Combine(Util.configDir(), "Regions"); + + if (!Directory.Exists(regionConfigPath)) + { + Directory.CreateDirectory(regionConfigPath); + } + + string[] configFiles = Directory.GetFiles(regionConfigPath, "*.xml"); + + if (configFiles.Length == 0) + { + CreateDefaultRegionInfoXml(Path.Combine(regionConfigPath, "default.xml")); + configFiles = Directory.GetFiles(regionConfigPath, "*.xml"); + } + + // Load all script engines found + OpenSim.Region.Environment.Scenes.Scripting.ScriptEngineLoader ScriptEngineLoader = new OpenSim.Region.Environment.Scenes.Scripting.ScriptEngineLoader(m_log); + + for (int i = 0; i < configFiles.Length; i++) + { + //Console.WriteLine("Loading region config file"); + RegionInfo regionInfo = new RegionInfo("REGION CONFIG #" + (i + 1), configFiles[i]); + + + UDPServer udpServer; + Scene scene = SetupScene(regionInfo, out udpServer); + + + OpenSim.Region.Environment.Scenes.Scripting.ScriptEngineInterface ScriptEngine = ScriptEngineLoader.LoadScriptEngine("DotNetEngine"); + scene.AddScriptEngine(ScriptEngine, m_log); + // TODO: TEMP load default script + ScriptEngine.StartScript(Path.Combine("ScriptEngines", "Default.lsl"), new OpenSim.Region.Environment.Scenes.Scripting.NullScriptHost()); + + + m_localScenes.Add(scene); + + m_udpServers.Add(udpServer); + m_regionData.Add(regionInfo); + } + + // Start UDP servers + for (int i = 0; i < m_udpServers.Count; i++) + { + this.m_udpServers[i].ServerListener(); + } + + //Run Startup Commands + if (m_startupCommandsFile != "") + { + MainLog.Instance.Verbose("Running startup command script (" + m_startupCommandsFile + ")"); + if (File.Exists(m_startupCommandsFile)) + { + StreamReader readFile = File.OpenText(m_startupCommandsFile); + string currentCommand = ""; + while ((currentCommand = readFile.ReadLine()) != null) + { + if (currentCommand != "") + { + MainLog.Instance.Verbose("Running '" + currentCommand + "'"); + MainLog.Instance.MainLogRunCommand(currentCommand); + } + } + } + else + { + MainLog.Instance.Error("Startup command script missing. Will not run startup commands"); + } + } + else + { + MainLog.Instance.Verbose("No startup command script specified. Moving on..."); + } + } + + private static void CreateDefaultRegionInfoXml(string fileName) + { + new RegionInfo("DEFAULT REGION CONFIG", fileName); + } + + protected override StorageManager CreateStorageManager(RegionInfo regionInfo) + { + return new StorageManager(m_storageDLL, regionInfo.DataStore, regionInfo.RegionName); + } + + protected override Scene CreateScene(RegionInfo regionInfo, StorageManager storageManager, AgentCircuitManager circuitManager) + { + return new Scene(regionInfo, circuitManager, m_commsManager, m_assetCache, storageManager, m_httpServer); + } + + protected override void Initialize() + { + m_httpServerPort = m_networkServersInfo.HttpListenerPort; + m_assetCache = new AssetCache("OpenSim.Region.GridInterfaces.Local.dll", m_networkServersInfo.AssetURL, m_networkServersInfo.AssetSendKey); + } + + protected override LogBase CreateLog() + { + if (!Directory.Exists(Util.logDir())) + { + Directory.CreateDirectory(Util.logDir()); + } + + return new LogBase((Path.Combine(Util.logDir(), m_logFilename)), "Region", this, m_silent); + } + + # region Setup methods + + protected override PhysicsScene GetPhysicsScene() + { + return GetPhysicsScene(m_physicsEngine); + } + + private class SimStatusHandler : IStreamHandler + { + public byte[] Handle(string path, Stream request) + { + return Encoding.UTF8.GetBytes("OK"); + } + + public string ContentType + { + get { return "text/plain"; } + } + + public string HttpMethod + { + get { return "GET"; } + } + + public string Path + { + get { return "/simstatus/"; } + } + } + + protected void ConnectToRemoteGridServer() + { + + } + + #endregion + + /// + /// Performs any last-minute sanity checking and shuts down the region server + /// + public virtual void Shutdown() + { + m_log.Verbose("Closing all threads"); + m_log.Verbose("Killing listener thread"); + m_log.Verbose("Killing clients"); + // IMPLEMENT THIS + m_log.Verbose("Closing console and terminating"); + for (int i = 0; i < m_localScenes.Count; i++) + { + m_localScenes[i].Close(); + } + m_log.Close(); + Environment.Exit(0); + } + + #region Console Commands + /// + /// Runs commands issued by the server console from the operator + /// + /// The first argument of the parameter (the command) + /// Additional arguments passed to the command + public void RunCmd(string command, string[] cmdparams) + { + switch (command) + { + case "help": + m_log.Error("alert - send alert to a designated user or all users."); + m_log.Error(" alert [First] [Last] [Message] - send an alert to a user. Case sensitive."); + m_log.Error(" alert general [Message] - send an alert to all users."); + m_log.Error("backup - trigger a simulator backup"); + m_log.Error("script - manually trigger scripts? or script commands?"); + m_log.Error("show uptime - show simulator startup and uptime."); + m_log.Error("show users - show info about connected users."); + m_log.Error("shutdown - disconnect all clients and shutdown."); + m_log.Error("terrain help - show help for terrain commands."); + m_log.Error("quit - equivalent to shutdown."); + break; + + case "show": + if (cmdparams.Length > 0) + { + Show(cmdparams[0]); + } + break; + + case "save-xml": + if (cmdparams.Length > 0) + { + m_localScenes[0].SavePrimsToXml(cmdparams[0]); + } + else + { + m_localScenes[0].SavePrimsToXml("test.xml"); + } + break; + + case "load-xml": + if (cmdparams.Length > 0) + { + m_localScenes[0].LoadPrimsFromXml(cmdparams[0]); + } + else + { + m_localScenes[0].LoadPrimsFromXml("test.xml"); + } + break; + + case "terrain": + string result = ""; + foreach (Scene scene in m_localScenes) + { + if (!scene.Terrain.RunTerrainCmd(cmdparams, ref result, scene.RegionInfo.RegionName)) + { + m_log.Error(result); + } + } + break; + case "terrain-sim": + string result2 = ""; + foreach (Scene scene in m_localScenes) + { + if (scene.RegionInfo.RegionName.ToLower() == cmdparams[0].ToLower()) + { + string[] tmpCmdparams = new string[cmdparams.Length - 1]; + cmdparams.CopyTo(tmpCmdparams, 1); + + if (!scene.Terrain.RunTerrainCmd(tmpCmdparams, ref result2, scene.RegionInfo.RegionName)) + { + m_log.Error(result2); + } + } + } + break; + case "script": + foreach (Scene scene in m_localScenes) + { + scene.SendCommandToScripts(cmdparams); + } + break; + + case "permissions": + // Treats each user as a super-admin when disabled + foreach (Scene scene in m_localScenes) + { + if (Convert.ToBoolean(cmdparams[0])) + scene.PermissionsMngr.EnablePermissions(); + else + scene.PermissionsMngr.DisablePermissions(); + } + break; + + case "backup": + foreach (Scene scene in m_localScenes) + { + scene.Backup(); + } + break; + + case "alert": + foreach (Scene scene in m_localScenes) + { + scene.HandleAlertCommand(cmdparams); + } + break; + + case "create": + if (CreateAccount != null) + { + CreateAccount(cmdparams[0]); + } + break; + + case "quit": + case "shutdown": + Shutdown(); + break; + + default: + m_log.Error("Unknown command"); + break; + } + } + + /// + /// Outputs to the console information about the region + /// + /// What information to display (valid arguments are "uptime", "users") + public void Show(string ShowWhat) + { + switch (ShowWhat) + { + case "uptime": + m_log.Error("OpenSim has been running since " + m_startuptime.ToString()); + m_log.Error("That is " + (DateTime.Now - m_startuptime).ToString()); + break; + case "users": + m_log.Error(String.Format("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16}{5,-16}{6,-16}", "Firstname", "Lastname", "Agent ID", "Session ID", "Circuit", "IP", "World")); + for (int i = 0; i < m_localScenes.Count; i++) + { + Scene scene = m_localScenes[i]; + foreach (Entity entity in scene.Entities.Values) + { + if (entity is ScenePresence) + { + ScenePresence scenePrescence = entity as ScenePresence; + m_log.Error( + String.Format("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16},{5,-16}{6,-16}", + scenePrescence.Firstname, + scenePrescence.Lastname, + scenePrescence.UUID, + scenePrescence.ControllingClient.AgentId, + "Unknown", + "Unknown", + scene.RegionInfo.RegionName)); + } + } + } + break; + } + } + #endregion + } + + +} diff --git a/OpenSim/Region/Application/VersionInfo.cs b/OpenSim/Region/Application/VersionInfo.cs new file mode 100644 index 0000000000..2c720a3304 --- /dev/null +++ b/OpenSim/Region/Application/VersionInfo.cs @@ -0,0 +1,36 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +namespace OpenSim +{ + /// + /// + public class VersionInfo + { + public static string Version = "0.3, SVN build "; + } +} diff --git a/OpenSim/Region/ClientStack/ClientStackNetworkHandler.cs b/OpenSim/Region/ClientStack/ClientStackNetworkHandler.cs new file mode 100644 index 0000000000..f4e537cca7 --- /dev/null +++ b/OpenSim/Region/ClientStack/ClientStackNetworkHandler.cs @@ -0,0 +1,40 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Net.Sockets; + +namespace OpenSim.Region.ClientStack +{ + + public interface ClientStackNetworkHandler + { + void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode);// EndPoint packetSender); + void RemoveClientCircuit(uint circuitcode); + void RegisterPacketServer(PacketServer server); + } + +} diff --git a/OpenSim/Region/ClientStack/ClientView.API.cs b/OpenSim/Region/ClientStack/ClientView.API.cs new file mode 100644 index 0000000000..72bcf57a25 --- /dev/null +++ b/OpenSim/Region/ClientStack/ClientView.API.cs @@ -0,0 +1,1273 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Net; +using System.Text; +using Axiom.Math; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Console; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Framework.Data; +using OpenSim.Framework.Utilities; + +namespace OpenSim.Region.ClientStack +{ + partial class ClientView + { + public event ImprovedInstantMessage OnInstantMessage; + public event ChatFromViewer OnChatFromViewer; + public event RezObject OnRezObject; + public event GenericCall4 OnDeRezObject; + public event ModifyTerrain OnModifyTerrain; + public event GenericCall OnRegionHandShakeReply; + public event GenericCall OnRequestWearables; + public event SetAppearance OnSetAppearance; + public event GenericCall2 OnCompleteMovementToRegion; + public event UpdateAgent OnAgentUpdate; + public event StartAnim OnStartAnim; + public event GenericCall OnRequestAvatarsData; + public event LinkObjects OnLinkObjects; + public event UpdateVector OnGrabObject; + public event ObjectSelect OnDeGrabObject; + public event ObjectDuplicate OnObjectDuplicate; + public event MoveObject OnGrabUpdate; + public event AddNewPrim OnAddPrim; + public event ObjectExtraParams OnUpdateExtraParams; + public event UpdateShape OnUpdatePrimShape; + public event ObjectSelect OnObjectSelect; + public event ObjectDeselect OnObjectDeselect; + public event GenericCall7 OnObjectDescription; + public event GenericCall7 OnObjectName; + public event UpdatePrimFlags OnUpdatePrimFlags; + public event UpdatePrimTexture OnUpdatePrimTexture; + public event UpdateVector OnUpdatePrimGroupPosition; + public event UpdateVector OnUpdatePrimSinglePosition; + public event UpdatePrimRotation OnUpdatePrimGroupRotation; + public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation; + public event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation; + public event UpdateVector OnUpdatePrimScale; + public event StatusChange OnChildAgentStatus; + public event GenericCall2 OnStopMovement; + public event GenericCall6 OnRemoveAvatar; + public event RequestMapBlocks OnRequestMapBlocks; + public event TeleportLocationRequest OnTeleportLocationRequest; + public event DisconnectUser OnDisconnectUser; + public event RequestAvatarProperties OnRequestAvatarProperties; + + public event CreateNewInventoryItem OnCreateNewInventoryItem; + public event CreateInventoryFolder OnCreateNewInventoryFolder; + public event FetchInventoryDescendents OnFetchInventoryDescendents; + public event FetchInventory OnFetchInventory; + public event RequestTaskInventory OnRequestTaskInventory; + public event UDPAssetUploadRequest OnAssetUploadRequest; + public event XferReceive OnXferReceive; + public event RequestXfer OnRequestXfer; + + public event UUIDNameRequest OnNameFromUUIDRequest; + + public event ParcelPropertiesRequest OnParcelPropertiesRequest; + public event ParcelDivideRequest OnParcelDivideRequest; + public event ParcelJoinRequest OnParcelJoinRequest; + public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest; + public event ParcelSelectObjects OnParcelSelectObjects; + public event ParcelObjectOwnerRequest OnParcelObjectOwnerRequest; + public event EstateOwnerMessageRequest OnEstateOwnerMessage; + + /// + /// + /// + public LLVector3 StartPos + { + get + { + return startpos; + } + set + { + startpos = value; + } + } + + /// + /// + /// + public LLUUID AgentId + { + get + { + return this.AgentID; + } + } + + public LLUUID SessionId + { + get + { + return this.SessionID; + } + } + + /// + /// + /// + public string FirstName + { + get + { + return this.firstName; + } + + } + + /// + /// + /// + public string LastName + { + get + { + return this.lastName; + } + } + + #region Scene/Avatar to Client + + /// + /// + /// + /// + public void SendRegionHandshake(RegionInfo regionInfo) + { + Encoding _enc = Encoding.ASCII; + RegionHandshakePacket handshake = new RegionHandshakePacket(); + + handshake.RegionInfo.BillableFactor = regionInfo.estateSettings.billableFactor; + handshake.RegionInfo.IsEstateManager = false; + handshake.RegionInfo.TerrainHeightRange00 = regionInfo.estateSettings.terrainHeightRange0; + handshake.RegionInfo.TerrainHeightRange01 = regionInfo.estateSettings.terrainHeightRange1; + handshake.RegionInfo.TerrainHeightRange10 = regionInfo.estateSettings.terrainHeightRange2; + handshake.RegionInfo.TerrainHeightRange11 = regionInfo.estateSettings.terrainHeightRange3; + handshake.RegionInfo.TerrainStartHeight00 = regionInfo.estateSettings.terrainStartHeight0; + handshake.RegionInfo.TerrainStartHeight01 = regionInfo.estateSettings.terrainStartHeight1; + handshake.RegionInfo.TerrainStartHeight10 = regionInfo.estateSettings.terrainStartHeight2; + handshake.RegionInfo.TerrainStartHeight11 = regionInfo.estateSettings.terrainStartHeight3; + handshake.RegionInfo.SimAccess = (byte)regionInfo.estateSettings.simAccess; + handshake.RegionInfo.WaterHeight = regionInfo.estateSettings.waterHeight; + + + handshake.RegionInfo.RegionFlags = (uint)regionInfo.estateSettings.regionFlags; + + handshake.RegionInfo.SimName = _enc.GetBytes(regionInfo.RegionName + "\0"); + handshake.RegionInfo.SimOwner = regionInfo.MasterAvatarAssignedUUID; + handshake.RegionInfo.TerrainBase0 = regionInfo.estateSettings.terrainBase0; + handshake.RegionInfo.TerrainBase1 = regionInfo.estateSettings.terrainBase1; + handshake.RegionInfo.TerrainBase2 = regionInfo.estateSettings.terrainBase2; + handshake.RegionInfo.TerrainBase3 = regionInfo.estateSettings.terrainBase3; + handshake.RegionInfo.TerrainDetail0 = regionInfo.estateSettings.terrainDetail0; + handshake.RegionInfo.TerrainDetail1 = regionInfo.estateSettings.terrainDetail1; + handshake.RegionInfo.TerrainDetail2 = regionInfo.estateSettings.terrainDetail2; + handshake.RegionInfo.TerrainDetail3 = regionInfo.estateSettings.terrainDetail3; + handshake.RegionInfo.CacheID = LLUUID.Random(); //I guess this is for the client to remember an old setting? + + this.OutPacket(handshake); + } + + /// + /// + /// + /// + public void MoveAgentIntoRegion(RegionInfo regInfo, LLVector3 pos, LLVector3 look) + { + AgentMovementCompletePacket mov = new AgentMovementCompletePacket(); + mov.AgentData.SessionID = this.SessionID; + mov.AgentData.AgentID = this.AgentID; + mov.Data.RegionHandle = regInfo.RegionHandle; + mov.Data.Timestamp = 1172750370; // TODO - dynamicalise this + + if ((pos.X == 0) && (pos.Y == 0) && (pos.Z == 0)) + { + mov.Data.Position = this.startpos; + } + else + { + mov.Data.Position = pos; + } + mov.Data.LookAt = look; + + OutPacket(mov); + } + + /// + /// + /// + /// + /// + /// + /// + /// + public void SendChatMessage(string message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID) + { + SendChatMessage(Helpers.StringToField(message), type, fromPos, fromName, fromAgentID); + } + + /// + /// + /// + /// + /// + /// + /// + /// + public void SendChatMessage(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID) + { + Encoding enc = Encoding.ASCII; + ChatFromSimulatorPacket reply = new ChatFromSimulatorPacket(); + reply.ChatData.Audible = 1; + reply.ChatData.Message = message; + reply.ChatData.ChatType = type; + reply.ChatData.SourceType = 1; + reply.ChatData.Position = fromPos; + reply.ChatData.FromName = enc.GetBytes(fromName + "\0"); + reply.ChatData.OwnerID = fromAgentID; + reply.ChatData.SourceID = fromAgentID; + + this.OutPacket(reply); + } + + /// + /// + /// + /// TODO + /// + /// + public void SendInstantMessage(string message, LLUUID target, string fromName) + { + if (message != "typing") + { + Encoding enc = Encoding.ASCII; + ImprovedInstantMessagePacket msg = new ImprovedInstantMessagePacket(); + msg.AgentData.AgentID = this.AgentID; + msg.AgentData.SessionID = this.SessionID; + msg.MessageBlock.FromAgentName = enc.GetBytes(fromName + " \0"); + msg.MessageBlock.Dialog = 0; + msg.MessageBlock.FromGroup = false; + msg.MessageBlock.ID = target.Combine(this.SecureSessionID); + msg.MessageBlock.Offline = 0; + msg.MessageBlock.ParentEstateID = 0; + msg.MessageBlock.Position = new LLVector3(); + msg.MessageBlock.RegionID = new LLUUID(); + msg.MessageBlock.Timestamp = 0; + msg.MessageBlock.ToAgentID = target; + msg.MessageBlock.Message = enc.GetBytes(message + "\0"); + msg.MessageBlock.BinaryBucket = new byte[0]; + + this.OutPacket(msg); + } + } + + /// + /// Send the region heightmap to the client + /// + /// heightmap + public virtual void SendLayerData(float[] map) + { + try + { + 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; + + Packet layerpack = TerrainManager.CreateLandPacket(map, patches); + OutPacket(layerpack); + } + } + } + catch (Exception e) + { + MainLog.Instance.Warn("client", "ClientView API.cs: SendLayerData() - Failed with exception " + e.ToString()); + } + } + + /// + /// Sends a specified patch to a client + /// + /// Patch coordinate (x) 0..16 + /// Patch coordinate (y) 0..16 + /// heightmap + public void SendLayerData(int px, int py, float[] map) + { + try + { + int[] patches = new int[1]; + int patchx, patchy; + patchx = px; + patchy = py; + + patches[0] = patchx + 0 + patchy * 16; + + Packet layerpack = TerrainManager.CreateLandPacket(map, patches); + OutPacket(layerpack); + } + catch (Exception e) + { + MainLog.Instance.Warn("client", "ClientView API .cs: SendLayerData() - Failed with exception " + e.ToString()); + } + } + + /// + /// + /// + /// + /// + /// + public void InformClientOfNeighbour(ulong neighbourHandle, IPEndPoint neighbourEndPoint) + { + IPAddress neighbourIP = neighbourEndPoint.Address; + ushort neighbourPort = (ushort)neighbourEndPoint.Port; + + EnableSimulatorPacket enablesimpacket = new EnableSimulatorPacket(); + enablesimpacket.SimulatorInfo = new EnableSimulatorPacket.SimulatorInfoBlock(); + enablesimpacket.SimulatorInfo.Handle = neighbourHandle; + + byte[] byteIP = neighbourIP.GetAddressBytes(); + enablesimpacket.SimulatorInfo.IP = (uint)byteIP[3] << 24; + enablesimpacket.SimulatorInfo.IP += (uint)byteIP[2] << 16; + enablesimpacket.SimulatorInfo.IP += (uint)byteIP[1] << 8; + enablesimpacket.SimulatorInfo.IP += (uint)byteIP[0]; + enablesimpacket.SimulatorInfo.Port = neighbourPort; + OutPacket(enablesimpacket); + } + + /// + /// + /// + /// + public AgentCircuitData RequestClientInfo() + { + AgentCircuitData agentData = new AgentCircuitData(); + agentData.AgentID = this.AgentId; + agentData.SessionID = this.SessionID; + agentData.SecureSessionID = this.SecureSessionID; + agentData.circuitcode = this.CircuitCode; + agentData.child = false; + agentData.firstname = this.firstName; + agentData.lastname = this.lastName; + agentData.CapsPath = ""; + return agentData; + } + + public void CrossRegion(ulong newRegionHandle, LLVector3 pos, LLVector3 lookAt, IPEndPoint externalIPEndPoint, string capsURL) + { + LLVector3 look = new LLVector3(lookAt.X * 10, lookAt.Y * 10, lookAt.Z * 10); + + CrossedRegionPacket newSimPack = new CrossedRegionPacket(); + newSimPack.AgentData = new CrossedRegionPacket.AgentDataBlock(); + newSimPack.AgentData.AgentID = this.AgentID; + newSimPack.AgentData.SessionID = this.SessionID; + newSimPack.Info = new CrossedRegionPacket.InfoBlock(); + newSimPack.Info.Position = pos; + newSimPack.Info.LookAt = look; // new LLVector3(0.0f, 0.0f, 0.0f); // copied from Avatar.cs - SHOULD BE DYNAMIC!!!!!!!!!! + newSimPack.RegionData = new CrossedRegionPacket.RegionDataBlock(); + newSimPack.RegionData.RegionHandle = newRegionHandle; + byte[] byteIP = externalIPEndPoint.Address.GetAddressBytes(); + newSimPack.RegionData.SimIP = (uint)byteIP[3] << 24; + newSimPack.RegionData.SimIP += (uint)byteIP[2] << 16; + newSimPack.RegionData.SimIP += (uint)byteIP[1] << 8; + newSimPack.RegionData.SimIP += (uint)byteIP[0]; + newSimPack.RegionData.SimPort = (ushort)externalIPEndPoint.Port; + //newSimPack.RegionData.SeedCapability = new byte[0]; + newSimPack.RegionData.SeedCapability = Helpers.StringToField(capsURL); + + this.OutPacket(newSimPack); + } + + public void SendMapBlock(List mapBlocks) + { + MapBlockReplyPacket mapReply = new MapBlockReplyPacket(); + mapReply.AgentData.AgentID = this.AgentID; + mapReply.Data = new MapBlockReplyPacket.DataBlock[mapBlocks.Count]; + mapReply.AgentData.Flags = 0; + + for (int i = 0; i < mapBlocks.Count; i++) + { + mapReply.Data[i] = new MapBlockReplyPacket.DataBlock(); + mapReply.Data[i].MapImageID = mapBlocks[i].MapImageId; + mapReply.Data[i].X = mapBlocks[i].X; + mapReply.Data[i].Y = mapBlocks[i].Y; + mapReply.Data[i].WaterHeight = mapBlocks[i].WaterHeight; + mapReply.Data[i].Name = Helpers.StringToField(mapBlocks[i].Name); + mapReply.Data[i].RegionFlags = mapBlocks[i].RegionFlags; + mapReply.Data[i].Access = mapBlocks[i].Access; + mapReply.Data[i].Agents = mapBlocks[i].Agents; + } + this.OutPacket(mapReply); + } + + public void SendLocalTeleport(LLVector3 position, LLVector3 lookAt, uint flags) + { + TeleportLocalPacket tpLocal = new TeleportLocalPacket(); + tpLocal.Info.AgentID = this.AgentID; + tpLocal.Info.TeleportFlags = flags; + tpLocal.Info.LocationID = 2; + tpLocal.Info.LookAt = lookAt; + tpLocal.Info.Position = position; + OutPacket(tpLocal); + } + + public void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint newRegionEndPoint, uint locationID, uint flags, string capsURL) + { + TeleportFinishPacket teleport = new TeleportFinishPacket(); + teleport.Info.AgentID = this.AgentID; + teleport.Info.RegionHandle = regionHandle; + teleport.Info.SimAccess = simAccess; + + teleport.Info.SeedCapability = Helpers.StringToField(capsURL); + //teleport.Info.SeedCapability = new byte[0]; + + IPAddress oIP = newRegionEndPoint.Address; + byte[] byteIP = oIP.GetAddressBytes(); + uint ip = (uint)byteIP[3] << 24; + ip += (uint)byteIP[2] << 16; + ip += (uint)byteIP[1] << 8; + ip += (uint)byteIP[0]; + + teleport.Info.SimIP = ip; + teleport.Info.SimPort = (ushort)newRegionEndPoint.Port; + teleport.Info.LocationID = 4; + teleport.Info.TeleportFlags = 1 << 4; + OutPacket(teleport); + } + + /// + /// + /// + public void SendTeleportCancel() + { + TeleportCancelPacket tpCancel = new TeleportCancelPacket(); + tpCancel.Info.SessionID = this.SessionID; + tpCancel.Info.AgentID = this.AgentID; + + OutPacket(tpCancel); + } + + /// + /// + /// + public void SendTeleportLocationStart() + { + TeleportStartPacket tpStart = new TeleportStartPacket(); + tpStart.Info.TeleportFlags = 16; // Teleport via location + OutPacket(tpStart); + } + + public void SendMoneyBalance(LLUUID transaction, bool success, byte[] description, int balance) + { + MoneyBalanceReplyPacket money = new MoneyBalanceReplyPacket(); + money.MoneyData.AgentID = this.AgentID; + money.MoneyData.TransactionID = transaction; + money.MoneyData.TransactionSuccess = success; + money.MoneyData.Description = description; + money.MoneyData.MoneyBalance = balance; + OutPacket(money); + } + + public void SendStartPingCheck(byte seq) + { + StartPingCheckPacket pc = new StartPingCheckPacket(); + pc.PingID.PingID = seq; + pc.Header.Reliable = false; + OutPacket(pc); + + } + + public void SendKillObject(ulong regionHandle, uint localID) + { + KillObjectPacket kill = new KillObjectPacket(); + kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; + kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); + kill.ObjectData[0].ID = localID; + OutPacket(kill); + } + + public void SendInventoryFolderDetails(LLUUID ownerID, LLUUID folderID, List items) + { + Encoding enc = Encoding.ASCII; + uint FULL_MASK_PERMISSIONS = 2147483647; + InventoryDescendentsPacket descend = new InventoryDescendentsPacket(); + descend.AgentData.AgentID = this.AgentId; + descend.AgentData.OwnerID = ownerID; + descend.AgentData.FolderID = folderID; + descend.AgentData.Descendents = items.Count; + descend.AgentData.Version = 0; + descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[items.Count]; + int i = 0; + foreach (InventoryItemBase item in items) + { + descend.ItemData[i] = new InventoryDescendentsPacket.ItemDataBlock(); + descend.ItemData[i].ItemID = item.inventoryID; + descend.ItemData[i].AssetID = item.assetID; + descend.ItemData[i].CreatorID = item.creatorsID; + descend.ItemData[i].BaseMask = item.inventoryBasePermissions; + descend.ItemData[i].CreationDate = 1000; + descend.ItemData[i].Description = enc.GetBytes(item.inventoryDescription + "\0"); + descend.ItemData[i].EveryoneMask = item.inventoryEveryOnePermissions; + descend.ItemData[i].Flags = 1; + descend.ItemData[i].FolderID = item.parentFolderID; + descend.ItemData[i].GroupID = new LLUUID("00000000-0000-0000-0000-000000000000"); + descend.ItemData[i].GroupMask = 0; + descend.ItemData[i].InvType = (sbyte)item.invType; + descend.ItemData[i].Name = enc.GetBytes(item.inventoryName + "\0"); + descend.ItemData[i].NextOwnerMask = item.inventoryNextPermissions; + descend.ItemData[i].OwnerID = item.avatarID; + descend.ItemData[i].OwnerMask = item.inventoryCurrentPermissions; + descend.ItemData[i].SalePrice = 0; + descend.ItemData[i].SaleType = 0; + descend.ItemData[i].Type = (sbyte)item.assetType; + descend.ItemData[i].CRC = Helpers.InventoryCRC(1000, 0, descend.ItemData[i].InvType, descend.ItemData[i].Type, descend.ItemData[i].AssetID, descend.ItemData[i].GroupID, 100, descend.ItemData[i].OwnerID, descend.ItemData[i].CreatorID, descend.ItemData[i].ItemID, descend.ItemData[i].FolderID, FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS); + + i++; + } + + this.OutPacket(descend); + + } + + public void SendInventoryItemDetails(LLUUID ownerID, InventoryItemBase item) + { + Encoding enc = Encoding.ASCII; + uint FULL_MASK_PERMISSIONS = 2147483647; + FetchInventoryReplyPacket inventoryReply = new FetchInventoryReplyPacket(); + inventoryReply.AgentData.AgentID = this.AgentId; + inventoryReply.InventoryData = new FetchInventoryReplyPacket.InventoryDataBlock[1]; + inventoryReply.InventoryData[0] = new FetchInventoryReplyPacket.InventoryDataBlock(); + inventoryReply.InventoryData[0].ItemID = item.inventoryID; + inventoryReply.InventoryData[0].AssetID = item.assetID; + inventoryReply.InventoryData[0].CreatorID = item.creatorsID; + inventoryReply.InventoryData[0].BaseMask = item.inventoryBasePermissions; + inventoryReply.InventoryData[0].CreationDate = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; + inventoryReply.InventoryData[0].Description = enc.GetBytes(item.inventoryDescription + "\0"); + inventoryReply.InventoryData[0].EveryoneMask = item.inventoryEveryOnePermissions; + inventoryReply.InventoryData[0].Flags = 0; + inventoryReply.InventoryData[0].FolderID = item.parentFolderID; + inventoryReply.InventoryData[0].GroupID = new LLUUID("00000000-0000-0000-0000-000000000000"); + inventoryReply.InventoryData[0].GroupMask = 0; + inventoryReply.InventoryData[0].InvType = (sbyte)item.invType; + inventoryReply.InventoryData[0].Name = enc.GetBytes(item.inventoryName + "\0"); + inventoryReply.InventoryData[0].NextOwnerMask = item.inventoryNextPermissions; + inventoryReply.InventoryData[0].OwnerID = item.avatarID; + inventoryReply.InventoryData[0].OwnerMask = item.inventoryCurrentPermissions; + inventoryReply.InventoryData[0].SalePrice = 0; + inventoryReply.InventoryData[0].SaleType = 0; + inventoryReply.InventoryData[0].Type = (sbyte)item.assetType; + inventoryReply.InventoryData[0].CRC = Helpers.InventoryCRC(1000, 0, inventoryReply.InventoryData[0].InvType, inventoryReply.InventoryData[0].Type, inventoryReply.InventoryData[0].AssetID, inventoryReply.InventoryData[0].GroupID, 100, inventoryReply.InventoryData[0].OwnerID, inventoryReply.InventoryData[0].CreatorID, inventoryReply.InventoryData[0].ItemID, inventoryReply.InventoryData[0].FolderID, FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS); + + this.OutPacket(inventoryReply); + } + + public void SendInventoryItemUpdate(InventoryItemBase Item) + { + Encoding enc = Encoding.ASCII; + uint FULL_MASK_PERMISSIONS = 2147483647; + UpdateCreateInventoryItemPacket InventoryReply = new UpdateCreateInventoryItemPacket(); + InventoryReply.AgentData.AgentID = this.AgentID; + InventoryReply.AgentData.SimApproved = true; + InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1]; + InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock(); + InventoryReply.InventoryData[0].ItemID = Item.inventoryID; + InventoryReply.InventoryData[0].AssetID = Item.assetID; + InventoryReply.InventoryData[0].CreatorID = Item.creatorsID; + InventoryReply.InventoryData[0].BaseMask = Item.inventoryBasePermissions; + InventoryReply.InventoryData[0].CreationDate = 1000; + InventoryReply.InventoryData[0].Description = enc.GetBytes(Item.inventoryDescription + "\0"); + InventoryReply.InventoryData[0].EveryoneMask = Item.inventoryEveryOnePermissions; + InventoryReply.InventoryData[0].Flags = 0; + InventoryReply.InventoryData[0].FolderID = Item.parentFolderID; + InventoryReply.InventoryData[0].GroupID = new LLUUID("00000000-0000-0000-0000-000000000000"); + InventoryReply.InventoryData[0].GroupMask = 0; + InventoryReply.InventoryData[0].InvType = (sbyte)Item.invType; + InventoryReply.InventoryData[0].Name = enc.GetBytes(Item.inventoryName + "\0"); + InventoryReply.InventoryData[0].NextOwnerMask = Item.inventoryNextPermissions; + InventoryReply.InventoryData[0].OwnerID = Item.avatarID; + InventoryReply.InventoryData[0].OwnerMask = Item.inventoryCurrentPermissions; + InventoryReply.InventoryData[0].SalePrice = 100; + InventoryReply.InventoryData[0].SaleType = 0; + InventoryReply.InventoryData[0].Type = (sbyte)Item.assetType; + InventoryReply.InventoryData[0].CRC = Helpers.InventoryCRC(1000, 0, InventoryReply.InventoryData[0].InvType, InventoryReply.InventoryData[0].Type, InventoryReply.InventoryData[0].AssetID, InventoryReply.InventoryData[0].GroupID, 100, InventoryReply.InventoryData[0].OwnerID, InventoryReply.InventoryData[0].CreatorID, InventoryReply.InventoryData[0].ItemID, InventoryReply.InventoryData[0].FolderID, FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS); + + OutPacket(InventoryReply); + } + + public void SendRemoveInventoryItem(LLUUID itemID) + { + RemoveInventoryItemPacket remove = new RemoveInventoryItemPacket(); + remove.AgentData.AgentID = this.AgentID; + remove.AgentData.SessionID = this.SessionID; + remove.InventoryData = new RemoveInventoryItemPacket.InventoryDataBlock[1]; + remove.InventoryData[0] = new RemoveInventoryItemPacket.InventoryDataBlock(); + remove.InventoryData[0].ItemID = itemID; + + OutPacket(remove); + } + + public void SendTaskInventory(LLUUID taskID, short serial, byte[] fileName) + { + ReplyTaskInventoryPacket replytask = new ReplyTaskInventoryPacket(); + replytask.InventoryData.TaskID = taskID; + replytask.InventoryData.Serial = serial; + replytask.InventoryData.Filename = fileName; + OutPacket(replytask); + } + + public void SendXferPacket(ulong xferID, uint packet, byte[] data) + { + SendXferPacketPacket sendXfer = new SendXferPacketPacket(); + sendXfer.XferID.ID = xferID; + sendXfer.XferID.Packet = packet; + sendXfer.DataPacket.Data = data; + OutPacket(sendXfer); + } + + /// + /// + /// + /// + public void SendAlertMessage(string message) + { + AlertMessagePacket alertPack = new AlertMessagePacket(); + alertPack.AlertData.Message = Helpers.StringToField(message); + OutPacket(alertPack); + } + + /// + /// + /// + /// + /// + public void SendAgentAlertMessage(string message, bool modal) + { + AgentAlertMessagePacket alertPack = new AgentAlertMessagePacket(); + alertPack.AgentData.AgentID = this.AgentID; + alertPack.AlertData.Message = Helpers.StringToField(message); + alertPack.AlertData.Modal = modal; + OutPacket(alertPack); + } + + public void SendLoadURL(string objectname, LLUUID objectID, LLUUID ownerID, bool groupOwned, string message, string url) + { + LoadURLPacket loadURL = new LoadURLPacket(); + loadURL.Data.ObjectName = Helpers.StringToField(objectname); + loadURL.Data.ObjectID = objectID; + loadURL.Data.OwnerID = ownerID; + loadURL.Data.OwnerIsGroup = groupOwned; + loadURL.Data.Message = Helpers.StringToField(message); + loadURL.Data.URL = Helpers.StringToField(url); + + OutPacket(loadURL); + } + + + public void SendPreLoadSound(LLUUID objectID, LLUUID ownerID, LLUUID soundID) + { + PreloadSoundPacket preSound = new PreloadSoundPacket(); + preSound.DataBlock = new PreloadSoundPacket.DataBlockBlock[1]; + preSound.DataBlock[0] = new PreloadSoundPacket.DataBlockBlock(); + preSound.DataBlock[0].ObjectID = objectID; + preSound.DataBlock[0].OwnerID = ownerID; + preSound.DataBlock[0].SoundID = soundID; + OutPacket(preSound); + } + + public void SendPlayAttachedSound(LLUUID soundID, LLUUID objectID, LLUUID ownerID, float gain, byte flags) + { + AttachedSoundPacket sound = new AttachedSoundPacket(); + sound.DataBlock.SoundID = soundID; + sound.DataBlock.ObjectID = objectID; + sound.DataBlock.OwnerID = ownerID; + sound.DataBlock.Gain = gain; + sound.DataBlock.Flags = flags; + + OutPacket(sound); + } + + public void SendViewerTime(int phase) + { + + SimulatorViewerTimeMessagePacket viewertime = new SimulatorViewerTimeMessagePacket(); + //viewertime.TimeInfo.SecPerDay = 86400; + // viewertime.TimeInfo.SecPerYear = 31536000; + viewertime.TimeInfo.SecPerDay = 1000; + viewertime.TimeInfo.SecPerYear = 365000; + viewertime.TimeInfo.SunPhase = 1; + int sunPhase = (phase + 2) / 2; + if ((sunPhase < 12) || (sunPhase > 36)) + { + viewertime.TimeInfo.SunDirection = new LLVector3(0f, 0.8f, -0.8f); + //Console.WriteLine("sending night"); + } + else + { + sunPhase = sunPhase - 12; + float yValue = 0.1f * (sunPhase); + if (yValue > 1.2f) { yValue = yValue - 1.2f; } + if (yValue > 1 ) { yValue = 1; } + if (yValue < 0) { yValue = 0; } + if (sunPhase < 14) + { + yValue = 1 - yValue; + } + if (sunPhase < 12) { yValue *= -1; } + viewertime.TimeInfo.SunDirection = new LLVector3(0f, yValue, 0.3f); + //Console.WriteLine("sending sun update " + yValue); + } + viewertime.TimeInfo.SunAngVelocity = new LLVector3(0, 0.0f, 10.0f); + viewertime.TimeInfo.UsecSinceStart = (ulong)Util.UnixTimeSinceEpoch(); + OutPacket(viewertime); + } + + public void SendAvatarProperties(LLUUID avatarID, string aboutText, string bornOn, string charterMember, string flAbout, uint flags, LLUUID flImageID, LLUUID imageID, string profileURL, LLUUID partnerID) + { + AvatarPropertiesReplyPacket avatarReply = new AvatarPropertiesReplyPacket(); + avatarReply.AgentData.AgentID = this.AgentID; + avatarReply.AgentData.AvatarID = avatarID; + avatarReply.PropertiesData.AboutText = Helpers.StringToField(aboutText); + avatarReply.PropertiesData.BornOn = Helpers.StringToField(bornOn); + avatarReply.PropertiesData.CharterMember = Helpers.StringToField(charterMember); + avatarReply.PropertiesData.FLAboutText = Helpers.StringToField(flAbout); + avatarReply.PropertiesData.Flags = 0; + avatarReply.PropertiesData.FLImageID = flImageID; + avatarReply.PropertiesData.ImageID = imageID; + avatarReply.PropertiesData.ProfileURL = Helpers.StringToField(profileURL); + avatarReply.PropertiesData.PartnerID = partnerID; + OutPacket(avatarReply); + } + #endregion + + #region Appearance/ Wearables Methods + + /// + /// + /// + /// + public void SendWearables(AvatarWearable[] wearables) + { + AgentWearablesUpdatePacket aw = new AgentWearablesUpdatePacket(); + aw.AgentData.AgentID = this.AgentID; + aw.AgentData.SerialNum = 0; + aw.AgentData.SessionID = this.SessionID; + + aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[13]; + AgentWearablesUpdatePacket.WearableDataBlock awb; + for (int i = 0; i < wearables.Length; i++) + { + awb = new AgentWearablesUpdatePacket.WearableDataBlock(); + awb.WearableType = (byte)i; + awb.AssetID = wearables[i].AssetID; + awb.ItemID = wearables[i].ItemID; + aw.WearableData[i] = awb; + } + + this.OutPacket(aw); + } + + /// + /// + /// + /// + /// + /// + public void SendAppearance(LLUUID agentID, byte[] visualParams, byte[] textureEntry) + { + AvatarAppearancePacket avp = new AvatarAppearancePacket(); + avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; + avp.ObjectData.TextureEntry = textureEntry; + + AvatarAppearancePacket.VisualParamBlock avblock = null; + for (int i = 0; i < visualParams.Length; i++) + { + avblock = new AvatarAppearancePacket.VisualParamBlock(); + avblock.ParamValue = visualParams[i]; + avp.VisualParam[i] = avblock; + } + + avp.Sender.IsTrial = false; + avp.Sender.ID = agentID; + OutPacket(avp); + } + + public void SendAnimation(LLUUID animID, int seq, LLUUID sourceAgentId) + { + AvatarAnimationPacket ani = new AvatarAnimationPacket(); + ani.AnimationSourceList = new AvatarAnimationPacket.AnimationSourceListBlock[1]; + ani.AnimationSourceList[0] = new AvatarAnimationPacket.AnimationSourceListBlock(); + ani.AnimationSourceList[0].ObjectID = sourceAgentId; + ani.Sender = new AvatarAnimationPacket.SenderBlock(); + ani.Sender.ID = sourceAgentId; + ani.AnimationList = new AvatarAnimationPacket.AnimationListBlock[1]; + ani.AnimationList[0] = new AvatarAnimationPacket.AnimationListBlock(); + ani.AnimationList[0].AnimID = animID; + ani.AnimationList[0].AnimSequenceID = seq; + this.OutPacket(ani); + } + + #endregion + + #region Avatar Packet/data sending Methods + + /// + /// send a objectupdate packet with information about the clients avatar + /// + /// + /// + /// + /// + /// + /// + public void SendAvatarData(ulong regionHandle, string firstName, string lastName, LLUUID avatarID, uint avatarLocalID, LLVector3 Pos, byte[] textureEntry) + { + ObjectUpdatePacket objupdate = new ObjectUpdatePacket(); + objupdate.RegionData.RegionHandle = regionHandle; + objupdate.RegionData.TimeDilation = 64096; + objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; + objupdate.ObjectData[0] = this.CreateDefaultAvatarPacket(textureEntry); + + //give this avatar object a local id and assign the user a name + objupdate.ObjectData[0].ID = avatarLocalID; + objupdate.ObjectData[0].FullID = avatarID; + objupdate.ObjectData[0].NameValue = Helpers.StringToField("FirstName STRING RW SV " + firstName + "\nLastName STRING RW SV " + lastName); + LLVector3 pos2 = new LLVector3((float)Pos.X, (float)Pos.Y, (float)Pos.Z); + byte[] pb = pos2.GetBytes(); + Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length); + + OutPacket(objupdate); + + } + + /// + /// + /// + /// + /// + /// + /// + /// + public void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLVector3 velocity) + { + ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = this.CreateAvatarImprovedBlock(localID, position, velocity); + ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket(); + terse.RegionData.RegionHandle = regionHandle; + terse.RegionData.TimeDilation = timeDilation; + terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; + terse.ObjectData[0] = terseBlock; + + this.OutPacket(terse); + } + + #endregion + + #region Primitive Packet/data Sending Methods + + /// + /// + /// + /// + /// + /// + public void AttachObject(uint localID, LLQuaternion rotation, byte attachPoint) + { + ObjectAttachPacket attach = new ObjectAttachPacket(); + attach.AgentData.AgentID = this.AgentID; + attach.AgentData.SessionID = this.SessionID; + attach.AgentData.AttachmentPoint = attachPoint; + attach.ObjectData = new ObjectAttachPacket.ObjectDataBlock[1]; + attach.ObjectData[0] = new ObjectAttachPacket.ObjectDataBlock(); + attach.ObjectData[0].ObjectLocalID = localID; + attach.ObjectData[0].Rotation = rotation; + + this.OutPacket(attach); + } + + public void SendPrimitiveToClient( + ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos, uint flags, + LLUUID objectID, LLUUID ownerID, string text, uint parentID, byte[] particleSystem, LLQuaternion rotation) + { + ObjectUpdatePacket outPacket = new ObjectUpdatePacket(); + outPacket.RegionData.RegionHandle = regionHandle; + outPacket.RegionData.TimeDilation = timeDilation; + outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; + + outPacket.ObjectData[0] = this.CreatePrimUpdateBlock(primShape, flags); + + outPacket.ObjectData[0].ID = localID; + outPacket.ObjectData[0].FullID = objectID; + outPacket.ObjectData[0].OwnerID = ownerID; + outPacket.ObjectData[0].Text = Helpers.StringToField(text); + outPacket.ObjectData[0].ParentID = parentID; + outPacket.ObjectData[0].PSBlock = particleSystem; + + byte[] pb = pos.GetBytes(); + Array.Copy(pb, 0, outPacket.ObjectData[0].ObjectData, 0, pb.Length); + + byte[] rot = rotation.GetBytes(); + Array.Copy(rot, 0, outPacket.ObjectData[0].ObjectData, 36, rot.Length); + + OutPacket(outPacket); + } + + /// + /// + /// + /// + /// + /// + /// + /// + public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLQuaternion rotation) + { + ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket(); + terse.RegionData.RegionHandle = regionHandle; + terse.RegionData.TimeDilation = timeDilation; + terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; + terse.ObjectData[0] = this.CreatePrimImprovedBlock(localID, position, rotation); + + this.OutPacket(terse); + } + + #endregion + + #region Helper Methods + + protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateAvatarImprovedBlock(uint localID, LLVector3 pos, LLVector3 velocity) + { + byte[] bytes = new byte[60]; + int i = 0; + ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock(); + + dat.TextureEntry = new byte[0];// AvatarTemplate.TextureEntry; + + uint ID = localID; + + bytes[i++] = (byte)(ID % 256); + bytes[i++] = (byte)((ID >> 8) % 256); + bytes[i++] = (byte)((ID >> 16) % 256); + bytes[i++] = (byte)((ID >> 24) % 256); + bytes[i++] = 0; + bytes[i++] = 1; + i += 14; + bytes[i++] = 128; + bytes[i++] = 63; + + byte[] pb = pos.GetBytes(); + Array.Copy(pb, 0, bytes, i, pb.Length); + i += 12; + ushort InternVelocityX; + ushort InternVelocityY; + ushort InternVelocityZ; + Vector3 internDirec = new Vector3(0, 0, 0); + + internDirec = new Vector3(velocity.X, velocity.Y, velocity.Z); + + internDirec = internDirec / 128.0f; + internDirec.x += 1; + internDirec.y += 1; + internDirec.z += 1; + + InternVelocityX = (ushort)(32768 * internDirec.x); + InternVelocityY = (ushort)(32768 * internDirec.y); + InternVelocityZ = (ushort)(32768 * internDirec.z); + + ushort ac = 32767; + bytes[i++] = (byte)(InternVelocityX % 256); + bytes[i++] = (byte)((InternVelocityX >> 8) % 256); + bytes[i++] = (byte)(InternVelocityY % 256); + bytes[i++] = (byte)((InternVelocityY >> 8) % 256); + bytes[i++] = (byte)(InternVelocityZ % 256); + bytes[i++] = (byte)((InternVelocityZ >> 8) % 256); + + //accel + bytes[i++] = (byte)(ac % 256); + bytes[i++] = (byte)((ac >> 8) % 256); + bytes[i++] = (byte)(ac % 256); + bytes[i++] = (byte)((ac >> 8) % 256); + bytes[i++] = (byte)(ac % 256); + bytes[i++] = (byte)((ac >> 8) % 256); + + //rot + bytes[i++] = (byte)(ac % 256); + bytes[i++] = (byte)((ac >> 8) % 256); + bytes[i++] = (byte)(ac % 256); + bytes[i++] = (byte)((ac >> 8) % 256); + bytes[i++] = (byte)(ac % 256); + bytes[i++] = (byte)((ac >> 8) % 256); + bytes[i++] = (byte)(ac % 256); + bytes[i++] = (byte)((ac >> 8) % 256); + + //rotation vel + bytes[i++] = (byte)(ac % 256); + bytes[i++] = (byte)((ac >> 8) % 256); + bytes[i++] = (byte)(ac % 256); + bytes[i++] = (byte)((ac >> 8) % 256); + bytes[i++] = (byte)(ac % 256); + bytes[i++] = (byte)((ac >> 8) % 256); + + dat.Data = bytes; + return (dat); + } + + /// + /// + /// + /// + /// + /// + /// + protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreatePrimImprovedBlock(uint localID, LLVector3 position, LLQuaternion rotation) + { + uint ID = localID; + byte[] bytes = new byte[60]; + + int i = 0; + ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock(); + dat.TextureEntry = new byte[0]; + bytes[i++] = (byte)(ID % 256); + bytes[i++] = (byte)((ID >> 8) % 256); + bytes[i++] = (byte)((ID >> 16) % 256); + bytes[i++] = (byte)((ID >> 24) % 256); + bytes[i++] = 0; + bytes[i++] = 0; + + byte[] pb = position.GetBytes(); + Array.Copy(pb, 0, bytes, i, pb.Length); + i += 12; + ushort ac = 32767; + + //vel + bytes[i++] = (byte)(ac % 256); + bytes[i++] = (byte)((ac >> 8) % 256); + bytes[i++] = (byte)(ac % 256); + bytes[i++] = (byte)((ac >> 8) % 256); + bytes[i++] = (byte)(ac % 256); + bytes[i++] = (byte)((ac >> 8) % 256); + + //accel + bytes[i++] = (byte)(ac % 256); + bytes[i++] = (byte)((ac >> 8) % 256); + bytes[i++] = (byte)(ac % 256); + bytes[i++] = (byte)((ac >> 8) % 256); + bytes[i++] = (byte)(ac % 256); + bytes[i++] = (byte)((ac >> 8) % 256); + + ushort rw, rx, ry, rz; + rw = (ushort)(32768 * (rotation.W + 1)); + rx = (ushort)(32768 * (rotation.X + 1)); + ry = (ushort)(32768 * (rotation.Y + 1)); + rz = (ushort)(32768 * (rotation.Z + 1)); + + //rot + bytes[i++] = (byte)(rx % 256); + bytes[i++] = (byte)((rx >> 8) % 256); + bytes[i++] = (byte)(ry % 256); + bytes[i++] = (byte)((ry >> 8) % 256); + bytes[i++] = (byte)(rz % 256); + bytes[i++] = (byte)((rz >> 8) % 256); + bytes[i++] = (byte)(rw % 256); + bytes[i++] = (byte)((rw >> 8) % 256); + + //rotation vel + bytes[i++] = (byte)(ac % 256); + bytes[i++] = (byte)((ac >> 8) % 256); + bytes[i++] = (byte)(ac % 256); + bytes[i++] = (byte)((ac >> 8) % 256); + bytes[i++] = (byte)(ac % 256); + bytes[i++] = (byte)((ac >> 8) % 256); + + dat.Data = bytes; + return dat; + } + + /// + /// Create the ObjectDataBlock for a ObjectUpdatePacket (for a Primitive) + /// + /// + /// + protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(PrimitiveBaseShape primShape, uint flags) + { + ObjectUpdatePacket.ObjectDataBlock objupdate = new ObjectUpdatePacket.ObjectDataBlock(); + this.SetDefaultPrimPacketValues(objupdate); + objupdate.UpdateFlags = flags; + this.SetPrimPacketShapeData(objupdate, primShape); + + return objupdate; + } + + protected void SetPrimPacketShapeData(ObjectUpdatePacket.ObjectDataBlock objectData, PrimitiveBaseShape primData) + { + + objectData.TextureEntry = primData.TextureEntry; + objectData.PCode = primData.PCode; + objectData.PathBegin = primData.PathBegin; + objectData.PathEnd = primData.PathEnd; + objectData.PathScaleX = primData.PathScaleX; + objectData.PathScaleY = primData.PathScaleY; + objectData.PathShearX = primData.PathShearX; + objectData.PathShearY = primData.PathShearY; + objectData.PathSkew = primData.PathSkew; + objectData.ProfileBegin = primData.ProfileBegin; + objectData.ProfileEnd = primData.ProfileEnd; + objectData.Scale = primData.Scale; + objectData.PathCurve = primData.PathCurve; + objectData.ProfileCurve = primData.ProfileCurve; + objectData.ProfileHollow = primData.ProfileHollow; + objectData.PathRadiusOffset = primData.PathRadiusOffset; + objectData.PathRevolutions = primData.PathRevolutions; + objectData.PathTaperX = primData.PathTaperX; + objectData.PathTaperY = primData.PathTaperY; + objectData.PathTwist = primData.PathTwist; + objectData.PathTwistBegin = primData.PathTwistBegin; + objectData.ExtraParams = primData.ExtraParams; + } + + /// + /// Set some default values in a ObjectUpdatePacket + /// + /// + protected void SetDefaultPrimPacketValues(ObjectUpdatePacket.ObjectDataBlock objdata) + { + objdata.PSBlock = new byte[0]; + objdata.ExtraParams = new byte[1]; + objdata.MediaURL = new byte[0]; + objdata.NameValue = new byte[0]; + objdata.Text = new byte[0]; + objdata.TextColor = new byte[4]; + objdata.JointAxisOrAnchor = new LLVector3(0, 0, 0); + objdata.JointPivot = new LLVector3(0, 0, 0); + objdata.Material = 3; + objdata.TextureAnim = new byte[0]; + objdata.Sound = LLUUID.Zero; + objdata.State = 0; + objdata.Data = new byte[0]; + + objdata.ObjectData = new byte[60]; + objdata.ObjectData[46] = 128; + objdata.ObjectData[47] = 63; + } + + + /// + /// + /// + /// + protected ObjectUpdatePacket.ObjectDataBlock CreateDefaultAvatarPacket(byte[] textureEntry) + { + ObjectUpdatePacket.ObjectDataBlock objdata = new ObjectUpdatePacket.ObjectDataBlock(); // new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i); + + SetDefaultAvatarPacketValues(ref objdata); + objdata.UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24); + objdata.PathCurve = 16; + objdata.ProfileCurve = 1; + objdata.PathScaleX = 100; + objdata.PathScaleY = 100; + objdata.ParentID = 0; + objdata.OwnerID = LLUUID.Zero; + objdata.Scale = new LLVector3(1, 1, 1); + objdata.PCode = 47; + if (textureEntry != null) + { + objdata.TextureEntry = textureEntry; + } + Encoding enc = Encoding.ASCII; + LLVector3 pos = new LLVector3(objdata.ObjectData, 16); + pos.X = 100f; + objdata.ID = 8880000; + objdata.NameValue = enc.GetBytes("FirstName STRING RW SV Test \nLastName STRING RW SV User \0"); + LLVector3 pos2 = new LLVector3(100f, 100f, 23f); + //objdata.FullID=user.AgentID; + byte[] pb = pos.GetBytes(); + Array.Copy(pb, 0, objdata.ObjectData, 16, pb.Length); + + return objdata; + } + + /// + /// + /// + /// + protected void SetDefaultAvatarPacketValues(ref ObjectUpdatePacket.ObjectDataBlock objdata) + { + objdata.PSBlock = new byte[0]; + objdata.ExtraParams = new byte[1]; + objdata.MediaURL = new byte[0]; + objdata.NameValue = new byte[0]; + objdata.Text = new byte[0]; + objdata.TextColor = new byte[4]; + objdata.JointAxisOrAnchor = new LLVector3(0, 0, 0); + objdata.JointPivot = new LLVector3(0, 0, 0); + objdata.Material = 4; + objdata.TextureAnim = new byte[0]; + objdata.Sound = LLUUID.Zero; + LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005")); + objdata.TextureEntry = ntex.ToBytes(); + objdata.State = 0; + objdata.Data = new byte[0]; + + objdata.ObjectData = new byte[76]; + objdata.ObjectData[15] = 128; + objdata.ObjectData[16] = 63; + objdata.ObjectData[56] = 128; + objdata.ObjectData[61] = 102; + objdata.ObjectData[62] = 40; + objdata.ObjectData[63] = 61; + objdata.ObjectData[64] = 189; + } + + public void SendNameReply(LLUUID profileId, string firstname, string lastname) + { + UUIDNameReplyPacket packet = new UUIDNameReplyPacket(); + + packet.UUIDNameBlock = new UUIDNameReplyPacket.UUIDNameBlockBlock[1]; + packet.UUIDNameBlock[0] = new UUIDNameReplyPacket.UUIDNameBlockBlock(); + packet.UUIDNameBlock[0].ID = profileId; + packet.UUIDNameBlock[0].FirstName = Helpers.StringToField(firstname); + packet.UUIDNameBlock[0].LastName = Helpers.StringToField(lastname); + + OutPacket(packet); + } + + #endregion + + } +} diff --git a/OpenSim/Region/ClientStack/ClientView.AgentAssetUpload.cs b/OpenSim/Region/ClientStack/ClientView.AgentAssetUpload.cs new file mode 100644 index 0000000000..95441eccfb --- /dev/null +++ b/OpenSim/Region/ClientStack/ClientView.AgentAssetUpload.cs @@ -0,0 +1,357 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Framework.Utilities; +using OpenSim.Framework.Communications.Caches; + + +namespace OpenSim.Region.ClientStack +{ + partial class ClientView + { + public class AgentAssetUpload + { + private Dictionary transactions = new Dictionary(); + private ClientView ourClient; + private AssetCache m_assetCache; + // private InventoryCache m_inventoryCache; + + public AgentAssetUpload(ClientView client, AssetCache assetCache ) + { + this.ourClient = client; + m_assetCache = assetCache; + // m_inventoryCache = inventoryCache; + } + + public void AddUpload(LLUUID transactionID, AssetBase asset) + { + AssetTransaction upload = new AssetTransaction(); + lock (this.transactions) + { + upload.Asset = asset; + upload.TransactionID = transactionID; + this.transactions.Add(transactionID, upload); + } + if (upload.Asset.Data.Length > 2) + { + //is complete + upload.UploadComplete = true; + AssetUploadCompletePacket response = new AssetUploadCompletePacket(); + response.AssetBlock.Type = asset.Type; + response.AssetBlock.Success = true; + response.AssetBlock.UUID = transactionID.Combine(this.ourClient.SecureSessionID); + this.ourClient.OutPacket(response); + m_assetCache.AddAsset(asset); + } + else + { + upload.UploadComplete = false; + upload.XferID = Util.GetNextXferID(); + RequestXferPacket xfer = new RequestXferPacket(); + xfer.XferID.ID = upload.XferID; + xfer.XferID.VFileType = upload.Asset.Type; + xfer.XferID.VFileID = transactionID.Combine(this.ourClient.SecureSessionID); + xfer.XferID.FilePath = 0; + xfer.XferID.Filename = new byte[0]; + this.ourClient.OutPacket(xfer); + } + + } + + public AssetBase GetUpload(LLUUID transactionID) + { + if (this.transactions.ContainsKey(transactionID)) + { + return this.transactions[transactionID].Asset; + } + + return null; + } + + public void HandleUploadPacket(AssetUploadRequestPacket pack, LLUUID assetID) + { + // Console.Write("asset upload request , type = " + pack.AssetBlock.Type.ToString()); + AssetBase asset = null; + if (pack.AssetBlock.Type == 0) + { + + //first packet for transaction + asset = new AssetBase(); + asset.FullID = assetID; + asset.Type = pack.AssetBlock.Type; + asset.InvType = asset.Type; + asset.Name = "UploadedTexture" + Util.RandomClass.Next(1, 1000).ToString("000"); + asset.Data = pack.AssetBlock.AssetData; + + + } + else if (pack.AssetBlock.Type == 13 | pack.AssetBlock.Type == 5 | pack.AssetBlock.Type == 7) + { + + asset = new AssetBase(); + asset.FullID = assetID; + // Console.WriteLine("skin asset id is " + assetID.ToStringHyphenated()); + asset.Type = pack.AssetBlock.Type; + asset.InvType = asset.Type; + asset.Name = "NewClothing" + Util.RandomClass.Next(1, 1000).ToString("000"); + asset.Data = pack.AssetBlock.AssetData; + + + } + + if (asset != null) + { + this.AddUpload(pack.AssetBlock.TransactionID, asset); + } + else + { + + //currently we don't support this asset type + //so lets just tell the client that the upload is complete + AssetUploadCompletePacket response = new AssetUploadCompletePacket(); + response.AssetBlock.Type = pack.AssetBlock.Type; + response.AssetBlock.Success = true; + response.AssetBlock.UUID = pack.AssetBlock.TransactionID.Combine(this.ourClient.SecureSessionID); + this.ourClient.OutPacket(response); + } + + } + + #region Xfer packet system for larger uploads + + public void HandleXferPacket(SendXferPacketPacket xferPacket) + { + lock (this.transactions) + { + foreach (AssetTransaction trans in this.transactions.Values) + { + if (trans.XferID == xferPacket.XferID.ID) + { + if (trans.Asset.Data.Length > 1) + { + byte[] newArray = new byte[trans.Asset.Data.Length + xferPacket.DataPacket.Data.Length]; + Array.Copy(trans.Asset.Data, 0, newArray, 0, trans.Asset.Data.Length); + Array.Copy(xferPacket.DataPacket.Data, 0, newArray, trans.Asset.Data.Length, xferPacket.DataPacket.Data.Length); + trans.Asset.Data = newArray; + } + else + { + byte[] newArray = new byte[xferPacket.DataPacket.Data.Length - 4]; + Array.Copy(xferPacket.DataPacket.Data, 4, newArray, 0, xferPacket.DataPacket.Data.Length - 4); + trans.Asset.Data = newArray; + } + + if ((xferPacket.XferID.Packet & 2147483648) != 0) + { + //end of transfer + trans.UploadComplete = true; + AssetUploadCompletePacket response = new AssetUploadCompletePacket(); + response.AssetBlock.Type = trans.Asset.Type; + response.AssetBlock.Success = true; + response.AssetBlock.UUID = trans.TransactionID.Combine(this.ourClient.SecureSessionID); + this.ourClient.OutPacket(response); + + m_assetCache.AddAsset(trans.Asset); + //check if we should add it to inventory + if (trans.AddToInventory) + { + // m_assetCache.AddAsset(trans.Asset); + //m_inventoryCache.AddNewInventoryItem(this.ourClient, trans.InventFolder, trans.Asset); + } + + + } + break; + } + + } + } + + ConfirmXferPacketPacket confirmXfer = new ConfirmXferPacketPacket(); + confirmXfer.XferID.ID = xferPacket.XferID.ID; + confirmXfer.XferID.Packet = xferPacket.XferID.Packet; + this.ourClient.OutPacket(confirmXfer); + } + + #endregion + + public AssetBase AddUploadToAssetCache(LLUUID transactionID) + { + AssetBase asset = null; + if (this.transactions.ContainsKey(transactionID)) + { + AssetTransaction trans = this.transactions[transactionID]; + if (trans.UploadComplete) + { + m_assetCache.AddAsset(trans.Asset); + asset = trans.Asset; + } + } + + return asset; + } + + public void CreateInventoryItem(CreateInventoryItemPacket packet) + { + if (this.transactions.ContainsKey(packet.InventoryBlock.TransactionID)) + { + AssetTransaction trans = this.transactions[packet.InventoryBlock.TransactionID]; + trans.Asset.Description = Util.FieldToString(packet.InventoryBlock.Description); + trans.Asset.Name = Util.FieldToString(packet.InventoryBlock.Name); + trans.Asset.Type = packet.InventoryBlock.Type; + trans.Asset.InvType = packet.InventoryBlock.InvType; + if (trans.UploadComplete) + { + //already complete so we can add it to the inventory + //m_assetCache.AddAsset(trans.Asset); + // m_inventoryCache.AddNewInventoryItem(this.ourClient, packet.InventoryBlock.FolderID, trans.Asset); + } + else + { + trans.AddToInventory = true; + trans.InventFolder = packet.InventoryBlock.FolderID; + } + } + } + + private class AssetTransaction + { + public uint XferID; + public AssetBase Asset; + public bool AddToInventory; + public LLUUID InventFolder = LLUUID.Zero; + public bool UploadComplete = false; + public LLUUID TransactionID = LLUUID.Zero; + + public AssetTransaction() + { + + } + } + + //new class , not currently used. + public class AssetXferUploader + { + private IClientAPI ourClient; + + public bool UploadComplete = false; + + public bool AddToInventory; + public LLUUID InventFolder = LLUUID.Zero; + + public uint XferID; + public AssetBase Asset; + public LLUUID TransactionID = LLUUID.Zero; + + + public AssetXferUploader(IClientAPI remoteClient, LLUUID assetID, LLUUID transaction, sbyte type, byte[] data) + { + ourClient = remoteClient; + Asset = new AssetBase(); + Asset.FullID = assetID; + Asset.InvType = type; + Asset.Type = type; + Asset.Data = data; + Asset.Name = "blank"; + Asset.Description = "empty"; + TransactionID = transaction; + + if (Asset.Data.Length > 2) + { + //data block should only have data in it, if there is no more data to be uploaded + this.SendCompleteMessage(); + } + else + { + this.ReqestStartXfer(); + } + } + + protected void SendCompleteMessage() + { + UploadComplete = true; + AssetUploadCompletePacket response = new AssetUploadCompletePacket(); + response.AssetBlock.Type = Asset.Type; + response.AssetBlock.Success = true; + response.AssetBlock.UUID = Asset.FullID; + this.ourClient.OutPacket(response); + + //TODO trigger event + } + + protected void ReqestStartXfer() + { + UploadComplete = false; + XferID = Util.GetNextXferID(); + RequestXferPacket xfer = new RequestXferPacket(); + xfer.XferID.ID = XferID; + xfer.XferID.VFileType = Asset.Type; + xfer.XferID.VFileID = Asset.FullID; + xfer.XferID.FilePath = 0; + xfer.XferID.Filename = new byte[0]; + this.ourClient.OutPacket(xfer); + } + + public void HandleXferPacket(uint xferID, uint packetID, byte[] data) + { + if (XferID == xferID) + { + if (Asset.Data.Length > 1) + { + byte[] newArray = new byte[Asset.Data.Length + data.Length]; + Array.Copy(Asset.Data, 0, newArray, 0, Asset.Data.Length); + Array.Copy(data, 0, newArray, Asset.Data.Length, data.Length); + Asset.Data = newArray; + } + else + { + byte[] newArray = new byte[data.Length - 4]; + Array.Copy(data, 4, newArray, 0, data.Length - 4); + Asset.Data = newArray; + } + + ConfirmXferPacketPacket confirmXfer = new ConfirmXferPacketPacket(); + confirmXfer.XferID.ID = xferID; + confirmXfer.XferID.Packet = packetID; + this.ourClient.OutPacket(confirmXfer); + + if ((packetID & 2147483648) != 0) + { + this.SendCompleteMessage(); + } + } + } + } + } + } +} diff --git a/OpenSim/Region/ClientStack/ClientView.PacketHandlers.cs b/OpenSim/Region/ClientStack/ClientView.PacketHandlers.cs new file mode 100644 index 0000000000..e1b1e9050d --- /dev/null +++ b/OpenSim/Region/ClientStack/ClientView.PacketHandlers.cs @@ -0,0 +1,241 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Console; + +namespace OpenSim.Region.ClientStack +{ + public partial class ClientView + { + protected virtual void RegisterLocalPacketHandlers() + { + this.AddLocalPacketHandler(PacketType.LogoutRequest, this.Logout); + this.AddLocalPacketHandler(PacketType.AgentCachedTexture, this.AgentTextureCached); + this.AddLocalPacketHandler(PacketType.MultipleObjectUpdate, this.MultipleObjUpdate); + } + + protected virtual bool Logout(ClientView simClient, Packet packet) + { + MainLog.Instance.Verbose( "OpenSimClient.cs:ProcessInPacket() - Got a logout request"); + //send reply to let the client logout + LogoutReplyPacket logReply = new LogoutReplyPacket(); + logReply.AgentData.AgentID = this.AgentID; + logReply.AgentData.SessionID = this.SessionID; + logReply.InventoryData = new LogoutReplyPacket.InventoryDataBlock[1]; + logReply.InventoryData[0] = new LogoutReplyPacket.InventoryDataBlock(); + logReply.InventoryData[0].ItemID = LLUUID.Zero; + OutPacket(logReply); + // + this.KillClient(); + return true; + } + + protected bool AgentTextureCached(ClientView simclient, Packet packet) + { + // Console.WriteLine(packet.ToString()); + AgentCachedTexturePacket chechedtex = (AgentCachedTexturePacket)packet; + AgentCachedTextureResponsePacket cachedresp = new AgentCachedTextureResponsePacket(); + cachedresp.AgentData.AgentID = this.AgentID; + cachedresp.AgentData.SessionID = this.SessionID; + cachedresp.AgentData.SerialNum = this.cachedtextureserial; + this.cachedtextureserial++; + cachedresp.WearableData = new AgentCachedTextureResponsePacket.WearableDataBlock[chechedtex.WearableData.Length]; + for (int i = 0; i < chechedtex.WearableData.Length; i++) + { + cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); + cachedresp.WearableData[i].TextureIndex = chechedtex.WearableData[i].TextureIndex; + cachedresp.WearableData[i].TextureID = LLUUID.Zero; + cachedresp.WearableData[i].HostName = new byte[0]; + } + this.OutPacket(cachedresp); + return true; + } + + protected bool MultipleObjUpdate(ClientView simClient, Packet packet) + { + MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet; + //System.Console.WriteLine("new multi update packet " + multipleupdate.ToString()); + for (int i = 0; i < multipleupdate.ObjectData.Length; i++) + { + #region position + if (multipleupdate.ObjectData[i].Type == 9) //change position + { + if (OnUpdatePrimGroupPosition != null) + { + LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0); + OnUpdatePrimGroupPosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this); + } + + } + else if (multipleupdate.ObjectData[i].Type == 1) //single item of group change position + { + if (OnUpdatePrimSinglePosition != null) + { + libsecondlife.LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0); + // System.Console.WriteLine("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); + OnUpdatePrimSinglePosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this); + } + } + #endregion position + #region rotation + else if (multipleupdate.ObjectData[i].Type == 2)// single item of group rotation from tab + { + if (OnUpdatePrimSingleRotation != null) + { + LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 0, true); + // Console.WriteLine("new rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W); + OnUpdatePrimSingleRotation(multipleupdate.ObjectData[i].ObjectLocalID, rot, this); + } + } + else if (multipleupdate.ObjectData[i].Type == 3)// single item of group rotation from mouse + { + if (OnUpdatePrimSingleRotation != null) + { + libsecondlife.LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 12, true); + // Console.WriteLine("new rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W); + OnUpdatePrimSingleRotation(multipleupdate.ObjectData[i].ObjectLocalID, rot, this); + } + } + else if (multipleupdate.ObjectData[i].Type == 10)//group rotation from object tab + { + if (OnUpdatePrimGroupRotation != null) + { + libsecondlife.LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 0, true); + // Console.WriteLine("new rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W); + OnUpdatePrimGroupRotation(multipleupdate.ObjectData[i].ObjectLocalID, rot, this); + } + } + else if (multipleupdate.ObjectData[i].Type == 11)//group rotation from mouse + { + if (OnUpdatePrimGroupMouseRotation != null) + { + libsecondlife.LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0); + libsecondlife.LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 12, true); + //Console.WriteLine("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z); + // Console.WriteLine("new rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W); + OnUpdatePrimGroupMouseRotation(multipleupdate.ObjectData[i].ObjectLocalID, pos, rot, this); + } + } + #endregion + #region scale + else if (multipleupdate.ObjectData[i].Type == 13)//group scale from object tab + { + if (OnUpdatePrimScale != null) + { + LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12); + //Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); + OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this); + + // Change the position based on scale (for bug number 246) + libsecondlife.LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0); + // System.Console.WriteLine("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); + OnUpdatePrimSinglePosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this); + } + } + else if (multipleupdate.ObjectData[i].Type == 29)//group scale from mouse + { + if (OnUpdatePrimScale != null) + { + libsecondlife.LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 0); + // Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z ); + // OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this); + } + } + else if (multipleupdate.ObjectData[i].Type == 5)//single prim scale from object tab + { + if (OnUpdatePrimScale != null) + { + libsecondlife.LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12); + // Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); + OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this); + } + } + else if (multipleupdate.ObjectData[i].Type == 21)//single prim scale from mouse + { + if (OnUpdatePrimScale != null) + { + libsecondlife.LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12); + // Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); + OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this); + } + } + #endregion + } + return true; + } + + public void RequestMapLayer() + { + //should be getting the map layer from the grid server + //send a layer covering the 800,800 - 1200,1200 area (should be covering the requested area) + MapLayerReplyPacket mapReply = new MapLayerReplyPacket(); + mapReply.AgentData.AgentID = this.AgentID; + mapReply.AgentData.Flags = 0; + mapReply.LayerData = new MapLayerReplyPacket.LayerDataBlock[1]; + mapReply.LayerData[0] = new MapLayerReplyPacket.LayerDataBlock(); + mapReply.LayerData[0].Bottom = 0; + mapReply.LayerData[0].Left = 0; + mapReply.LayerData[0].Top = 30000; + mapReply.LayerData[0].Right = 30000; + mapReply.LayerData[0].ImageID = new LLUUID("00000000-0000-0000-9999-000000000006"); + this.OutPacket(mapReply); + } + + public void RequestMapBlocks(int minX, int minY, int maxX, int maxY) + { + /* + IList simMapProfiles = m_gridServer.RequestMapBlocks(minX, minY, maxX, maxY); + MapBlockReplyPacket mbReply = new MapBlockReplyPacket(); + mbReply.AgentData.AgentID = this.AgentID; + int len; + if (simMapProfiles == null) + len = 0; + else + len = simMapProfiles.Count; + + mbReply.Data = new MapBlockReplyPacket.DataBlock[len]; + int iii; + for (iii = 0; iii < len; iii++) + { + Hashtable mp = (Hashtable)simMapProfiles[iii]; + mbReply.Data[iii] = new MapBlockReplyPacket.DataBlock(); + mbReply.Data[iii].Name = System.Text.Encoding.UTF8.GetBytes((string)mp["name"]); + mbReply.Data[iii].Access = System.Convert.ToByte(mp["access"]); + mbReply.Data[iii].Agents = System.Convert.ToByte(mp["agents"]); + mbReply.Data[iii].MapImageID = new LLUUID((string)mp["map-image-id"]); + mbReply.Data[iii].RegionFlags = System.Convert.ToUInt32(mp["region-flags"]); + mbReply.Data[iii].WaterHeight = System.Convert.ToByte(mp["water-height"]); + mbReply.Data[iii].X = System.Convert.ToUInt16(mp["x"]); + mbReply.Data[iii].Y = System.Convert.ToUInt16(mp["y"]); + } + this.OutPacket(mbReply); + */ + } + } +} diff --git a/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs b/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs new file mode 100644 index 0000000000..42f06b4d74 --- /dev/null +++ b/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs @@ -0,0 +1,652 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Inventory; +using OpenSim.Framework.Types; +using OpenSim.Framework.Utilities; + +namespace OpenSim.Region.ClientStack +{ + public partial class ClientView + { + private int m_moneyBalance; + + public int MoneyBalance + { + get { return m_moneyBalance; } + } + + public bool AddMoney(int debit) + { + if (m_moneyBalance + debit >= 0) + { + m_moneyBalance += debit; + SendMoneyBalance(LLUUID.Zero, true, Helpers.StringToField("Poof Poof!"), m_moneyBalance); + return true; + } + else + { + return false; + } + } + + protected override void ProcessInPacket(Packet Pack) + { + ack_pack(Pack); + if (debug) + { + if (Pack.Type != PacketType.AgentUpdate) + { + Console.WriteLine(CircuitCode + ":IN: " + Pack.Type.ToString()); + } + } + + if (this.ProcessPacketMethod(Pack)) + { + //there is a handler registered that handled this packet type + return; + } + else + { + Encoding _enc = Encoding.ASCII; + + switch (Pack.Type) + { + case PacketType.ViewerEffect: + ViewerEffectPacket viewer = (ViewerEffectPacket)Pack; + foreach (ClientView client in m_clientThreads.Values) + { + if (client.AgentID != this.AgentID) + { + viewer.AgentData.AgentID = client.AgentID; + viewer.AgentData.SessionID = client.SessionID; + client.OutPacket(viewer); + } + } + break; + + #region Scene/Avatar + case PacketType.AvatarPropertiesRequest: + AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack; + if (OnRequestAvatarProperties != null) + { + OnRequestAvatarProperties(this, avatarProperties.AgentData.AvatarID); + } + break; + case PacketType.ChatFromViewer: + ChatFromViewerPacket inchatpack = (ChatFromViewerPacket)Pack; + if (Util.FieldToString(inchatpack.ChatData.Message) == "") + { + //empty message so don't bother with it + break; + } + string fromName = ""; //ClientAvatar.firstname + " " + ClientAvatar.lastname; + byte[] message = inchatpack.ChatData.Message; + byte type = inchatpack.ChatData.Type; + LLVector3 fromPos = new LLVector3(); // ClientAvatar.Pos; + LLUUID fromAgentID = AgentID; + if (OnChatFromViewer != null) + { + this.OnChatFromViewer(message, type, fromPos, fromName, fromAgentID); + } + break; + case PacketType.ImprovedInstantMessage: + ImprovedInstantMessagePacket msgpack = (ImprovedInstantMessagePacket)Pack; + + string IMfromName = Util.FieldToString(msgpack.MessageBlock.FromAgentName); + string IMmessage = Util.FieldToString(msgpack.MessageBlock.Message); + + if (OnInstantMessage != null) + { + this.OnInstantMessage(msgpack.AgentData.AgentID, msgpack.MessageBlock.ToAgentID, + msgpack.MessageBlock.Timestamp, IMfromName, IMmessage); + } + break; + case PacketType.RezObject: + RezObjectPacket rezPacket = (RezObjectPacket)Pack; + if (OnRezObject != null) + { + this.OnRezObject(this, rezPacket.InventoryData.ItemID, rezPacket.RezData.RayEnd); + } + break; + case PacketType.DeRezObject: + if (OnDeRezObject != null) + { + OnDeRezObject(Pack, this); + } + break; + case PacketType.ModifyLand: + ModifyLandPacket modify = (ModifyLandPacket)Pack; + if (modify.ParcelData.Length > 0) + { + if (OnModifyTerrain != null) + { + OnModifyTerrain(modify.ModifyBlock.Height, modify.ModifyBlock.Seconds, modify.ModifyBlock.BrushSize, + modify.ModifyBlock.Action, modify.ParcelData[0].North, modify.ParcelData[0].West, this); + } + } + break; + case PacketType.RegionHandshakeReply: + if (OnRegionHandShakeReply != null) + { + OnRegionHandShakeReply(this); + } + break; + case PacketType.AgentWearablesRequest: + if (OnRequestWearables != null) + { + OnRequestWearables(this); + } + if (OnRequestAvatarsData != null) + { + OnRequestAvatarsData(this); + } + break; + case PacketType.AgentSetAppearance: + AgentSetAppearancePacket appear = (AgentSetAppearancePacket)Pack; + if (OnSetAppearance != null) + { + OnSetAppearance(appear.ObjectData.TextureEntry, appear.VisualParam); + } + break; + case PacketType.CompleteAgentMovement: + if (OnCompleteMovementToRegion != null) + { + OnCompleteMovementToRegion(); + } + break; + case PacketType.AgentUpdate: + if (OnAgentUpdate != null) + { + AgentUpdatePacket agenUpdate = (AgentUpdatePacket)Pack; + OnAgentUpdate(this, agenUpdate.AgentData.ControlFlags, agenUpdate.AgentData.BodyRotation); + } + break; + case PacketType.AgentAnimation: + if (!m_child) + { + AgentAnimationPacket AgentAni = (AgentAnimationPacket)Pack; + for (int i = 0; i < AgentAni.AnimationList.Length; i++) + { + if (AgentAni.AnimationList[i].StartAnim) + { + if (OnStartAnim != null) + { + OnStartAnim(AgentAni.AnimationList[i].AnimID, 1); + } + } + } + } + break; + + #endregion + + #region Objects/Prims + case PacketType.ObjectLink: + // OpenSim.Framework.Console.MainLog.Instance.Verbose( Pack.ToString()); + ObjectLinkPacket link = (ObjectLinkPacket)Pack; + uint parentprimid = 0; + List childrenprims = new List(); + if (link.ObjectData.Length > 1) + { + parentprimid = link.ObjectData[0].ObjectLocalID; + + for (int i = 1; i < link.ObjectData.Length; i++) + { + childrenprims.Add(link.ObjectData[i].ObjectLocalID); + } + } + if (OnLinkObjects != null) + { + OnLinkObjects(parentprimid, childrenprims); + } + break; + case PacketType.ObjectAdd: + if (OnAddPrim != null) + { + ObjectAddPacket addPacket = (ObjectAddPacket)Pack; + PrimitiveBaseShape shape = GetShapeFromAddPacket(addPacket); + + OnAddPrim(this.AgentId, addPacket.ObjectData.RayEnd, shape); + } + break; + case PacketType.ObjectShape: + ObjectShapePacket shapePacket = (ObjectShapePacket)Pack; + for (int i = 0; i < shapePacket.ObjectData.Length; i++) + { + if (OnUpdatePrimShape != null) + { + OnUpdatePrimShape(shapePacket.ObjectData[i].ObjectLocalID, shapePacket.ObjectData[i]); + } + } + break; + case PacketType.ObjectExtraParams: + ObjectExtraParamsPacket extraPar = (ObjectExtraParamsPacket)Pack; + if (OnUpdateExtraParams != null) + { + OnUpdateExtraParams(extraPar.ObjectData[0].ObjectLocalID, extraPar.ObjectData[0].ParamType, extraPar.ObjectData[0].ParamInUse, extraPar.ObjectData[0].ParamData); + } + break; + case PacketType.ObjectDuplicate: + ObjectDuplicatePacket dupe = (ObjectDuplicatePacket)Pack; + for (int i = 0; i < dupe.ObjectData.Length; i++) + { + if (OnObjectDuplicate != null) + { + OnObjectDuplicate(dupe.ObjectData[i].ObjectLocalID, dupe.SharedData.Offset, dupe.SharedData.DuplicateFlags); + } + } + + break; + + case PacketType.ObjectSelect: + ObjectSelectPacket incomingselect = (ObjectSelectPacket)Pack; + for (int i = 0; i < incomingselect.ObjectData.Length; i++) + { + if (OnObjectSelect != null) + { + OnObjectSelect(incomingselect.ObjectData[i].ObjectLocalID, this); + } + } + break; + case PacketType.ObjectDeselect: + ObjectDeselectPacket incomingdeselect = (ObjectDeselectPacket)Pack; + for (int i = 0; i < incomingdeselect.ObjectData.Length; i++) + { + if (OnObjectDeselect != null) + { + OnObjectDeselect(incomingdeselect.ObjectData[i].ObjectLocalID, this); + } + } + break; + case PacketType.ObjectFlagUpdate: + ObjectFlagUpdatePacket flags = (ObjectFlagUpdatePacket)Pack; + if (OnUpdatePrimFlags != null) + { + OnUpdatePrimFlags(flags.AgentData.ObjectLocalID, Pack, this); + } + break; + case PacketType.ObjectImage: + ObjectImagePacket imagePack = (ObjectImagePacket)Pack; + for (int i = 0; i < imagePack.ObjectData.Length; i++) + { + if (OnUpdatePrimTexture != null) + { + OnUpdatePrimTexture(imagePack.ObjectData[i].ObjectLocalID, imagePack.ObjectData[i].TextureEntry, this); + } + } + break; + case PacketType.ObjectGrab: + ObjectGrabPacket grab = (ObjectGrabPacket)Pack; + if (OnGrabObject != null) + { + OnGrabObject(grab.ObjectData.LocalID, grab.ObjectData.GrabOffset, this); + } + break; + case PacketType.ObjectGrabUpdate: + ObjectGrabUpdatePacket grabUpdate = (ObjectGrabUpdatePacket)Pack; + if (OnGrabUpdate != null) + { + OnGrabUpdate(grabUpdate.ObjectData.ObjectID, grabUpdate.ObjectData.GrabOffsetInitial, grabUpdate.ObjectData.GrabPosition, this); + } + break; + case PacketType.ObjectDeGrab: + ObjectDeGrabPacket deGrab = (ObjectDeGrabPacket)Pack; + if (OnDeGrabObject != null) + { + OnDeGrabObject(deGrab.ObjectData.LocalID, this); + } + break; + case PacketType.ObjectDescription: + ObjectDescriptionPacket objDes = (ObjectDescriptionPacket)Pack; + for (int i = 0; i < objDes.ObjectData.Length; i++) + { + if (OnObjectDescription != null) + { + OnObjectDescription(objDes.ObjectData[i].LocalID, enc.GetString(objDes.ObjectData[i].Description)); + } + } + break; + case PacketType.ObjectName: + ObjectNamePacket objName = (ObjectNamePacket)Pack; + for (int i = 0; i < objName.ObjectData.Length; i++) + { + if (OnObjectName != null) + { + OnObjectName(objName.ObjectData[i].LocalID, enc.GetString(objName.ObjectData[i].Name)); + } + } + break; + case PacketType.ObjectPermissions: + //Console.WriteLine("permissions set " + Pack.ToString()); + break; + #endregion + + #region Inventory/Asset/Other related packets + case PacketType.RequestImage: + RequestImagePacket imageRequest = (RequestImagePacket)Pack; + + for (int i = 0; i < imageRequest.RequestImage.Length; i++) + { + m_assetCache.AddTextureRequest(this, imageRequest.RequestImage[i].Image, imageRequest.RequestImage[i].Packet); + } + break; + case PacketType.TransferRequest: + //Console.WriteLine("OpenSimClient.cs:ProcessInPacket() - Got transfer request"); + TransferRequestPacket transfer = (TransferRequestPacket)Pack; + m_assetCache.AddAssetRequest(this, transfer); + break; + case PacketType.AssetUploadRequest: + AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack; + if (OnAssetUploadRequest != null) + { + OnAssetUploadRequest(this, request.AssetBlock.TransactionID.Combine(this.SecureSessionID), request.AssetBlock.TransactionID, request.AssetBlock.Type, request.AssetBlock.AssetData); + } + break; + case PacketType.RequestXfer: + RequestXferPacket xferReq = (RequestXferPacket)Pack; + if (OnRequestXfer != null) + { + OnRequestXfer(this, xferReq.XferID.ID, Util.FieldToString(xferReq.XferID.Filename)); + } + break; + case PacketType.SendXferPacket: + SendXferPacketPacket xferRec = (SendXferPacketPacket)Pack; + if (OnXferReceive != null) + { + OnXferReceive(this, xferRec.XferID.ID, xferRec.XferID.Packet, xferRec.DataPacket.Data); + } + break; + case PacketType.CreateInventoryFolder: + if (this.OnCreateNewInventoryFolder != null) + { + CreateInventoryFolderPacket invFolder = (CreateInventoryFolderPacket)Pack; + this.OnCreateNewInventoryFolder(this, invFolder.FolderData.FolderID, (ushort)invFolder.FolderData.Type, Util.FieldToString(invFolder.FolderData.Name), invFolder.FolderData.ParentID); + } + break; + case PacketType.CreateInventoryItem: + CreateInventoryItemPacket createItem = (CreateInventoryItemPacket)Pack; + if (this.OnCreateNewInventoryItem != null) + { + this.OnCreateNewInventoryItem(this, createItem.InventoryBlock.TransactionID, createItem.InventoryBlock.FolderID, createItem.InventoryBlock.CallbackID, + Util.FieldToString(createItem.InventoryBlock.Description), Util.FieldToString(createItem.InventoryBlock.Name), createItem.InventoryBlock.InvType, + createItem.InventoryBlock.Type, createItem.InventoryBlock.WearableType, createItem.InventoryBlock.NextOwnerMask); + } + break; + case PacketType.FetchInventory: + if (this.OnFetchInventory != null) + { + FetchInventoryPacket FetchInventory = (FetchInventoryPacket)Pack; + for (int i = 0; i < FetchInventory.InventoryData.Length; i++) + { + this.OnFetchInventory(this, FetchInventory.InventoryData[i].ItemID, FetchInventory.InventoryData[i].OwnerID); + } + } + break; + case PacketType.FetchInventoryDescendents: + if (this.OnFetchInventoryDescendents != null) + { + FetchInventoryDescendentsPacket Fetch = (FetchInventoryDescendentsPacket)Pack; + this.OnFetchInventoryDescendents(this, Fetch.InventoryData.FolderID, Fetch.InventoryData.OwnerID, Fetch.InventoryData.FetchFolders, Fetch.InventoryData.FetchItems, Fetch.InventoryData.SortOrder); + } + break; + case PacketType.UpdateInventoryItem: + UpdateInventoryItemPacket update = (UpdateInventoryItemPacket)Pack; + //Console.WriteLine(Pack.ToString()); + /*for (int i = 0; i < update.InventoryData.Length; i++) + { + if (update.InventoryData[i].TransactionID != LLUUID.Zero) + { + AssetBase asset = m_assetCache.GetAsset(update.InventoryData[i].TransactionID.Combine(this.SecureSessionID)); + if (asset != null) + { + // Console.WriteLine("updating inventory item, found asset" + asset.FullID.ToStringHyphenated() + " already in cache"); + m_inventoryCache.UpdateInventoryItemAsset(this, update.InventoryData[i].ItemID, asset); + } + else + { + asset = this.UploadAssets.AddUploadToAssetCache(update.InventoryData[i].TransactionID); + if (asset != null) + { + //Console.WriteLine("updating inventory item, adding asset" + asset.FullID.ToStringHyphenated() + " to cache"); + m_inventoryCache.UpdateInventoryItemAsset(this, update.InventoryData[i].ItemID, asset); + } + else + { + //Console.WriteLine("trying to update inventory item, but asset is null"); + } + } + } + else + { + m_inventoryCache.UpdateInventoryItemDetails(this, update.InventoryData[i].ItemID, update.InventoryData[i]); ; + } + }*/ + break; + case PacketType.RequestTaskInventory: + RequestTaskInventoryPacket requesttask = (RequestTaskInventoryPacket)Pack; + if (this.OnRequestTaskInventory != null) + { + this.OnRequestTaskInventory(this, requesttask.InventoryData.LocalID); + } + break; + case PacketType.UpdateTaskInventory: + // Console.WriteLine(Pack.ToString()); + UpdateTaskInventoryPacket updatetask = (UpdateTaskInventoryPacket)Pack; + break; + case PacketType.MapLayerRequest: + this.RequestMapLayer(); + break; + case PacketType.MapBlockRequest: + MapBlockRequestPacket MapRequest = (MapBlockRequestPacket)Pack; + if (OnRequestMapBlocks != null) + { + OnRequestMapBlocks(this, MapRequest.PositionData.MinX, MapRequest.PositionData.MinY, MapRequest.PositionData.MaxX, MapRequest.PositionData.MaxY); + } + break; + case PacketType.TeleportLandmarkRequest: + TeleportLandmarkRequestPacket tpReq = (TeleportLandmarkRequestPacket)Pack; + + TeleportStartPacket tpStart = new TeleportStartPacket(); + tpStart.Info.TeleportFlags = 8; // tp via lm + this.OutPacket(tpStart); + + TeleportProgressPacket tpProgress = new TeleportProgressPacket(); + tpProgress.Info.Message = (new ASCIIEncoding()).GetBytes("sending_landmark"); + tpProgress.Info.TeleportFlags = 8; + tpProgress.AgentData.AgentID = tpReq.Info.AgentID; + this.OutPacket(tpProgress); + + // Fetch landmark + LLUUID lmid = tpReq.Info.LandmarkID; + AssetBase lma = this.m_assetCache.GetAsset(lmid); + if (lma != null) + { + AssetLandmark lm = new AssetLandmark(lma); + + if (lm.RegionID == m_scene.RegionInfo.SimUUID) + { + TeleportLocalPacket tpLocal = new TeleportLocalPacket(); + + tpLocal.Info.AgentID = tpReq.Info.AgentID; + tpLocal.Info.TeleportFlags = 8; // Teleport via landmark + tpLocal.Info.LocationID = 2; + tpLocal.Info.Position = lm.Position; + OutPacket(tpLocal); + } + else + { + TeleportCancelPacket tpCancel = new TeleportCancelPacket(); + tpCancel.Info.AgentID = tpReq.Info.AgentID; + tpCancel.Info.SessionID = tpReq.Info.SessionID; + OutPacket(tpCancel); + } + } + else + { + Console.WriteLine("Cancelling Teleport - fetch asset not yet implemented"); + + TeleportCancelPacket tpCancel = new TeleportCancelPacket(); + tpCancel.Info.AgentID = tpReq.Info.AgentID; + tpCancel.Info.SessionID = tpReq.Info.SessionID; + OutPacket(tpCancel); + } + break; + case PacketType.TeleportLocationRequest: + TeleportLocationRequestPacket tpLocReq = (TeleportLocationRequestPacket)Pack; + // Console.WriteLine(tpLocReq.ToString()); + + if (OnTeleportLocationRequest != null) + { + OnTeleportLocationRequest(this, tpLocReq.Info.RegionHandle, tpLocReq.Info.Position, tpLocReq.Info.LookAt, 16); + } + else + { + //no event handler so cancel request + TeleportCancelPacket tpCancel = new TeleportCancelPacket(); + tpCancel.Info.SessionID = tpLocReq.AgentData.SessionID; + tpCancel.Info.AgentID = tpLocReq.AgentData.AgentID; + OutPacket(tpCancel); + } + break; + #endregion + + case PacketType.MoneyBalanceRequest: + SendMoneyBalance(LLUUID.Zero, true, new byte[0], MoneyBalance); + break; + case PacketType.UUIDNameRequest: + UUIDNameRequestPacket incoming = (UUIDNameRequestPacket)Pack; + foreach (UUIDNameRequestPacket.UUIDNameBlockBlock UUIDBlock in incoming.UUIDNameBlock) + { + OnNameFromUUIDRequest(UUIDBlock.ID, this); + } + break; + #region Parcel related packets + case PacketType.ParcelPropertiesRequest: + ParcelPropertiesRequestPacket propertiesRequest = (ParcelPropertiesRequestPacket)Pack; + if (OnParcelPropertiesRequest != null) + { + OnParcelPropertiesRequest((int)Math.Round(propertiesRequest.ParcelData.West), (int)Math.Round(propertiesRequest.ParcelData.South), (int)Math.Round(propertiesRequest.ParcelData.East), (int)Math.Round(propertiesRequest.ParcelData.North), propertiesRequest.ParcelData.SequenceID, propertiesRequest.ParcelData.SnapSelection, this); + } + break; + case PacketType.ParcelDivide: + ParcelDividePacket landDivide = (ParcelDividePacket)Pack; + if (OnParcelDivideRequest != null) + { + OnParcelDivideRequest((int)Math.Round(landDivide.ParcelData.West), (int)Math.Round(landDivide.ParcelData.South), (int)Math.Round(landDivide.ParcelData.East), (int)Math.Round(landDivide.ParcelData.North), this); + } + break; + case PacketType.ParcelJoin: + ParcelJoinPacket landJoin = (ParcelJoinPacket)Pack; + if (OnParcelJoinRequest != null) + { + OnParcelJoinRequest((int)Math.Round(landJoin.ParcelData.West), (int)Math.Round(landJoin.ParcelData.South), (int)Math.Round(landJoin.ParcelData.East), (int)Math.Round(landJoin.ParcelData.North), this); + } + break; + case PacketType.ParcelPropertiesUpdate: + ParcelPropertiesUpdatePacket updatePacket = (ParcelPropertiesUpdatePacket)Pack; + if (OnParcelPropertiesUpdateRequest != null) + { + OnParcelPropertiesUpdateRequest(updatePacket, this); + + } + break; + case PacketType.ParcelSelectObjects: + ParcelSelectObjectsPacket selectPacket = (ParcelSelectObjectsPacket)Pack; + if (OnParcelSelectObjects != null) + { + OnParcelSelectObjects(selectPacket.ParcelData.LocalID, Convert.ToInt32(selectPacket.ParcelData.ReturnType), this); + } + break; + + case PacketType.ParcelObjectOwnersRequest: + ParcelObjectOwnersRequestPacket reqPacket = (ParcelObjectOwnersRequestPacket)Pack; + if (OnParcelObjectOwnerRequest != null) + { + OnParcelObjectOwnerRequest(reqPacket.ParcelData.LocalID, this); + } + break; + #endregion + + #region Estate Packets + case PacketType.EstateOwnerMessage: + EstateOwnerMessagePacket messagePacket = (EstateOwnerMessagePacket)Pack; + if (OnEstateOwnerMessage != null) + { + OnEstateOwnerMessage(messagePacket, this); + } + break; + #endregion + + #region unimplemented handlers + case PacketType.AgentIsNowWearing: + // AgentIsNowWearingPacket wear = (AgentIsNowWearingPacket)Pack; + //Console.WriteLine(Pack.ToString()); + break; + case PacketType.ObjectScale: + //OpenSim.Framework.Console.MainLog.Instance.Verbose( Pack.ToString()); + break; + #endregion + } + } + } + + private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket) + { + PrimitiveBaseShape shape = new PrimitiveBaseShape(); + + shape.PCode = addPacket.ObjectData.PCode; + shape.PathBegin = addPacket.ObjectData.PathBegin; + shape.PathEnd = addPacket.ObjectData.PathEnd; + shape.PathScaleX = addPacket.ObjectData.PathScaleX; + shape.PathScaleY = addPacket.ObjectData.PathScaleY; + shape.PathShearX = addPacket.ObjectData.PathShearX; + shape.PathShearY = addPacket.ObjectData.PathShearY; + shape.PathSkew = addPacket.ObjectData.PathSkew; + shape.ProfileBegin = addPacket.ObjectData.ProfileBegin; + shape.ProfileEnd = addPacket.ObjectData.ProfileEnd; + shape.Scale = addPacket.ObjectData.Scale; + shape.PathCurve = addPacket.ObjectData.PathCurve; + shape.ProfileCurve = addPacket.ObjectData.ProfileCurve; + shape.ProfileHollow = addPacket.ObjectData.ProfileHollow; + shape.PathRadiusOffset = addPacket.ObjectData.PathRadiusOffset; + shape.PathRevolutions = addPacket.ObjectData.PathRevolutions; + shape.PathTaperX = addPacket.ObjectData.PathTaperX; + shape.PathTaperY = addPacket.ObjectData.PathTaperY; + shape.PathTwist = addPacket.ObjectData.PathTwist; + shape.PathTwistBegin = addPacket.ObjectData.PathTwistBegin; + LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-9999-000000000005")); + shape.TextureEntry = ntex.ToBytes(); + return shape; + } + } +} diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs new file mode 100644 index 0000000000..26febbee47 --- /dev/null +++ b/OpenSim/Region/ClientStack/ClientView.cs @@ -0,0 +1,295 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Net; +using System.Text; +using System.Threading; +using System.Timers; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Inventory; +using OpenSim.Framework.Types; +using OpenSim.Framework.Utilities; +using OpenSim.Framework.Communications.Caches; + +using Timer=System.Timers.Timer; + +namespace OpenSim.Region.ClientStack +{ + public delegate bool PacketMethod(ClientView simClient, Packet packet); + + /// + /// Handles new client connections + /// Constructor takes a single Packet and authenticates everything + /// + public partial class ClientView : ClientViewBase, IClientAPI + { + public static TerrainManager TerrainManager; + + protected static Dictionary PacketHandlers = new Dictionary(); //Global/static handlers for all clients + protected Dictionary m_packetHandlers = new Dictionary(); //local handlers for this instance + + public LLUUID AgentID; + public LLUUID SessionID; + public LLUUID SecureSessionID = LLUUID.Zero; + public string firstName; + public string lastName; + public bool m_child = false; + private UseCircuitCodePacket cirpack; + public Thread ClientThread; + public LLVector3 startpos; + + //private AgentAssetUpload UploadAssets; + private LLUUID newAssetFolder = LLUUID.Zero; + private bool debug = false; + protected IScene m_scene; + private Dictionary m_clientThreads; + private AssetCache m_assetCache; + // private InventoryCache m_inventoryCache; + private int cachedtextureserial = 0; + protected AgentCircuitManager m_authenticateSessionsHandler; + private Encoding enc = Encoding.ASCII; + // Dead client detection vars + private Timer clientPingTimer; + private int packetsReceived = 0; + private int probesWithNoIngressPackets = 0; + private int lastPacketsReceived = 0; + + public ClientView(EndPoint remoteEP, UseCircuitCodePacket initialcirpack, Dictionary clientThreads, IScene scene, AssetCache assetCache, PacketServer packServer, AgentCircuitManager authenSessions ) + { + m_moneyBalance = 1000; + + m_scene = scene; + m_clientThreads = clientThreads; + m_assetCache = assetCache; + + m_networkServer = packServer; + // m_inventoryCache = inventoryCache; + m_authenticateSessionsHandler = authenSessions; + + MainLog.Instance.Verbose( "OpenSimClient.cs - Started up new client thread to handle incoming request"); + cirpack = initialcirpack; + userEP = remoteEP; + + this.startpos = m_authenticateSessionsHandler.GetPosition(initialcirpack.CircuitCode.Code); + + PacketQueue = new BlockingQueue(); + + //this.UploadAssets = new AgentAssetUpload(this, m_assetCache, m_inventoryCache); + AckTimer = new Timer(500); + AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed); + AckTimer.Start(); + + this.RegisterLocalPacketHandlers(); + + ClientThread = new Thread(new ThreadStart(AuthUser)); + ClientThread.IsBackground = true; + ClientThread.Start(); + } + + # region Client Methods + + public void KillClient() + { + clientPingTimer.Stop(); + + m_scene.RemoveClient(this.AgentId); + + m_clientThreads.Remove(this.CircuitCode); + m_networkServer.RemoveClientCircuit(this.CircuitCode); + this.ClientThread.Abort(); + } + #endregion + + # region Packet Handling + public static bool AddPacketHandler(PacketType packetType, PacketMethod handler) + { + bool result = false; + lock (PacketHandlers) + { + if (!PacketHandlers.ContainsKey(packetType)) + { + PacketHandlers.Add(packetType, handler); + result = true; + } + } + return result; + } + + public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler) + { + bool result = false; + lock (m_packetHandlers) + { + if (!m_packetHandlers.ContainsKey(packetType)) + { + m_packetHandlers.Add(packetType, handler); + result = true; + } + } + return result; + } + + protected virtual bool ProcessPacketMethod(Packet packet) + { + bool result = false; + bool found = false; + PacketMethod method; + if (m_packetHandlers.TryGetValue(packet.Type, out method)) + { + //there is a local handler for this packet type + result = method(this, packet); + } + else + { + //there is not a local handler so see if there is a Global handler + lock (PacketHandlers) + { + found = PacketHandlers.TryGetValue(packet.Type, out method); + } + if (found) + { + result = method(this, packet); + } + } + return result; + } + + protected virtual void ClientLoop() + { + MainLog.Instance.Verbose( "OpenSimClient.cs:ClientLoop() - Entered loop"); + while (true) + { + QueItem nextPacket = PacketQueue.Dequeue(); + if (nextPacket.Incoming) + { + //is a incoming packet + if (nextPacket.Packet.Type != PacketType.AgentUpdate) { + packetsReceived++; + } + ProcessInPacket(nextPacket.Packet); + } + else + { + //is a out going packet + ProcessOutPacket(nextPacket.Packet); + } + } + } + # endregion + + protected void CheckClientConnectivity(object sender, ElapsedEventArgs e) + { + if (packetsReceived == lastPacketsReceived) { + probesWithNoIngressPackets++; + if (probesWithNoIngressPackets > 30) { + this.KillClient(); + } else { + // this will normally trigger at least one packet (ping response) + SendStartPingCheck(0); + } + } else { + // Something received in the meantime - we can reset the counters + probesWithNoIngressPackets = 0; + lastPacketsReceived = packetsReceived; + } + } + + # region Setup + + protected virtual void InitNewClient() + { + clientPingTimer = new Timer(5000); + clientPingTimer.Elapsed += new ElapsedEventHandler(CheckClientConnectivity); + clientPingTimer.Enabled = true; + + MainLog.Instance.Verbose( "OpenSimClient.cs:InitNewClient() - Adding viewer agent to scene"); + this.m_scene.AddNewClient(this, false); + } + + protected virtual void AuthUser() + { + // AuthenticateResponse sessionInfo = m_gridServer.AuthenticateSession(cirpack.CircuitCode.SessionID, cirpack.CircuitCode.ID, cirpack.CircuitCode.Code); + AuthenticateResponse sessionInfo = this.m_authenticateSessionsHandler.AuthenticateSession(cirpack.CircuitCode.SessionID, cirpack.CircuitCode.ID, cirpack.CircuitCode.Code); + if (!sessionInfo.Authorised) + { + //session/circuit not authorised + MainLog.Instance.Notice("OpenSimClient.cs:AuthUser() - New user request denied to " + userEP.ToString()); + ClientThread.Abort(); + } + else + { + MainLog.Instance.Notice("OpenSimClient.cs:AuthUser() - Got authenticated connection from " + userEP.ToString()); + //session is authorised + this.AgentID = cirpack.CircuitCode.ID; + this.SessionID = cirpack.CircuitCode.SessionID; + this.CircuitCode = cirpack.CircuitCode.Code; + this.firstName = sessionInfo.LoginInfo.First; + this.lastName = sessionInfo.LoginInfo.Last; + + if (sessionInfo.LoginInfo.SecureSession != LLUUID.Zero) + { + this.SecureSessionID = sessionInfo.LoginInfo.SecureSession; + } + InitNewClient(); + + ClientLoop(); + } + } + # endregion + + + protected override void KillThread() + { + this.ClientThread.Abort(); + } + + #region Inventory Creation + private void SetupInventory(AuthenticateResponse sessionInfo) + { + + } + private AgentInventory CreateInventory(LLUUID baseFolder) + { + AgentInventory inventory = null; + + return inventory; + } + + private void CreateInventoryItem(CreateInventoryItemPacket packet) + { + + } + #endregion + + } +} diff --git a/OpenSim/Region/ClientStack/ClientViewBase.cs b/OpenSim/Region/ClientStack/ClientViewBase.cs new file mode 100644 index 0000000000..79f0239a83 --- /dev/null +++ b/OpenSim/Region/ClientStack/ClientViewBase.cs @@ -0,0 +1,331 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Net; +using System.Net.Sockets; +using System.Timers; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Console; +using OpenSim.Framework.Utilities; +using OpenSim.Region.Environment; + +namespace OpenSim.Region.ClientStack +{ + public class ClientViewBase + { + protected BlockingQueue PacketQueue; + protected Dictionary PendingAcks = new Dictionary(); + protected Dictionary NeedAck = new Dictionary(); + + protected Timer AckTimer; + protected uint Sequence = 0; + protected object SequenceLock = new object(); + protected const int MAX_APPENDED_ACKS = 10; + protected const int RESEND_TIMEOUT = 4000; + protected const int MAX_SEQUENCE = 0xFFFFFF; + + public uint CircuitCode; + public EndPoint userEP; + + protected PacketServer m_networkServer; + + public ClientViewBase() + { + + } + + protected virtual void ProcessInPacket(Packet Pack) + { + + } + + protected virtual void ProcessOutPacket(Packet Pack) + { + // Keep track of when this packet was sent out + Pack.TickCount = System.Environment.TickCount; + + // Console.WriteLine(CircuitCode + ":OUT: " + Pack.Type.ToString()); + + if (!Pack.Header.Resent) + { + // Set the sequence number + lock (SequenceLock) + { + if (Sequence >= MAX_SEQUENCE) + { + Sequence = 1; + } + else + { + Sequence++; + } + + Pack.Header.Sequence = Sequence; + } + + if (Pack.Header.Reliable) //DIRTY HACK + { + lock (NeedAck) + { + if (!NeedAck.ContainsKey(Pack.Header.Sequence)) + { + try + { + NeedAck.Add(Pack.Header.Sequence, Pack); + } + catch (Exception e) // HACKY + { + e.ToString(); + // Ignore + // Seems to throw a exception here occasionally + // of 'duplicate key' despite being locked. + // !?!?!? + } + } + else + { + // Client.Log("Attempted to add a duplicate sequence number (" + + // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " + + // packet.Type.ToString(), Helpers.LogLevel.Warning); + } + } + + // Don't append ACKs to resent packets, in case that's what was causing the + // delivery to fail + if (!Pack.Header.Resent) + { + // Append any ACKs that need to be sent out to this packet + lock (PendingAcks) + { + if (PendingAcks.Count > 0 && PendingAcks.Count < MAX_APPENDED_ACKS && + Pack.Type != PacketType.PacketAck && + Pack.Type != PacketType.LogoutRequest) + { + Pack.Header.AckList = new uint[PendingAcks.Count]; + int i = 0; + + foreach (uint ack in PendingAcks.Values) + { + Pack.Header.AckList[i] = ack; + i++; + } + + PendingAcks.Clear(); + Pack.Header.AppendedAcks = true; + } + } + } + } + } + + byte[] ZeroOutBuffer = new byte[4096]; + byte[] sendbuffer; + sendbuffer = Pack.ToBytes(); + + try + { + if (Pack.Header.Zerocoded) + { + int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer); + m_networkServer.SendPacketTo(ZeroOutBuffer, packetsize, SocketFlags.None, CircuitCode);//userEP); + } + else + { + m_networkServer.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, CircuitCode); //userEP); + } + } + catch (Exception) + { + MainLog.Instance.Warn("client", "OpenSimClient.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " + userEP.ToString() + " - killing thread"); + this.KillThread(); + } + + } + + public virtual void InPacket(Packet NewPack) + { + // Handle appended ACKs + if (NewPack.Header.AppendedAcks) + { + lock (NeedAck) + { + foreach (uint ack in NewPack.Header.AckList) + { + NeedAck.Remove(ack); + } + } + } + + // Handle PacketAck packets + if (NewPack.Type == PacketType.PacketAck) + { + PacketAckPacket ackPacket = (PacketAckPacket)NewPack; + + lock (NeedAck) + { + foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets) + { + NeedAck.Remove(block.ID); + } + } + } + else if ((NewPack.Type == PacketType.StartPingCheck)) + { + //reply to pingcheck + StartPingCheckPacket startPing = (StartPingCheckPacket)NewPack; + CompletePingCheckPacket endPing = new CompletePingCheckPacket(); + endPing.PingID.PingID = startPing.PingID.PingID; + OutPacket(endPing); + } + else + { + QueItem item = new QueItem(); + item.Packet = NewPack; + item.Incoming = true; + this.PacketQueue.Enqueue(item); + } + + } + + public virtual void OutPacket(Packet NewPack) + { + QueItem item = new QueItem(); + item.Packet = NewPack; + item.Incoming = false; + this.PacketQueue.Enqueue(item); + } + + # region Low Level Packet Methods + + protected void ack_pack(Packet Pack) + { + if (Pack.Header.Reliable) + { + PacketAckPacket ack_it = new PacketAckPacket(); + ack_it.Packets = new PacketAckPacket.PacketsBlock[1]; + ack_it.Packets[0] = new PacketAckPacket.PacketsBlock(); + ack_it.Packets[0].ID = Pack.Header.Sequence; + ack_it.Header.Reliable = false; + + OutPacket(ack_it); + + } + /* + if (Pack.Header.Reliable) + { + lock (PendingAcks) + { + uint sequence = (uint)Pack.Header.Sequence; + if (!PendingAcks.ContainsKey(sequence)) { PendingAcks[sequence] = sequence; } + } + }*/ + } + + protected void ResendUnacked() + { + int now = System.Environment.TickCount; + + lock (NeedAck) + { + foreach (Packet packet in NeedAck.Values) + { + if ((now - packet.TickCount > RESEND_TIMEOUT) && (!packet.Header.Resent)) + { + MainLog.Instance.Verbose( "Resending " + packet.Type.ToString() + " packet, " + + (now - packet.TickCount) + "ms have passed"); + + packet.Header.Resent = true; + OutPacket(packet); + } + } + } + } + + protected void SendAcks() + { + lock (PendingAcks) + { + if (PendingAcks.Count > 0) + { + if (PendingAcks.Count > 250) + { + // FIXME: Handle the odd case where we have too many pending ACKs queued up + MainLog.Instance.Verbose( "Too many ACKs queued up!"); + return; + } + + //OpenSim.Framework.Console.MainLog.Instance.WriteLine("Sending PacketAck"); + + + int i = 0; + PacketAckPacket acks = new PacketAckPacket(); + acks.Packets = new PacketAckPacket.PacketsBlock[PendingAcks.Count]; + + foreach (uint ack in PendingAcks.Values) + { + acks.Packets[i] = new PacketAckPacket.PacketsBlock(); + acks.Packets[i].ID = ack; + i++; + } + + acks.Header.Reliable = false; + OutPacket(acks); + + PendingAcks.Clear(); + } + } + } + + protected void AckTimer_Elapsed(object sender, ElapsedEventArgs ea) + { + SendAcks(); + ResendUnacked(); + } + #endregion + + protected virtual void KillThread() + { + + } + + #region Nested Classes + + public class QueItem + { + public QueItem() + { + } + + public Packet Packet; + public bool Incoming; + } + #endregion + } +} diff --git a/OpenSim/Region/ClientStack/PacketServer.cs b/OpenSim/Region/ClientStack/PacketServer.cs new file mode 100644 index 0000000000..7fef9b2e28 --- /dev/null +++ b/OpenSim/Region/ClientStack/PacketServer.cs @@ -0,0 +1,172 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Collections.Generic; +using System.Net; +using System.Net.Sockets; +using libsecondlife.Packets; +using OpenSim.Framework; +using OpenSim.Framework.Types; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Communications.Caches; + +namespace OpenSim.Region.ClientStack +{ + public class PacketServer + { + private ClientStackNetworkHandler _networkHandler; + private IScene _localScene; + public Dictionary ClientThreads = new Dictionary(); + private ClientManager m_clientManager = new ClientManager(); + public ClientManager ClientManager + { + get { return m_clientManager; } + } + + public PacketServer(ClientStackNetworkHandler networkHandler) + { + _networkHandler = networkHandler; + _networkHandler.RegisterPacketServer(this); + } + + public IScene LocalScene + { + set + { + this._localScene = value; + } + } + + /// + /// + /// + /// + /// + public virtual void ClientInPacket(uint circuitCode, Packet packet) + { + if (this.ClientThreads.ContainsKey(circuitCode)) + { + ClientThreads[circuitCode].InPacket(packet); + } + } + + /// + /// + /// + /// + /// + public virtual bool AddNewCircuitCodeClient(uint circuitCode) + { + return false; + } + + /// + /// + /// + /// + public virtual void SendPacketToAllClients(Packet packet) + { + + } + + /// + /// + /// + /// + /// + public virtual void SendPacketToAllExcept(Packet packet, ClientView simClient) + { + + } + + /// + /// + /// + /// + /// + public virtual void AddClientPacketHandler(PacketType packetType, PacketMethod handler) + { + + } + + /// + /// + /// + public virtual void RegisterClientPacketHandlers() + { + + } + + protected virtual ClientView CreateNewClient(EndPoint remoteEP, UseCircuitCodePacket initialcirpack, Dictionary clientThreads, IScene scene, AssetCache assetCache, PacketServer packServer, AgentCircuitManager authenSessions) + { + return new ClientView(remoteEP, initialcirpack, clientThreads, scene, assetCache, packServer, authenSessions ); + } + + /// + /// + /// + /// + /// + /// + /// + /// + /// + public virtual bool AddNewClient(EndPoint epSender, UseCircuitCodePacket useCircuit, AssetCache assetCache, AgentCircuitManager authenticateSessionsClass) + { + ClientView newuser = + CreateNewClient(epSender, useCircuit, ClientThreads, _localScene, assetCache, this, + authenticateSessionsClass); + + this.ClientThreads.Add(useCircuit.CircuitCode.Code, newuser); + this.m_clientManager.Add(useCircuit.CircuitCode.Code, (IClientAPI)newuser); + + return true; + } + + /// + /// + /// + /// + /// + /// + /// + public virtual void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode) + { + this._networkHandler.SendPacketTo(buffer, size, flags, circuitcode); + } + + /// + /// + /// + /// + public virtual void RemoveClientCircuit(uint circuitcode) + { + this._networkHandler.RemoveClientCircuit(circuitcode); + this.m_clientManager.Remove(circuitcode); + } + } +} diff --git a/OpenSim/Region/ClientStack/RegionApplicationBase.cs b/OpenSim/Region/ClientStack/RegionApplicationBase.cs new file mode 100644 index 0000000000..a958887c95 --- /dev/null +++ b/OpenSim/Region/ClientStack/RegionApplicationBase.cs @@ -0,0 +1,140 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Net; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Data; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Types; +using OpenSim.Physics.Manager; +using OpenSim.Region.Environment; +using libsecondlife; +using OpenSim.Region.Environment.Scenes; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Communications.Caches; + +namespace OpenSim.Region.ClientStack +{ + public abstract class RegionApplicationBase + { + protected AssetCache m_assetCache; + protected Dictionary m_clientCircuits = new Dictionary(); + protected DateTime m_startuptime; + protected NetworkServersInfo m_networkServersInfo; + + protected BaseHttpServer m_httpServer; + protected int m_httpServerPort; + + protected LogBase m_log; + protected CommunicationsManager m_commsManager; + + public RegionApplicationBase() + { + m_startuptime = DateTime.Now; + } + + virtual public void StartUp() + { + + ClientView.TerrainManager = new TerrainManager(new SecondLife()); + + Initialize(); + + ScenePresence.CreateDefaultTextureEntry(); + + m_httpServer = new BaseHttpServer(m_httpServerPort); + + m_log.Verbose("Starting HTTP server"); + m_httpServer.Start(); + } + + protected abstract void Initialize(); + + protected void StartLog() + { + m_log = CreateLog(); + MainLog.Instance = m_log; + } + + protected abstract LogBase CreateLog(); + protected abstract PhysicsScene GetPhysicsScene(); + protected abstract StorageManager CreateStorageManager(RegionInfo regionInfo); + + protected PhysicsScene GetPhysicsScene(string engine) + { + PhysicsPluginManager physicsPluginManager; + physicsPluginManager = new PhysicsPluginManager(); + physicsPluginManager.LoadPlugins(); + return physicsPluginManager.GetPhysicsScene(engine); + } + + protected Scene SetupScene(RegionInfo regionInfo, out UDPServer udpServer) + { + AgentCircuitManager authen = new AgentCircuitManager(); + udpServer = new UDPServer(regionInfo.InternalEndPoint.Port, m_assetCache, m_log, authen); + + StorageManager storageManager = CreateStorageManager(regionInfo); + Scene scene = CreateScene(regionInfo, storageManager, authen); + + udpServer.LocalScene = scene; + + scene.LoadWorldMap(); + + scene.PhysScene = GetPhysicsScene(); + scene.PhysScene.SetTerrain(scene.Terrain.GetHeights1D()); + scene.LoadPrimsFromStorage(); + + //Master Avatar Setup + UserProfileData masterAvatar = m_commsManager.UserServer.SetupMasterUser(scene.RegionInfo.MasterAvatarFirstName, scene.RegionInfo.MasterAvatarLastName, scene.RegionInfo.MasterAvatarSandboxPassword); + if (masterAvatar != null) + { + m_log.Verbose("PARCEL", "Found master avatar [" + masterAvatar.UUID.ToStringHyphenated() + "]"); + scene.RegionInfo.MasterAvatarAssignedUUID = masterAvatar.UUID; + //TODO: Load parcels from storageManager + } + else + { + m_log.Verbose("PARCEL", "No master avatar found, using null."); + scene.RegionInfo.MasterAvatarAssignedUUID = libsecondlife.LLUUID.Zero; + //TODO: Load parcels from storageManager + } + scene.LandManager.resetSimLandObjects(); + + scene.performParcelPrimCountUpdate(); + scene.StartTimer(); + return scene; + } + + protected abstract Scene CreateScene(RegionInfo regionInfo, StorageManager storageManager, AgentCircuitManager circuitManager); + + + } +} diff --git a/OpenSim/Region/ClientStack/UDPServer.cs b/OpenSim/Region/ClientStack/UDPServer.cs new file mode 100644 index 0000000000..6feaa9b6c1 --- /dev/null +++ b/OpenSim/Region/ClientStack/UDPServer.cs @@ -0,0 +1,193 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Net; +using System.Net.Sockets; +using libsecondlife.Packets; +using OpenSim.Framework; +using OpenSim.Framework.Types; +using OpenSim.Framework.Console; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Communications.Caches; + +namespace OpenSim.Region.ClientStack +{ + + public class UDPServer : ClientStackNetworkHandler + { + protected Dictionary clientCircuits = new Dictionary(); + public Socket Server; + protected IPEndPoint ServerIncoming; + protected byte[] RecvBuffer = new byte[4096]; + protected byte[] ZeroBuffer = new byte[8192]; + protected IPEndPoint ipeSender; + protected EndPoint epSender; + protected AsyncCallback ReceivedData; + protected PacketServer _packetServer; + + protected int listenPort; + protected IScene m_localScene; + protected AssetCache m_assetCache; + protected LogBase m_log; + protected AgentCircuitManager m_authenticateSessionsClass; + + public PacketServer PacketServer + { + get + { + return _packetServer; + } + set + { + _packetServer = value; + } + } + + public IScene LocalScene + { + set + { + this.m_localScene = value; + this._packetServer.LocalScene = this.m_localScene; + } + } + + public UDPServer() + { + } + + public UDPServer(int port, AssetCache assetCache, LogBase console, AgentCircuitManager authenticateClass) + { + listenPort = port; + this.m_assetCache = assetCache; + this.m_log = console; + this.m_authenticateSessionsClass = authenticateClass; + this.CreatePacketServer(); + } + + protected virtual void CreatePacketServer() + { + PacketServer packetServer = new PacketServer(this); + } + + protected virtual void OnReceivedData(IAsyncResult result) + { + ipeSender = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0); + epSender = (EndPoint)ipeSender; + Packet packet = null; + int numBytes = Server.EndReceiveFrom(result, ref epSender); + int packetEnd = numBytes - 1; + + packet = Packet.BuildPacket(RecvBuffer, ref packetEnd, ZeroBuffer); + + // do we already have a circuit for this endpoint + if (this.clientCircuits.ContainsKey(epSender)) + { + //if so then send packet to the packetserver + this._packetServer.ClientInPacket(this.clientCircuits[epSender], packet); + } + else if (packet.Type == PacketType.UseCircuitCode) + { + // new client + this.AddNewClient(packet); + } + else + { // invalid client + m_log.Warn("client", "Got a packet from an invalid client - " + epSender.ToString()); + } + + Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); + } + + protected virtual void AddNewClient(Packet packet) + { + UseCircuitCodePacket useCircuit = (UseCircuitCodePacket)packet; + this.clientCircuits.Add(epSender, useCircuit.CircuitCode.Code); + + this.PacketServer.AddNewClient(epSender, useCircuit, m_assetCache, m_authenticateSessionsClass); + } + + public void ServerListener() + { + m_log.Verbose("SERVER", "Opening UDP socket on " + listenPort); + + ServerIncoming = new IPEndPoint(IPAddress.Parse("0.0.0.0"), listenPort); + Server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + Server.Bind(ServerIncoming); + + m_log.Verbose("SERVER", "UDP socket bound, getting ready to listen"); + + ipeSender = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0); + epSender = (EndPoint)ipeSender; + ReceivedData = new AsyncCallback(this.OnReceivedData); + Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); + + m_log.Status("SERVER", "Listening..."); + + } + + public virtual void RegisterPacketServer(PacketServer server) + { + this._packetServer = server; + } + + public virtual void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode)//EndPoint packetSender) + { + // find the endpoint for this circuit + EndPoint sendto = null; + foreach (KeyValuePair p in this.clientCircuits) + { + if (p.Value == circuitcode) + { + sendto = p.Key; + break; + } + } + if (sendto != null) + { + //we found the endpoint so send the packet to it + this.Server.SendTo(buffer, size, flags, sendto); + } + } + + public virtual void RemoveClientCircuit(uint circuitcode) + { + foreach (KeyValuePair p in this.clientCircuits) + { + if (p.Value == circuitcode) + { + this.clientCircuits.Remove(p.Key); + break; + } + } + } + + + } +} \ No newline at end of file diff --git a/OpenSim/Region/Communications/Local/CommunicationsLocal.cs b/OpenSim/Region/Communications/Local/CommunicationsLocal.cs new file mode 100644 index 0000000000..5d1ab94b16 --- /dev/null +++ b/OpenSim/Region/Communications/Local/CommunicationsLocal.cs @@ -0,0 +1,130 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 OpenSim.Framework.Communications; +using OpenSim.Framework.Types; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Communications.Caches; +using OpenSim.Framework.Console; +using OpenSim.Framework.Utilities; +using OpenSim.Framework.Data; +using OpenSim.Framework.UserManagement; + +namespace OpenSim.Region.Communications.Local +{ + public class CommunicationsLocal : CommunicationsManager + { + public LocalBackEndServices InstanceServices; + public LocalUserServices UserServices; + public LocalLoginService LoginServices; + public LocalInventoryService InvenServices; + // public CAPSService CapsServices; + private LocalSettings m_settings; + + public CommunicationsLocal(NetworkServersInfo serversInfo, BaseHttpServer httpServer, AssetCache assetCache, LocalSettings settings ) + : base(serversInfo, httpServer, assetCache) + { + m_settings = settings; + + InvenServices = new LocalInventoryService(); + InvenServices.AddPlugin(m_settings.InventoryPlugin); + InventoryServer = InvenServices; + + UserServices = new LocalUserServices(this, serversInfo); + UserServices.AddPlugin(m_settings.UserDatabasePlugin); + UserServer = UserServices; + + InstanceServices = new LocalBackEndServices(); + GridServer = InstanceServices; + InterRegion = InstanceServices; + + //CapsServices = new CAPSService(httpServer); + + LoginServices = new LocalLoginService(UserServices, m_settings.WelcomeMessage, this, serversInfo, m_settings.AccountAuthentication); + httpServer.AddXmlRPCHandler("login_to_simulator", LoginServices.XmlRpcLoginMethod); + } + + internal void InformRegionOfLogin(ulong regionHandle, Login login) + { + this.InstanceServices.AddNewSession(regionHandle, login); + } + + public void doCreate(string what) + { + switch (what) + { + case "user": + string tempfirstname; + string templastname; + string tempMD5Passwd; + uint regX = 1000; + uint regY = 1000; + + tempfirstname = MainLog.Instance.CmdPrompt("First name"); + templastname = MainLog.Instance.CmdPrompt("Last name"); + tempMD5Passwd = MainLog.Instance.PasswdPrompt("Password"); + regX = Convert.ToUInt32(MainLog.Instance.CmdPrompt("Start Region X")); + regY = Convert.ToUInt32(MainLog.Instance.CmdPrompt("Start Region Y")); + + tempMD5Passwd = Util.Md5Hash(Util.Md5Hash(tempMD5Passwd) + ":" + ""); + + this.UserServices.AddUserProfile(tempfirstname, templastname, tempMD5Passwd, regX, regY); + UserProfileData userProf = this.UserServer.GetUserProfile(tempfirstname, templastname); + if (userProf != null) + { + this.InvenServices.CreateNewUserInventory(userProf.UUID); + Console.WriteLine("created new inventory set for " + tempfirstname + " " + templastname); + } + break; + } + } + + public class LocalSettings + { + public string WelcomeMessage = ""; + public bool AccountAuthentication = false; + public string InventoryPlugin = "OpenSim.Framework.Data.SQLite.dll"; + public string UserDatabasePlugin = "OpenSim.Framework.Data.DB4o.dll"; + + public LocalSettings(string welcomeMessage, bool accountsAuthenticate, string inventoryPlugin, string userPlugin) + { + WelcomeMessage = welcomeMessage; + AccountAuthentication = accountsAuthenticate; + if (inventoryPlugin != "") + { + InventoryPlugin = inventoryPlugin; + } + if (userPlugin != "") + { + UserDatabasePlugin = userPlugin; + } + } + } + + } +} diff --git a/OpenSim/Region/Communications/Local/LocalBackEndServices.cs b/OpenSim/Region/Communications/Local/LocalBackEndServices.cs new file mode 100644 index 0000000000..8e303ad11b --- /dev/null +++ b/OpenSim/Region/Communications/Local/LocalBackEndServices.cs @@ -0,0 +1,215 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Collections.Generic; +using libsecondlife; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Types; + +namespace OpenSim.Region.Communications.Local +{ + + public class LocalBackEndServices : IGridServices, IInterRegionCommunications + { + protected Dictionary regions = new Dictionary(); + protected Dictionary regionHosts = new Dictionary(); + + public LocalBackEndServices() + { + + } + + /// + /// Register a region method with the BackEnd Services. + /// + /// + /// + public RegionCommsListener RegisterRegion(RegionInfo regionInfo) + { + //Console.WriteLine("CommsManager - Region " + regionInfo.RegionHandle + " , " + regionInfo.RegionLocX + " , "+ regionInfo.RegionLocY +" is registering"); + if (!this.regions.ContainsKey((uint)regionInfo.RegionHandle)) + { + //Console.WriteLine("CommsManager - Adding Region " + regionInfo.RegionHandle ); + this.regions.Add(regionInfo.RegionHandle, regionInfo); + RegionCommsListener regionHost = new RegionCommsListener(); + this.regionHosts.Add(regionInfo.RegionHandle, regionHost); + + return regionHost; + } + + //already in our list of regions so for now lets return null + return null; + } + + /// + /// + /// + /// + public List RequestNeighbours(RegionInfo regionInfo) + { + // Console.WriteLine("Finding Neighbours to " + regionInfo.RegionHandle); + List neighbours = new List(); + + foreach (RegionInfo reg in this.regions.Values) + { + // Console.WriteLine("CommsManager- RequestNeighbours() checking region " + reg.RegionLocX + " , "+ reg.RegionLocY); + if (reg.RegionHandle != regionInfo.RegionHandle) + { + //Console.WriteLine("CommsManager- RequestNeighbours() - found a different region in list, checking location"); + if ((reg.RegionLocX > (regionInfo.RegionLocX - 2)) && (reg.RegionLocX < (regionInfo.RegionLocX + 2))) + { + if ((reg.RegionLocY > (regionInfo.RegionLocY - 2)) && (reg.RegionLocY < (regionInfo.RegionLocY + 2))) + { + neighbours.Add(reg); + } + } + } + } + return neighbours; + } + + /// + /// + /// + /// + /// + public RegionInfo RequestNeighbourInfo(ulong regionHandle) + { + if (this.regions.ContainsKey(regionHandle)) + { + return this.regions[regionHandle]; + } + return null; + } + + /// + /// + /// + /// + /// + /// + /// + /// + public List RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY) + { + List mapBlocks = new List(); + foreach(RegionInfo regInfo in this.regions.Values) + { + if (((regInfo.RegionLocX >= minX) && (regInfo.RegionLocX <= maxX)) && ((regInfo.RegionLocY >= minY) && (regInfo.RegionLocY <= maxY))) + { + MapBlockData map = new MapBlockData(); + map.Name = regInfo.RegionName; + map.X = (ushort)regInfo.RegionLocX; + map.Y = (ushort)regInfo.RegionLocY; + map.WaterHeight =(byte) regInfo.estateSettings.waterHeight; + map.MapImageId = regInfo.estateSettings.terrainImageID; //new LLUUID("00000000-0000-0000-9999-000000000007"); + map.Agents = 1; + map.RegionFlags = 72458694; + map.Access = 13; + mapBlocks.Add(map); + } + } + return mapBlocks; + } + + /// + /// + /// + /// + /// + public bool InformRegionOfChildAgent(ulong regionHandle, AgentCircuitData agentData) //should change from agentCircuitData + { + //Console.WriteLine("CommsManager- Trying to Inform a region to expect child agent"); + if (this.regionHosts.ContainsKey(regionHandle)) + { + // Console.WriteLine("CommsManager- Informing a region to expect child agent"); + this.regionHosts[regionHandle].TriggerExpectUser(regionHandle, agentData); + return true; + } + return false; + } + + /// + /// + /// + /// + /// + /// + /// + public bool ExpectAvatarCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying) + { + if (this.regionHosts.ContainsKey(regionHandle)) + { + // Console.WriteLine("CommsManager- Informing a region to expect avatar crossing"); + this.regionHosts[regionHandle].TriggerExpectAvatarCrossing(regionHandle, agentID, position, isFlying); + return true; + } + return false; + } + + public bool AcknowledgeAgentCrossed(ulong regionHandle, LLUUID agentID) + { + if (this.regionHosts.ContainsKey(regionHandle)) + { + return true; + } + return false; + } + + /// + /// Is a Sandbox mode method, used by the local Login server to inform a region of a connection user/session + /// + /// + /// + /// + public bool AddNewSession(ulong regionHandle, Login loginData) + { + AgentCircuitData agent = new AgentCircuitData(); + agent.AgentID = loginData.Agent; + agent.firstname = loginData.First; + agent.lastname = loginData.Last; + agent.SessionID = loginData.Session; + agent.SecureSessionID = loginData.SecureSession; + agent.circuitcode = loginData.CircuitCode; + agent.BaseFolder = loginData.BaseFolder; + agent.InventoryFolder = loginData.InventoryFolder; + agent.startpos = new LLVector3(128, 128, 70); + agent.CapsPath = loginData.CapsPath; + + if (this.regionHosts.ContainsKey(regionHandle)) + { + this.regionHosts[regionHandle].TriggerExpectUser(regionHandle, agent); + return true; + } + + // region not found + return false; + } + } +} + diff --git a/OpenSim/Region/Communications/Local/LocalInventoryService.cs b/OpenSim/Region/Communications/Local/LocalInventoryService.cs new file mode 100644 index 0000000000..af58d33286 --- /dev/null +++ b/OpenSim/Region/Communications/Local/LocalInventoryService.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using libsecondlife; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Data; +using OpenSim.Framework.Types; +using OpenSim.Framework.UserManagement; +using OpenSim.Framework.Utilities; +using OpenSim.Framework.InventoryServiceBase; +using InventoryFolder = OpenSim.Framework.Communications.Caches.InventoryFolder; + +namespace OpenSim.Region.Communications.Local +{ + public class LocalInventoryService : InventoryServiceBase , IInventoryServices + { + + public LocalInventoryService() + { + + } + + public void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack, InventoryItemInfo itemCallBack) + { + List folders = this.RequestFirstLevelFolders(userID); + InventoryFolder rootFolder = null; + + //need to make sure we send root folder first + foreach (InventoryFolderBase folder in folders) + { + if (folder.parentID == libsecondlife.LLUUID.Zero) + { + InventoryFolder newfolder = new InventoryFolder(folder); + rootFolder = newfolder; + folderCallBack(userID, newfolder); + } + } + + if (rootFolder != null) + { + foreach (InventoryFolderBase folder in folders) + { + if (folder.folderID != rootFolder.folderID) + { + InventoryFolder newfolder = new InventoryFolder(folder); + folderCallBack(userID, newfolder); + + List items = this.RequestFolderItems(newfolder.folderID); + foreach (InventoryItemBase item in items) + { + itemCallBack(userID, item); + } + } + } + } + } + + public void AddNewInventoryFolder(LLUUID userID, InventoryFolder folder) + { + this.AddFolder(folder); + } + + public void AddNewInventoryItem(LLUUID userID, InventoryItemBase item) + { + this.AddItem(item); + } + + public void DeleteInventoryItem(LLUUID userID, InventoryItemBase item) + { + this.deleteItem(item); + } + } +} diff --git a/OpenSim/Region/Communications/Local/LocalLoginService.cs b/OpenSim/Region/Communications/Local/LocalLoginService.cs new file mode 100644 index 0000000000..d3b76de346 --- /dev/null +++ b/OpenSim/Region/Communications/Local/LocalLoginService.cs @@ -0,0 +1,162 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using libsecondlife; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Data; +using OpenSim.Framework.Types; +using OpenSim.Framework.UserManagement; +using OpenSim.Framework.Utilities; +using OpenSim.Framework.Inventory; + +namespace OpenSim.Region.Communications.Local +{ + public class LocalLoginService : LoginService + { + private CommunicationsLocal m_Parent; + + private NetworkServersInfo serversInfo; + private uint defaultHomeX; + private uint defaultHomeY; + private bool authUsers = false; + + public LocalLoginService(UserManagerBase userManager, string welcomeMess, CommunicationsLocal parent, NetworkServersInfo serversInfo, bool authenticate) + : base(userManager, welcomeMess) + { + m_Parent = parent; + this.serversInfo = serversInfo; + defaultHomeX = this.serversInfo.DefaultHomeLocX; + defaultHomeY = this.serversInfo.DefaultHomeLocY; + this.authUsers = authenticate; + } + + + public override UserProfileData GetTheUser(string firstname, string lastname) + { + UserProfileData profile = this.m_userManager.getUserProfile(firstname, lastname); + if (profile != null) + { + + return profile; + } + + if (!authUsers) + { + //no current user account so make one + Console.WriteLine("No User account found so creating a new one "); + this.m_userManager.AddUserProfile(firstname, lastname, "test", defaultHomeX, defaultHomeY); + + profile = this.m_userManager.getUserProfile(firstname, lastname); + + return profile; + } + return null; + } + + public override bool AuthenticateUser(UserProfileData profile, string password) + { + if (!authUsers) + { + //for now we will accept any password in sandbox mode + Console.WriteLine("authorising user"); + return true; + } + else + { + Console.WriteLine("Authenticating " + profile.username + " " + profile.surname); + + password = password.Remove(0, 3); //remove $1$ + + string s = Util.Md5Hash(password + ":" + profile.passwordSalt); + + return profile.passwordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase); + } + } + + public override void CustomiseResponse(LoginResponse response, UserProfileData theUser) + { + ulong currentRegion = theUser.currentAgent.currentHandle; + RegionInfo reg = m_Parent.GridServer.RequestNeighbourInfo(currentRegion); + + if (reg != null) + { + response.Home = "{'region_handle':[r" + (reg.RegionLocX * 256).ToString() + ",r" + (reg.RegionLocY * 256).ToString() + "], " + + "'position':[r" + theUser.homeLocation.X.ToString() + ",r" + theUser.homeLocation.Y.ToString() + ",r" + theUser.homeLocation.Z.ToString() + "], " + + "'look_at':[r" + theUser.homeLocation.X.ToString() + ",r" + theUser.homeLocation.Y.ToString() + ",r" + theUser.homeLocation.Z.ToString() + "]}"; + string capsPath = Util.GetRandomCapsPath(); + response.SimAddress = reg.ExternalEndPoint.Address.ToString(); + response.SimPort = (Int32)reg.ExternalEndPoint.Port; + response.RegionX = reg.RegionLocX; + response.RegionY = reg.RegionLocY; + + response.SeedCapability = "http://" + reg.ExternalHostName + ":" + this.serversInfo.HttpListenerPort.ToString() + "/CAPS/" + capsPath + "0000/"; + // response.SeedCapability = "http://" + reg.ExternalHostName + ":" + this.serversInfo.HttpListenerPort.ToString() + "/CapsSeed/" + capsPath + "0000/"; + theUser.currentAgent.currentRegion = reg.SimUUID; + theUser.currentAgent.currentHandle = reg.RegionHandle; + + Login _login = new Login(); + //copy data to login object + _login.First = response.Firstname; + _login.Last = response.Lastname; + _login.Agent = response.AgentID; + _login.Session = response.SessionID; + _login.SecureSession = response.SecureSessionID; + _login.CircuitCode = (uint)response.CircuitCode; + _login.CapsPath = capsPath; + + m_Parent.InformRegionOfLogin(currentRegion, _login); + } + else + { + Console.WriteLine("not found region " + currentRegion); + } + + } + + protected override InventoryData CreateInventoryData(LLUUID userID) + { + List folders = this.m_Parent.InvenServices.RequestFirstLevelFolders(userID); + if (folders.Count > 0) + { + LLUUID rootID = LLUUID.Zero; + ArrayList AgentInventoryArray = new ArrayList(); + Hashtable TempHash; + foreach (InventoryFolderBase InvFolder in folders) + { + if (InvFolder.parentID == LLUUID.Zero) + { + rootID = InvFolder.folderID; + } + TempHash = new Hashtable(); + TempHash["name"] = InvFolder.name; + TempHash["parent_id"] = InvFolder.parentID.ToStringHyphenated(); + TempHash["version"] = (Int32)InvFolder.version; + TempHash["type_default"] = (Int32)InvFolder.type; + TempHash["folder_id"] = InvFolder.folderID.ToStringHyphenated(); + AgentInventoryArray.Add(TempHash); + } + return new InventoryData(AgentInventoryArray, rootID); + } + else + { + AgentInventory userInventory = new AgentInventory(); + userInventory.CreateRootFolder(userID, false); + + ArrayList AgentInventoryArray = new ArrayList(); + Hashtable TempHash; + foreach (OpenSim.Framework.Inventory.InventoryFolder InvFolder in userInventory.InventoryFolders.Values) + { + TempHash = new Hashtable(); + TempHash["name"] = InvFolder.FolderName; + TempHash["parent_id"] = InvFolder.ParentID.ToStringHyphenated(); + TempHash["version"] = (Int32)InvFolder.Version; + TempHash["type_default"] = (Int32)InvFolder.DefaultType; + TempHash["folder_id"] = InvFolder.FolderID.ToStringHyphenated(); + AgentInventoryArray.Add(TempHash); + } + + return new InventoryData(AgentInventoryArray, userInventory.InventoryRoot.FolderID); + } + } + } +} diff --git a/OpenSim/Region/Communications/Local/LocalUserServices.cs b/OpenSim/Region/Communications/Local/LocalUserServices.cs new file mode 100644 index 0000000000..8fea858bce --- /dev/null +++ b/OpenSim/Region/Communications/Local/LocalUserServices.cs @@ -0,0 +1,70 @@ +using System; +using libsecondlife; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Data; +using OpenSim.Framework.Types; +using OpenSim.Framework.UserManagement; +using OpenSim.Framework.Utilities; + +namespace OpenSim.Region.Communications.Local +{ + public class LocalUserServices : UserManagerBase, IUserServices + { + private CommunicationsLocal m_Parent; + + private NetworkServersInfo serversInfo; + private uint defaultHomeX ; + private uint defaultHomeY; + + + public LocalUserServices(CommunicationsLocal parent, NetworkServersInfo serversInfo) + { + m_Parent = parent; + this.serversInfo = serversInfo; + defaultHomeX = this.serversInfo.DefaultHomeLocX; + defaultHomeY = this.serversInfo.DefaultHomeLocY; + } + + public UserProfileData GetUserProfile(string firstName, string lastName) + { + return GetUserProfile(firstName + " " + lastName); + } + + public UserProfileData GetUserProfile(string name) + { + return this.getUserProfile(name); + } + + public UserProfileData GetUserProfile(LLUUID avatarID) + { + return this.getUserProfile(avatarID); + } + + 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/Local/Properties/AssemblyInfo.cs b/OpenSim/Region/Communications/Local/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..9afb75ee22 --- /dev/null +++ b/OpenSim/Region/Communications/Local/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.Region.Communications.Local")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OpenSim.Region.Communications.Local")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("fb173926-bd0a-4cd0-bb45-185b2f72ddfb")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/Communications/OGS1/CommunicationsOGS1.cs b/OpenSim/Region/Communications/OGS1/CommunicationsOGS1.cs new file mode 100644 index 0000000000..78867e8722 --- /dev/null +++ b/OpenSim/Region/Communications/OGS1/CommunicationsOGS1.cs @@ -0,0 +1,25 @@ +using OpenSim.Framework.Communications; +using OpenSim.Framework.Types; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Communications.Caches; + + +namespace OpenSim.Region.Communications.OGS1 +{ + public class CommunicationsOGS1 : CommunicationsManager + { + public OGS1InventoryService InvenService; + + public CommunicationsOGS1(NetworkServersInfo serversInfo, BaseHttpServer httpServer, AssetCache assetCache ) :base(serversInfo, httpServer, assetCache) + { + OGS1GridServices gridInterComms = new OGS1GridServices(serversInfo, httpServer); + GridServer = gridInterComms; + InterRegion = gridInterComms; + + InvenService = new OGS1InventoryService(); + InventoryServer = InvenService; + + UserServer = new OGS1UserServices(this); + } + } +} diff --git a/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs b/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs new file mode 100644 index 0000000000..27282756e7 --- /dev/null +++ b/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs @@ -0,0 +1,501 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Net; +using System.Runtime.Remoting; +using System.Runtime.Remoting.Channels; +using System.Runtime.Remoting.Channels.Tcp; +using libsecondlife; +using Nwc.XmlRpc; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Console; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Types; + +namespace OpenSim.Region.Communications.OGS1 +{ + public class OGS1GridServices : IGridServices, IInterRegionCommunications + { + public Dictionary listeners = new Dictionary(); + protected Dictionary regions = new Dictionary(); + + public BaseHttpServer httpListener; + public NetworkServersInfo serversInfo; + public BaseHttpServer httpServer; + + /// + /// + /// + /// + /// + public OGS1GridServices(NetworkServersInfo servers_info, BaseHttpServer httpServe) + { + serversInfo = servers_info; + httpServer = httpServe; + httpServer.AddXmlRPCHandler("expect_user", this.ExpectUser); + httpServer.AddXmlRPCHandler("check", this.PingCheckReply); + this.StartRemoting(); + } + + /// + /// + /// + /// + /// + public RegionCommsListener RegisterRegion(RegionInfo regionInfo) + { + if (!this.regions.ContainsKey((uint)regionInfo.RegionHandle)) + { + this.regions.Add(regionInfo.RegionHandle, regionInfo); + } + + Hashtable GridParams = new Hashtable(); + // Login / Authentication + + GridParams["authkey"] = serversInfo.GridSendKey; + GridParams["UUID"] = regionInfo.SimUUID.ToStringHyphenated(); + GridParams["sim_ip"] = regionInfo.ExternalHostName; + GridParams["sim_port"] = regionInfo.InternalEndPoint.Port.ToString(); + GridParams["region_locx"] = regionInfo.RegionLocX.ToString(); + GridParams["region_locy"] = regionInfo.RegionLocY.ToString(); + GridParams["sim_name"] = regionInfo.RegionName; + GridParams["http_port"] = serversInfo.HttpListenerPort.ToString(); + GridParams["remoting_port"] = serversInfo.RemotingListenerPort.ToString(); + GridParams["map-image-id"] = regionInfo.estateSettings.terrainImageID.ToStringHyphenated(); + + // Package into an XMLRPC Request + ArrayList SendParams = new ArrayList(); + SendParams.Add(GridParams); + + // Send Request + XmlRpcRequest GridReq = new XmlRpcRequest("simulator_login", SendParams); + XmlRpcResponse GridResp = GridReq.Send(serversInfo.GridURL, 3000); + Hashtable GridRespData = (Hashtable)GridResp.Value; + + Hashtable griddatahash = GridRespData; + + // Process Response + if (GridRespData.ContainsKey("error")) + { + string errorstring = (string)GridRespData["error"]; + MainLog.Instance.Error("Unable to connect to grid: " + errorstring); + return null; + } + + // Initialise the background listeners + RegionCommsListener regListener = new RegionCommsListener(); + if (!this.listeners.ContainsKey(regionInfo.RegionHandle)) + { + this.listeners.Add(regionInfo.RegionHandle, regListener); + } + else + { + listeners[regionInfo.RegionHandle] = regListener; + } + + return regListener; + } + + /// + /// + /// + /// + /// + public List RequestNeighbours(RegionInfo regionInfo) + { + + Hashtable respData = MapBlockQuery((int)regionInfo.RegionLocX - 1, (int)regionInfo.RegionLocY - 1, (int)regionInfo.RegionLocX + 1, (int)regionInfo.RegionLocY + 1); + + List neighbours = new List(); + + foreach (ArrayList a in respData.Values) + { + foreach (Hashtable n in a) + { + uint regX = Convert.ToUInt32(n["x"]); + uint regY = Convert.ToUInt32(n["y"]); + if ((regionInfo.RegionLocX != regX) || (regionInfo.RegionLocY != regY)) + { + string externalIpStr = OpenSim.Framework.Utilities.Util.GetHostFromDNS((string)n["sim_ip"]).ToString(); + uint port = Convert.ToUInt32(n["sim_port"]); + string externalUri = (string)n["sim_uri"]; + + IPEndPoint neighbourInternalEndPoint = new IPEndPoint(IPAddress.Parse(externalIpStr), (int)port); + string neighbourExternalUri = externalUri; + RegionInfo neighbour = new RegionInfo(regX, regY, neighbourInternalEndPoint, externalIpStr); + + //OGS1 + //neighbour.RegionHandle = (ulong)n["regionhandle"]; is now calculated locally + + neighbour.RegionName = (string)n["name"]; + + //OGS1+ + neighbour.SimUUID = (string)n["uuid"]; + + neighbours.Add(neighbour); + } + } + } + + return neighbours; + } + + /// + /// + /// + /// + /// + public RegionInfo RequestNeighbourInfo(ulong regionHandle) + { + if (this.regions.ContainsKey(regionHandle)) + { + return this.regions[regionHandle]; + } + + Hashtable requestData = new Hashtable(); + requestData["region_handle"] = regionHandle.ToString(); + requestData["authkey"] = this.serversInfo.GridSendKey; + ArrayList SendParams = new ArrayList(); + SendParams.Add(requestData); + XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams); + XmlRpcResponse GridResp = GridReq.Send(this.serversInfo.GridURL, 3000); + + Hashtable responseData = (Hashtable)GridResp.Value; + + if (responseData.ContainsKey("error")) + { + Console.WriteLine("error received from grid server" + responseData["error"]); + return null; + } + + uint regX = Convert.ToUInt32((string)responseData["region_locx"]); + uint regY = Convert.ToUInt32((string)responseData["region_locy"]); + string internalIpStr = (string)responseData["sim_ip"]; + uint port = Convert.ToUInt32(responseData["sim_port"]); + string externalUri = (string)responseData["sim_uri"]; + + IPEndPoint neighbourInternalEndPoint = new IPEndPoint(IPAddress.Parse(internalIpStr), (int)port); + string neighbourExternalUri = externalUri; + RegionInfo regionInfo = new RegionInfo(regX, regY, neighbourInternalEndPoint, internalIpStr); + + regionInfo.RemotingPort = Convert.ToUInt32((string)responseData["remoting_port"]); + regionInfo.RemotingAddress = internalIpStr; + + regionInfo.SimUUID = new LLUUID((string)responseData["region_UUID"]); + regionInfo.RegionName = (string)responseData["region_name"]; + + return regionInfo; + } + + /// + /// + /// + /// + /// + /// + /// + /// + public List RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY) + { + Hashtable respData = MapBlockQuery(minX, minY, maxX, maxY); + + List neighbours = new List(); + + foreach (ArrayList a in respData.Values) + { + foreach (Hashtable n in a) + { + MapBlockData neighbour = new MapBlockData(); + + neighbour.X = Convert.ToUInt16(n["x"]); + neighbour.Y = Convert.ToUInt16(n["y"]); + + neighbour.Name = (string)n["name"]; + neighbour.Access = Convert.ToByte(n["access"]); + neighbour.RegionFlags = Convert.ToUInt32(n["region-flags"]); + neighbour.WaterHeight = Convert.ToByte(n["water-height"]); + neighbour.MapImageId = new LLUUID((string)n["map-image-id"]); + + neighbours.Add(neighbour); + } + } + + return neighbours; + } + + /// + /// Performs a XML-RPC query against the grid server returning mapblock information in the specified coordinates + /// + /// REDUNDANT - OGS1 is to be phased out in favour of OGS2 + /// Minimum X value + /// Minimum Y value + /// Maximum X value + /// Maximum Y value + /// Hashtable of hashtables containing map data elements + private Hashtable MapBlockQuery(int minX, int minY, int maxX, int maxY) + { + Hashtable param = new Hashtable(); + param["xmin"] = minX; + param["ymin"] = minY; + param["xmax"] = maxX; + param["ymax"] = maxY; + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("map_block", parameters); + XmlRpcResponse resp = req.Send(serversInfo.GridURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + return respData; + } + + /// + /// A ping / version check + /// + /// + /// + public XmlRpcResponse PingCheckReply(XmlRpcRequest request) + { + XmlRpcResponse response = new XmlRpcResponse(); + + Hashtable respData = new Hashtable(); + respData["online"] = "true"; + + foreach (ulong region in this.listeners.Keys) + { + Hashtable regData = new Hashtable(); + RegionInfo reg = regions[region]; + regData["status"] = "active"; + regData["handle"] = region.ToString(); + + respData[reg.SimUUID.ToStringHyphenated()] = regData; + } + + response.Value = respData; + + return response; + } + + + // Grid Request Processing + /// + /// + /// + /// + /// + public XmlRpcResponse ExpectUser(XmlRpcRequest request) + { + Console.WriteLine("Expecting User..."); + Hashtable requestData = (Hashtable)request.Params[0]; + AgentCircuitData agentData = new AgentCircuitData(); + agentData.SessionID = new LLUUID((string)requestData["session_id"]); + agentData.SecureSessionID = new LLUUID((string)requestData["secure_session_id"]); + agentData.firstname = (string)requestData["firstname"]; + agentData.lastname = (string)requestData["lastname"]; + agentData.AgentID = new LLUUID((string)requestData["agent_id"]); + agentData.circuitcode = Convert.ToUInt32(requestData["circuit_code"]); + agentData.CapsPath = (string)requestData["caps_path"]; + + if (requestData.ContainsKey("child_agent") && requestData["child_agent"].Equals("1")) + { + agentData.child = true; + } + else + { + agentData.startpos = new LLVector3(Convert.ToUInt32(requestData["startpos_x"]), Convert.ToUInt32(requestData["startpos_y"]), Convert.ToUInt32(requestData["startpos_z"])); + agentData.child = false; + + } + + if (listeners.ContainsKey(Convert.ToUInt64((string)requestData["regionhandle"]))) + { + this.listeners[Convert.ToUInt64((string)requestData["regionhandle"])].TriggerExpectUser(Convert.ToUInt64((string)requestData["regionhandle"]), agentData); + } + else + { + MainLog.Instance.Error("ExpectUser() - Unknown region " + (Convert.ToUInt64(requestData["regionhandle"])).ToString()); + } + + MainLog.Instance.Verbose("ExpectUser() - Welcoming new user..."); + + return new XmlRpcResponse(); + } + + #region InterRegion Comms + /// + /// + /// + private void StartRemoting() + { + TcpChannel ch = new TcpChannel(this.serversInfo.RemotingListenerPort); + ChannelServices.RegisterChannel(ch, true); + + WellKnownServiceTypeEntry wellType = new WellKnownServiceTypeEntry(typeof(OGS1InterRegionRemoting), "InterRegions", WellKnownObjectMode.Singleton); + RemotingConfiguration.RegisterWellKnownServiceType(wellType); + InterRegionSingleton.Instance.OnArrival += this.IncomingArrival; + InterRegionSingleton.Instance.OnChildAgent += this.IncomingChildAgent; + } + + #region Methods called by regions in this instance + /// + /// + /// + /// + /// + /// + public bool InformRegionOfChildAgent(ulong regionHandle, AgentCircuitData agentData) + { + try + { + if (this.listeners.ContainsKey(regionHandle)) + { + this.listeners[regionHandle].TriggerExpectUser(regionHandle, agentData); + return true; + } + RegionInfo regInfo = this.RequestNeighbourInfo(regionHandle); + if (regInfo != null) + { + //don't want to be creating a new link to the remote instance every time like we are here + bool retValue = false; + + + OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject( + typeof(OGS1InterRegionRemoting), + "tcp://" + regInfo.RemotingAddress + ":" + regInfo.RemotingPort + "/InterRegions"); + if (remObject != null) + { + retValue = remObject.InformRegionOfChildAgent(regionHandle, agentData); + } + else + { + Console.WriteLine("remoting object not found"); + } + remObject = null; + + + return retValue; + } + + return false; + } + catch (System.Runtime.Remoting.RemotingException e) + { + MainLog.Instance.Error("Remoting Error: Unable to connect to remote region.\n" + e.ToString()); + return false; + } + catch + { + return false; + } + } + + /// + /// + /// + /// + /// + /// + /// + public bool ExpectAvatarCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying) + { + try + { + if (this.listeners.ContainsKey(regionHandle)) + { + this.listeners[regionHandle].TriggerExpectAvatarCrossing(regionHandle, agentID, position, isFlying); + return true; + } + RegionInfo regInfo = this.RequestNeighbourInfo(regionHandle); + if (regInfo != null) + { + bool retValue = false; + OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject( + typeof(OGS1InterRegionRemoting), + "tcp://" + regInfo.RemotingAddress + ":" + regInfo.RemotingPort + "/InterRegions"); + if (remObject != null) + { + retValue = remObject.ExpectAvatarCrossing(regionHandle, agentID, position, isFlying); + } + else + { + Console.WriteLine("remoting object not found"); + } + remObject = null; + + return retValue; + } + //TODO need to see if we know about where this region is and use .net remoting + // to inform it. + return false; + } + catch (System.Runtime.Remoting.RemotingException e) + { + MainLog.Instance.Error("Remoting Error: Unable to connect to remote region.\n" + e.ToString()); + return false; + } + catch + { + return false; + } + } + + public bool AcknowledgeAgentCrossed(ulong regionHandle, LLUUID agentID) + { + if (this.listeners.ContainsKey(regionHandle)) + { + return true; + } + return false; + } + #endregion + + #region Methods triggered by calls from external instances + /// + /// + /// + /// + /// + /// + public bool IncomingChildAgent(ulong regionHandle, AgentCircuitData agentData) + { + try + { + if (this.listeners.ContainsKey(regionHandle)) + { + this.listeners[regionHandle].TriggerExpectUser(regionHandle, agentData); + return true; + } + } + catch (System.Runtime.Remoting.RemotingException e) + { + MainLog.Instance.Error("Remoting Error: Unable to connect to remote region.\n" + e.ToString()); + } + return false; + } + + /// + /// + /// + /// + /// + /// + /// + public bool IncomingArrival(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying) + { + try + { + if (this.listeners.ContainsKey(regionHandle)) + { + this.listeners[regionHandle].TriggerExpectAvatarCrossing(regionHandle, agentID, position, isFlying); + return true; + } + } + catch (System.Runtime.Remoting.RemotingException e) + { + MainLog.Instance.Error("Remoting Error: Unable to connect to remote region.\n" + e.ToString()); + } + return false; + } + #endregion + #endregion + } +} diff --git a/OpenSim/Region/Communications/OGS1/OGS1InterSimComms.cs b/OpenSim/Region/Communications/OGS1/OGS1InterSimComms.cs new file mode 100644 index 0000000000..f9a13fa119 --- /dev/null +++ b/OpenSim/Region/Communications/OGS1/OGS1InterSimComms.cs @@ -0,0 +1,85 @@ +using System; +using libsecondlife; +using OpenSim.Framework.Types; + +namespace OpenSim.Region.Communications.OGS1 +{ + public delegate bool InformRegionChild(ulong regionHandle, AgentCircuitData agentData); + public delegate bool ExpectArrival(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying); + + public sealed class InterRegionSingleton + { + static readonly InterRegionSingleton instance = new InterRegionSingleton(); + + public event InformRegionChild OnChildAgent; + public event ExpectArrival OnArrival; + + static InterRegionSingleton() + { + } + + InterRegionSingleton() + { + } + + public static InterRegionSingleton Instance + { + get + { + return instance; + } + } + + public bool InformRegionOfChildAgent(ulong regionHandle, AgentCircuitData agentData) + { + if (OnChildAgent != null) + { + return OnChildAgent(regionHandle, agentData); + } + return false; + } + + public bool ExpectAvatarCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying) + { + if (OnArrival != null) + { + return OnArrival(regionHandle, agentID, position, isFlying); + } + return false; + } + } + + public class OGS1InterRegionRemoting : MarshalByRefObject + { + + public OGS1InterRegionRemoting() + { + } + + public bool InformRegionOfChildAgent(ulong regionHandle, AgentCircuitData agentData) + { + try + { + return InterRegionSingleton.Instance.InformRegionOfChildAgent(regionHandle, agentData); + } + catch (System.Runtime.Remoting.RemotingException e) + { + Console.WriteLine("Remoting Error: Unable to connect to remote region.\n" + e.ToString()); + return false; + } + } + + public bool ExpectAvatarCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying) + { + try + { + return InterRegionSingleton.Instance.ExpectAvatarCrossing(regionHandle, agentID, position, isFlying); + } + catch (System.Runtime.Remoting.RemotingException e) + { + Console.WriteLine("Remoting Error: Unable to connect to remote region.\n" + e.ToString()); + return false; + } + } + } +} diff --git a/OpenSim/Region/Communications/OGS1/OGS1InventoryService.cs b/OpenSim/Region/Communications/OGS1/OGS1InventoryService.cs new file mode 100644 index 0000000000..70ab75ea6c --- /dev/null +++ b/OpenSim/Region/Communications/OGS1/OGS1InventoryService.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using libsecondlife; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Data; +using InventoryFolder = OpenSim.Framework.Communications.Caches.InventoryFolder; + +namespace OpenSim.Region.Communications.OGS1 +{ + public class OGS1InventoryService : IInventoryServices + { + + public OGS1InventoryService() + { + + } + + public void RequestInventoryForUser(LLUUID userID, InventoryFolderInfo folderCallBack, InventoryItemInfo itemCallBack) + { + + } + + public void AddNewInventoryFolder(LLUUID userID, InventoryFolder folder) + { + + } + + public void AddNewInventoryItem(LLUUID userID, InventoryItemBase item) + { + + } + + public void DeleteInventoryItem(LLUUID userID, InventoryItemBase item) + { + + } + } +} diff --git a/OpenSim/Region/Communications/OGS1/OGS1UserServices.cs b/OpenSim/Region/Communications/OGS1/OGS1UserServices.cs new file mode 100644 index 0000000000..f25706ebd2 --- /dev/null +++ b/OpenSim/Region/Communications/OGS1/OGS1UserServices.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections; +using libsecondlife; +using Nwc.XmlRpc; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Data; + +namespace OpenSim.Region.Communications.OGS1 +{ + public class OGS1UserServices :IUserServices + { + CommunicationsOGS1 m_parent; + public OGS1UserServices(CommunicationsOGS1 parent) + { + m_parent = parent; + } + + public UserProfileData ConvertXMLRPCDataToUserProfile(Hashtable data) + { + if (data.Contains("error_type")) + { + Console.WriteLine("Error sent by user server when trying to get user profile: (" + data["error_type"] + "): " + data["error_desc"]); + return null; + } + + UserProfileData userData = new UserProfileData(); + userData.username = (string)data["firstname"]; + userData.surname = (string)data["lastname"]; + userData.UUID = new LLUUID((string)data["uuid"]); + userData.userInventoryURI = (string)data["server_inventory"]; + userData.userAssetURI = (string)data["server_asset"]; + userData.profileFirstText = (string)data["profile_firstlife_about"]; + userData.profileFirstImage = new LLUUID((string)data["profile_firstlife_image"]); + userData.profileCanDoMask = Convert.ToUInt32((string)data["profile_can_do"]); + userData.profileWantDoMask = Convert.ToUInt32(data["profile_want_do"]); + userData.profileImage = new LLUUID((string)data["profile_image"]); + userData.lastLogin = Convert.ToInt32((string)data["profile_lastlogin"]); + userData.homeRegion = Convert.ToUInt64((string)data["home_region"]); + userData.homeLocation = new LLVector3((float)Convert.ToDecimal((string)data["home_coordinates_x"]), (float)Convert.ToDecimal((string)data["home_coordinates_y"]), (float)Convert.ToDecimal((string)data["home_coordinates_z"])); + userData.homeLookAt = new LLVector3((float)Convert.ToDecimal((string)data["home_look_x"]), (float)Convert.ToDecimal((string)data["home_look_y"]), (float)Convert.ToDecimal((string)data["home_look_z"])); + + return userData; + } + public UserProfileData GetUserProfile(string firstName, string lastName) + { + return GetUserProfile(firstName + " " + lastName); + } + public UserProfileData GetUserProfile(string name) + { + try + { + Hashtable param = new Hashtable(); + param["avatar_name"] = name; + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("get_user_by_name", parameters); + XmlRpcResponse resp = req.Send(m_parent.ServersInfo.UserURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + return ConvertXMLRPCDataToUserProfile(respData); + } + catch (System.Net.WebException e) + { + OpenSim.Framework.Console.MainLog.Instance.Warn("Error when trying to fetch profile data by name from remote user server: " + e.Message); + } + return null; + } + public UserProfileData GetUserProfile(LLUUID avatarID) + { + try + { + Hashtable param = new Hashtable(); + param["avatar_uuid"] = avatarID.ToString(); + IList parameters = new ArrayList(); + parameters.Add(param); + XmlRpcRequest req = new XmlRpcRequest("get_user_by_uuid", parameters); + XmlRpcResponse resp = req.Send(m_parent.ServersInfo.UserURL, 3000); + Hashtable respData = (Hashtable)resp.Value; + + return ConvertXMLRPCDataToUserProfile(respData); + } + catch (Exception e) + { + Console.WriteLine("Error when trying to fetch profile data by uuid from remote user server: " + e.Message); + } + return null; + } + + public void clearUserAgent(LLUUID avatarID) + { + // TODO: implement + } + + 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); + return profile; + } + } +} diff --git a/OpenSim/Region/Communications/OGS1/Properties/AssemblyInfo.cs b/OpenSim/Region/Communications/OGS1/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..41f811a1aa --- /dev/null +++ b/OpenSim/Region/Communications/OGS1/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenGrid.Framework.Communications.OGS1")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OpenGrid.Framework.Communications.OGS1")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("a8b2b39b-c83b-41e2-b0b5-7ccfc1fddae7")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/Environment/EstateManager.cs b/OpenSim/Region/Environment/EstateManager.cs new file mode 100644 index 0000000000..dbb9138875 --- /dev/null +++ b/OpenSim/Region/Environment/EstateManager.cs @@ -0,0 +1,384 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Console; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Region.Environment.Scenes; +using Avatar = OpenSim.Region.Environment.Scenes.ScenePresence; + + +namespace OpenSim.Region.Environment +{ + + /// + /// Processes requests regarding estates. Refer to EstateSettings.cs in OpenSim.Framework. Types for all of the core settings + /// + public class EstateManager + { + private Scene m_scene; + private RegionInfo m_regInfo; + + public EstateManager(Scene scene,RegionInfo reginfo) + { + m_scene = scene; + m_regInfo = reginfo; + } + + private bool convertParamStringToBool(byte[] field) + { + string s = Helpers.FieldToUTF8String(field); + if (s == "1" || s.ToLower() == "y" || s.ToLower() == "yes" || s.ToLower() == "t" || s.ToLower() == "true") + { + return true; + } + return false; + } + + /// + /// Sets terrain texture heights for each of the four corners of the region - textures are distributed as a linear range between the two heights. + /// + /// Which corner + /// Minimum height that texture range should cover + /// Maximum height that texture range should cover + public void setEstateTextureRange(Int16 corner, float lowValue, float highValue) + { + switch (corner) + { + case 0: + m_regInfo.estateSettings.terrainStartHeight0 = lowValue; + m_regInfo.estateSettings.terrainHeightRange0 = highValue; + break; + case 1: + m_regInfo.estateSettings.terrainStartHeight1 = lowValue; + m_regInfo.estateSettings.terrainHeightRange1 = highValue; + break; + case 2: + m_regInfo.estateSettings.terrainStartHeight2 = lowValue; + m_regInfo.estateSettings.terrainHeightRange2 = highValue; + break; + case 3: + m_regInfo.estateSettings.terrainStartHeight3 = lowValue; + m_regInfo.estateSettings.terrainHeightRange3 = highValue; + break; + } + } + + /// + /// Sets the 'detail' terrain texture on each of the bands. + /// + /// Which texture band + /// The UUID of the texture + public void setTerrainTexture(Int16 band, LLUUID textureUUID) + { + switch (band) + { + case 0: + m_regInfo.estateSettings.terrainDetail0 = textureUUID; + break; + case 1: + m_regInfo.estateSettings.terrainDetail1 = textureUUID; + break; + case 2: + m_regInfo.estateSettings.terrainDetail2 = textureUUID; + break; + case 3: + m_regInfo.estateSettings.terrainDetail3 = textureUUID; + break; + } + } + + /// + /// Sets common region settings + /// + /// Water height of the waterplane (may not nessecarily be one value) + /// Maximum amount terrain can be raised from previous baking + /// Minimum amount terrain can be lowered from previous baking + /// Use a fixed time of day on the sun? + /// The offset hour of the day + public void setRegionSettings(float WaterHeight, float TerrainRaiseLimit, float TerrainLowerLimit, bool UseFixedSun, float SunHour) + { + // Water Height + m_regInfo.estateSettings.waterHeight = WaterHeight; + m_scene.Terrain.watermap.Fill(WaterHeight); + + // Terraforming limits + m_regInfo.estateSettings.terrainRaiseLimit = TerrainRaiseLimit; + m_regInfo.estateSettings.terrainLowerLimit = TerrainLowerLimit; + m_scene.Terrain.maxRaise = TerrainRaiseLimit; + m_scene.Terrain.minLower = TerrainLowerLimit; + + // Time of day / fixed sun + m_regInfo.estateSettings.useFixedSun = UseFixedSun; + m_regInfo.estateSettings.sunHour = SunHour; + } + + #region Packet Handlers + + + public void handleEstateOwnerMessage(EstateOwnerMessagePacket packet, IClientAPI remote_client) + { + switch (Helpers.FieldToUTF8String(packet.MethodData.Method)) + { + case "getinfo": + this.sendRegionInfoPacketToAll(); + break; + case "setregioninfo": + if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) + estateSetRegionInfoHandler(packet); + break; + case "texturebase": + if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) + estateTextureBaseHandler(packet); + break; + case "texturedetail": + if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) + estateTextureDetailHandler(packet); + break; + case "textureheights": + if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) + estateTextureHeightsHandler(packet); + break; + case "texturecommit": + sendRegionHandshakeToAll(); + break; + case "setregionterrain": + if (m_scene.PermissionsMngr.CanEditEstateTerrain(remote_client.AgentId)) + estateSetRegionTerrainHandler(packet); + break; + default: + MainLog.Instance.Error("EstateOwnerMessage: Unknown method requested\n" + packet.ToString()); + break; + } + } + + private void estateSetRegionInfoHandler(EstateOwnerMessagePacket packet) + { + if (packet.ParamList.Length != 9) + { + MainLog.Instance.Error("EstateOwnerMessage: SetRegionInfo method has a ParamList of invalid length"); + } + else + { + m_regInfo.estateSettings.regionFlags = Simulator.RegionFlags.None; + + if (convertParamStringToBool(packet.ParamList[0].Parameter)) + { + m_regInfo.estateSettings.regionFlags = m_regInfo.estateSettings.regionFlags | Simulator.RegionFlags.BlockTerraform; + } + + if (convertParamStringToBool(packet.ParamList[1].Parameter)) + { + m_regInfo.estateSettings.regionFlags = m_regInfo.estateSettings.regionFlags | Simulator.RegionFlags.NoFly; + } + + if (convertParamStringToBool(packet.ParamList[2].Parameter)) + { + m_regInfo.estateSettings.regionFlags = m_regInfo.estateSettings.regionFlags | Simulator.RegionFlags.AllowDamage; + } + + if (convertParamStringToBool(packet.ParamList[3].Parameter) == false) + { + m_regInfo.estateSettings.regionFlags = m_regInfo.estateSettings.regionFlags | Simulator.RegionFlags.BlockLandResell; + } + + + int tempMaxAgents = Convert.ToInt16(Convert.ToDecimal(Helpers.FieldToUTF8String(packet.ParamList[4].Parameter))); + m_regInfo.estateSettings.maxAgents = (byte)tempMaxAgents; + + float tempObjectBonusFactor = (float)Convert.ToDecimal(Helpers.FieldToUTF8String(packet.ParamList[5].Parameter)); + m_regInfo.estateSettings.objectBonusFactor = tempObjectBonusFactor; + + int tempMatureLevel = Convert.ToInt16(Helpers.FieldToUTF8String(packet.ParamList[6].Parameter)); + m_regInfo.estateSettings.simAccess = (Simulator.SimAccess)tempMatureLevel; + + + if (convertParamStringToBool(packet.ParamList[7].Parameter)) + { + m_regInfo.estateSettings.regionFlags = m_regInfo.estateSettings.regionFlags | Simulator.RegionFlags.RestrictPushObject; + } + + if (convertParamStringToBool(packet.ParamList[8].Parameter)) + { + m_regInfo.estateSettings.regionFlags = m_regInfo.estateSettings.regionFlags | Simulator.RegionFlags.AllowParcelChanges; + } + + sendRegionInfoPacketToAll(); + + } + } + + private void estateSetRegionTerrainHandler(EstateOwnerMessagePacket packet) + { + if (packet.ParamList.Length != 9) + { + MainLog.Instance.Error("EstateOwnerMessage: SetRegionTerrain method has a ParamList of invalid length"); + } + else + { + float WaterHeight = (float)Convert.ToDecimal(Helpers.FieldToUTF8String(packet.ParamList[0].Parameter)); + float TerrainRaiseLimit = (float)Convert.ToDecimal(Helpers.FieldToUTF8String(packet.ParamList[1].Parameter)); + float TerrainLowerLimit = (float)Convert.ToDecimal(Helpers.FieldToUTF8String(packet.ParamList[2].Parameter)); + bool UseFixedSun = this.convertParamStringToBool(packet.ParamList[4].Parameter); + float SunHour = (float)Convert.ToDecimal(Helpers.FieldToUTF8String(packet.ParamList[5].Parameter)); + + setRegionSettings(WaterHeight, TerrainRaiseLimit, TerrainLowerLimit, UseFixedSun, SunHour); + + sendRegionInfoPacketToAll(); + } + } + + private void estateTextureHeightsHandler(EstateOwnerMessagePacket packet) + { + foreach (EstateOwnerMessagePacket.ParamListBlock block in packet.ParamList) + { + string s = Helpers.FieldToUTF8String(block.Parameter); + string[] splitField = s.Split(' '); + if (splitField.Length == 3) + { + + Int16 corner = Convert.ToInt16(splitField[0]); + float lowValue = (float)Convert.ToDecimal(splitField[1]); + float highValue = (float)Convert.ToDecimal(splitField[2]); + + setEstateTextureRange(corner, lowValue, highValue); + } + } + } + + private void estateTextureDetailHandler(EstateOwnerMessagePacket packet) + { + foreach (EstateOwnerMessagePacket.ParamListBlock block in packet.ParamList) + { + + string s = Helpers.FieldToUTF8String(block.Parameter); + string[] splitField = s.Split(' '); + if (splitField.Length == 2) + { + Int16 corner = Convert.ToInt16(splitField[0]); + LLUUID textureUUID = new LLUUID(splitField[1]); + + setTerrainTexture(corner, textureUUID); + } + } + } + + private void estateTextureBaseHandler(EstateOwnerMessagePacket packet) + { + foreach (EstateOwnerMessagePacket.ParamListBlock block in packet.ParamList) + { + string s = Helpers.FieldToUTF8String(block.Parameter); + string[] splitField = s.Split(' '); + if (splitField.Length == 2) + { + LLUUID tempUUID = new LLUUID(splitField[1]); + switch (Convert.ToInt16(splitField[0])) + { + case 0: + m_regInfo.estateSettings.terrainBase0 = tempUUID; + break; + case 1: + m_regInfo.estateSettings.terrainBase1 = tempUUID; + break; + case 2: + m_regInfo.estateSettings.terrainBase2 = tempUUID; + break; + case 3: + m_regInfo.estateSettings.terrainBase3 = tempUUID; + break; + } + } + } + } + + #endregion + + #region Outgoing Packets + + public void sendRegionInfoPacketToAll() + { + List avatars = m_scene.RequestAvatarList(); + + for (int i = 0; i < avatars.Count; i++) + { + this.sendRegionInfoPacket(avatars[i].ControllingClient); + } + } + + public void sendRegionHandshakeToAll() + { + List avatars = m_scene.RequestAvatarList(); + + for (int i = 0; i < avatars.Count; i++) + { + this.sendRegionHandshake(avatars[i].ControllingClient); + } + } + + public void sendRegionInfoPacket(IClientAPI remote_client) + { + Encoding _enc = Encoding.ASCII; + + AgentCircuitData circuitData = remote_client.RequestClientInfo(); + + RegionInfoPacket regionInfoPacket = new RegionInfoPacket(); + regionInfoPacket.AgentData.AgentID = circuitData.AgentID; + regionInfoPacket.AgentData.SessionID = circuitData.SessionID; + regionInfoPacket.RegionInfo.BillableFactor = m_regInfo.estateSettings.billableFactor; + regionInfoPacket.RegionInfo.EstateID = m_regInfo.estateSettings.estateID; + regionInfoPacket.RegionInfo.MaxAgents = m_regInfo.estateSettings.maxAgents; + regionInfoPacket.RegionInfo.ObjectBonusFactor = m_regInfo.estateSettings.objectBonusFactor; + regionInfoPacket.RegionInfo.ParentEstateID = m_regInfo.estateSettings.parentEstateID; + regionInfoPacket.RegionInfo.PricePerMeter = m_regInfo.estateSettings.pricePerMeter; + regionInfoPacket.RegionInfo.RedirectGridX = m_regInfo.estateSettings.redirectGridX; + regionInfoPacket.RegionInfo.RedirectGridY = m_regInfo.estateSettings.redirectGridY; + regionInfoPacket.RegionInfo.RegionFlags = (uint)m_regInfo.estateSettings.regionFlags; + regionInfoPacket.RegionInfo.SimAccess = (byte)m_regInfo.estateSettings.simAccess; + regionInfoPacket.RegionInfo.SimName = _enc.GetBytes( m_regInfo.RegionName); + regionInfoPacket.RegionInfo.SunHour = m_regInfo.estateSettings.sunHour; + regionInfoPacket.RegionInfo.TerrainLowerLimit = m_regInfo.estateSettings.terrainLowerLimit; + regionInfoPacket.RegionInfo.TerrainRaiseLimit = m_regInfo.estateSettings.terrainRaiseLimit; + regionInfoPacket.RegionInfo.UseEstateSun = !m_regInfo.estateSettings.useFixedSun; + regionInfoPacket.RegionInfo.WaterHeight = m_regInfo.estateSettings.waterHeight; + + remote_client.OutPacket(regionInfoPacket); + } + + public void sendRegionHandshake(IClientAPI remoteClient) + { + remoteClient.SendRegionHandshake(m_regInfo); + } + + #endregion + + } +} diff --git a/OpenSim/Region/Environment/Interfaces/IRegionDataStore.cs b/OpenSim/Region/Environment/Interfaces/IRegionDataStore.cs new file mode 100644 index 0000000000..f3c583a945 --- /dev/null +++ b/OpenSim/Region/Environment/Interfaces/IRegionDataStore.cs @@ -0,0 +1,64 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; + +using OpenSim.Framework.Types; +using OpenSim.Region; +using OpenSim.Region.Environment; +using OpenSim.Region.Environment.Scenes; +using OpenSim.Region.Environment.LandManagement; + +using System.Collections.Generic; + +namespace OpenSim.Region.Interfaces +{ + public interface IRegionDataStore + { + /// + /// Initialises the data storage engine + /// + /// The file to save the database to (may not be applicable) + /// The name of the database to store to (may not be applicable) + void Initialise(string filename, string dbname); + + void StoreObject(SceneObjectGroup obj); + void RemoveObject(LLUUID uuid); + + List LoadObjects(); + + void StoreTerrain(double[,] terrain); + double[,] LoadTerrain(); + + void StoreParcel(Land Parcel); + void RemoveLandObject(uint ID); + List LoadLandObjects(); + + void Shutdown(); + } +} \ No newline at end of file diff --git a/OpenSim/Region/Environment/LandManagement/Land.cs b/OpenSim/Region/Environment/LandManagement/Land.cs new file mode 100644 index 0000000000..a918e337b7 --- /dev/null +++ b/OpenSim/Region/Environment/LandManagement/Land.cs @@ -0,0 +1,602 @@ +using System; +using System.Collections.Generic; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Region.Environment.Scenes; + +namespace OpenSim.Region.Environment.LandManagement +{ + #region Parcel Class + /// + /// Keeps track of a specific piece of land's information + /// + public class Land + { + #region Member Variables + public LandData landData = new LandData(); + public List primsOverMe = new List(); + + public Scene m_scene; + + private bool[,] landBitmap = new bool[64, 64]; + + #endregion + + + #region Constructors + public Land(LLUUID owner_id, bool is_group_owned, Scene scene) + { + m_scene = scene; + landData.ownerID = owner_id; + landData.isGroupOwned = is_group_owned; + + } + #endregion + + + #region Member Functions + + #region General Functions + /// + /// Checks to see if this land object contains a point + /// + /// + /// + /// Returns true if the piece of land contains the specified point + public bool containsPoint(int x, int y) + { + if (x >= 0 && y >= 0 && x <= 256 && x <= 256) + { + return (landBitmap[x / 4, y / 4] == true); + } + else + { + return false; + } + } + + public Land Copy() + { + Land newLand = new Land(this.landData.ownerID, this.landData.isGroupOwned, m_scene); + + //Place all new variables here! + newLand.landBitmap = (bool[,])(this.landBitmap.Clone()); + newLand.landData = landData.Copy(); + + return newLand; + } + + #endregion + + + #region Packet Request Handling + /// + /// Sends land properties as requested + /// + /// ID sent by client for them to keep track of + /// Bool sent by client for them to use + /// Object representing the client + public void sendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client) + { + + ParcelPropertiesPacket updatePacket = new ParcelPropertiesPacket(); + updatePacket.ParcelData.AABBMax = landData.AABBMax; + updatePacket.ParcelData.AABBMin = landData.AABBMin; + updatePacket.ParcelData.Area = landData.area; + updatePacket.ParcelData.AuctionID = landData.auctionID; + updatePacket.ParcelData.AuthBuyerID = landData.authBuyerID; //unemplemented + + updatePacket.ParcelData.Bitmap = landData.landBitmapByteArray; + + updatePacket.ParcelData.Desc = Helpers.StringToField(landData.landDesc); + updatePacket.ParcelData.Category = (byte)landData.category; + updatePacket.ParcelData.ClaimDate = landData.claimDate; + updatePacket.ParcelData.ClaimPrice = landData.claimPrice; + updatePacket.ParcelData.GroupID = landData.groupID; + updatePacket.ParcelData.GroupPrims = landData.groupPrims; + updatePacket.ParcelData.IsGroupOwned = landData.isGroupOwned; + updatePacket.ParcelData.LandingType = (byte)landData.landingType; + updatePacket.ParcelData.LocalID = landData.localID; + if (landData.area > 0) + { + updatePacket.ParcelData.MaxPrims = Convert.ToInt32(Math.Round((Convert.ToDecimal(landData.area) / Convert.ToDecimal(65536)) * 15000 * Convert.ToDecimal(m_scene.RegionInfo.estateSettings.objectBonusFactor))); + } + else + { + updatePacket.ParcelData.MaxPrims = 0; + } + updatePacket.ParcelData.MediaAutoScale = landData.mediaAutoScale; + updatePacket.ParcelData.MediaID = landData.mediaID; + updatePacket.ParcelData.MediaURL = Helpers.StringToField(landData.mediaURL); + updatePacket.ParcelData.MusicURL = Helpers.StringToField(landData.musicURL); + updatePacket.ParcelData.Name = Helpers.StringToField(landData.landName); + updatePacket.ParcelData.OtherCleanTime = 0; //unemplemented + updatePacket.ParcelData.OtherCount = 0; //unemplemented + updatePacket.ParcelData.OtherPrims = landData.otherPrims; + updatePacket.ParcelData.OwnerID = landData.ownerID; + updatePacket.ParcelData.OwnerPrims = landData.ownerPrims; + updatePacket.ParcelData.ParcelFlags = landData.landFlags; + updatePacket.ParcelData.ParcelPrimBonus = m_scene.RegionInfo.estateSettings.objectBonusFactor; + updatePacket.ParcelData.PassHours = landData.passHours; + updatePacket.ParcelData.PassPrice = landData.passPrice; + updatePacket.ParcelData.PublicCount = 0; //unemplemented + + uint regionFlags = (uint)m_scene.RegionInfo.estateSettings.regionFlags; + updatePacket.ParcelData.RegionDenyAnonymous = ((regionFlags & (uint)Simulator.RegionFlags.DenyAnonymous) > 0); + updatePacket.ParcelData.RegionDenyIdentified = ((regionFlags & (uint)Simulator.RegionFlags.DenyIdentified) > 0); + updatePacket.ParcelData.RegionDenyTransacted = ((regionFlags & (uint)Simulator.RegionFlags.DenyTransacted) > 0); + updatePacket.ParcelData.RegionPushOverride = ((regionFlags & (uint)Simulator.RegionFlags.RestrictPushObject) > 0); + + updatePacket.ParcelData.RentPrice = 0; + updatePacket.ParcelData.RequestResult = request_result; + updatePacket.ParcelData.SalePrice = landData.salePrice; + updatePacket.ParcelData.SelectedPrims = landData.selectedPrims; + updatePacket.ParcelData.SelfCount = 0;//unemplemented + updatePacket.ParcelData.SequenceID = sequence_id; + if (landData.simwideArea > 0) + { + updatePacket.ParcelData.SimWideMaxPrims = Convert.ToInt32(Math.Round((Convert.ToDecimal(landData.simwideArea) / Convert.ToDecimal(65536)) * 15000 * Convert.ToDecimal(m_scene.RegionInfo.estateSettings.objectBonusFactor))); + } + else + { + updatePacket.ParcelData.SimWideMaxPrims = 0; + } + updatePacket.ParcelData.SimWideTotalPrims = landData.simwidePrims; + updatePacket.ParcelData.SnapSelection = snap_selection; + updatePacket.ParcelData.SnapshotID = landData.snapshotID; + updatePacket.ParcelData.Status = (byte)landData.landStatus; + updatePacket.ParcelData.TotalPrims = landData.ownerPrims + landData.groupPrims + landData.otherPrims + landData.selectedPrims; + updatePacket.ParcelData.UserLocation = landData.userLocation; + updatePacket.ParcelData.UserLookAt = landData.userLookAt; + remote_client.OutPacket((Packet)updatePacket); + } + + public void updateLandProperties(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client) + { + if (remote_client.AgentId == landData.ownerID) + { + //Needs later group support + landData.authBuyerID = packet.ParcelData.AuthBuyerID; + landData.category = (libsecondlife.Parcel.ParcelCategory)packet.ParcelData.Category; + landData.landDesc = Helpers.FieldToUTF8String(packet.ParcelData.Desc); + landData.groupID = packet.ParcelData.GroupID; + landData.landingType = packet.ParcelData.LandingType; + landData.mediaAutoScale = packet.ParcelData.MediaAutoScale; + landData.mediaID = packet.ParcelData.MediaID; + landData.mediaURL = Helpers.FieldToUTF8String(packet.ParcelData.MediaURL); + landData.musicURL = Helpers.FieldToUTF8String(packet.ParcelData.MusicURL); + landData.landName = Helpers.FieldToUTF8String(packet.ParcelData.Name); + landData.landFlags = packet.ParcelData.ParcelFlags; + landData.passHours = packet.ParcelData.PassHours; + landData.passPrice = packet.ParcelData.PassPrice; + landData.salePrice = packet.ParcelData.SalePrice; + landData.snapshotID = packet.ParcelData.SnapshotID; + landData.userLocation = packet.ParcelData.UserLocation; + landData.userLookAt = packet.ParcelData.UserLookAt; + sendLandUpdateToAvatarsOverMe(); + + + } + } + + public void sendLandUpdateToAvatarsOverMe() + { + List avatars = m_scene.RequestAvatarList(); + for (int i = 0; i < avatars.Count; i++) + { + Land over = m_scene.LandManager.getLandObject((int)Math.Round(avatars[i].AbsolutePosition.X), (int)Math.Round(avatars[i].AbsolutePosition.Y)); + if (over.landData.localID == this.landData.localID) + { + sendLandProperties(0, false, 0, avatars[i].ControllingClient); + } + } + } + #endregion + + + #region Update Functions + /// + /// Updates the AABBMin and AABBMax values after area/shape modification of the land object + /// + private void updateAABBAndAreaValues() + { + int min_x = 64; + int min_y = 64; + int max_x = 0; + int max_y = 0; + int tempArea = 0; + int x, y; + for (x = 0; x < 64; x++) + { + for (y = 0; y < 64; y++) + { + if (landBitmap[x, y] == true) + { + if (min_x > x) min_x = x; + if (min_y > y) min_y = y; + if (max_x < x) max_x = x; + if (max_y < y) max_y = y; + tempArea += 16; //16sqm peice of land + } + } + } + landData.AABBMin = new LLVector3((float)(min_x * 4), (float)(min_y * 4), (float)m_scene.Terrain.GetHeight((min_x * 4), (min_y * 4))); + landData.AABBMax = new LLVector3((float)(max_x * 4), (float)(max_y * 4), (float)m_scene.Terrain.GetHeight((max_x * 4), (max_y * 4))); + landData.area = tempArea; + } + + public void updateLandBitmapByteArray() + { + landData.landBitmapByteArray = convertLandBitmapToBytes(); + } + + /// + /// Update all settings in land such as area, bitmap byte array, etc + /// + public void forceUpdateLandInfo() + { + this.updateAABBAndAreaValues(); + this.updateLandBitmapByteArray(); + } + + public void setLandBitmapFromByteArray() + { + landBitmap = convertBytesToLandBitmap(); + } + #endregion + + + #region Land Bitmap Functions + /// + /// Sets the land's bitmap manually + /// + /// 64x64 block representing where this land is on a map + public void setLandBitmap(bool[,] bitmap) + { + if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) + { + //Throw an exception - The bitmap is not 64x64 + throw new Exception("Error: Invalid Parcel Bitmap"); + } + else + { + //Valid: Lets set it + landBitmap = bitmap; + forceUpdateLandInfo(); + + } + } + /// + /// Gets the land's bitmap manually + /// + /// + public bool[,] getLandBitmap() + { + return landBitmap; + } + /// + /// Converts the land bitmap to a packet friendly byte array + /// + /// + private byte[] convertLandBitmapToBytes() + { + byte[] tempConvertArr = new byte[512]; + byte tempByte = 0; + int x, y, i, byteNum = 0; + i = 0; + for (y = 0; y < 64; y++) + { + for (x = 0; x < 64; x++) + { + tempByte = Convert.ToByte(tempByte | Convert.ToByte(landBitmap[x, y]) << (i++ % 8)); + if (i % 8 == 0) + { + tempConvertArr[byteNum] = tempByte; + tempByte = (byte)0; + i = 0; + byteNum++; + } + } + } + return tempConvertArr; + } + + private bool[,] convertBytesToLandBitmap() + { + bool[,] tempConvertMap = new bool[64, 64]; + tempConvertMap.Initialize(); + byte tempByte = 0; + int x = 0, y = 0, i = 0, bitNum = 0; + for (i = 0; i < 512; i++) + { + tempByte = landData.landBitmapByteArray[i]; + for (bitNum = 0; bitNum < 8; bitNum++) + { + bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte)1); + tempConvertMap[x, y] = bit; + x++; + if (x > 63) + { + x = 0; + y++; + } + + } + + } + return tempConvertMap; + } + /// + /// Full sim land object creation + /// + /// + public static bool[,] basicFullRegionLandBitmap() + { + return getSquareLandBitmap(0, 0, 256, 256); + } + + /// + /// Used to modify the bitmap between the x and y points. Points use 64 scale + /// + /// + /// + /// + /// + /// + public static bool[,] getSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) + { + + bool[,] tempBitmap = new bool[64, 64]; + tempBitmap.Initialize(); + + tempBitmap = modifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); + return tempBitmap; + } + + /// + /// Change a land bitmap at within a square and set those points to a specific value + /// + /// + /// + /// + /// + /// + /// + /// + public static bool[,] modifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, bool set_value) + { + if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2) + { + //Throw an exception - The bitmap is not 64x64 + throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()"); + } + + int x, y; + for (y = 0; y < 64; y++) + { + for (x = 0; x < 64; x++) + { + if (x >= start_x / 4 && x < end_x / 4 + && y >= start_y / 4 && y < end_y / 4) + { + land_bitmap[x, y] = set_value; + } + } + } + return land_bitmap; + } + /// + /// Join the true values of 2 bitmaps together + /// + /// + /// + /// + public static bool[,] mergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) + { + if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) + { + //Throw an exception - The bitmap is not 64x64 + throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps"); + } + if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2) + { + //Throw an exception - The bitmap is not 64x64 + throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps"); + + } + + int x, y; + for (y = 0; y < 64; y++) + { + for (x = 0; x < 64; x++) + { + if (bitmap_add[x, y]) + { + bitmap_base[x, y] = true; + } + } + } + return bitmap_base; + } + #endregion + + #region Object Select and Object Owner Listing + public void sendForceObjectSelect(int local_id, int request_type, IClientAPI remote_client) + { + List resultLocalIDs = new List(); + foreach (SceneObjectGroup obj in primsOverMe) + { + if (obj.LocalId > 0) + { + if (request_type == LandManager.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == this.landData.ownerID) + { + resultLocalIDs.Add(obj.LocalId); + } + else if (request_type == LandManager.LAND_SELECT_OBJECTS_GROUP && false) //TODO: change false to group support! + { + + } + else if (request_type == LandManager.LAND_SELECT_OBJECTS_OTHER && obj.OwnerID != remote_client.AgentId) + { + resultLocalIDs.Add(obj.LocalId); + } + } + } + + + bool firstCall = true; + int MAX_OBJECTS_PER_PACKET = 251; + ForceObjectSelectPacket pack = new ForceObjectSelectPacket(); + ForceObjectSelectPacket.DataBlock[] data; + while (resultLocalIDs.Count > 0) + { + if (firstCall) + { + pack._Header.ResetList = true; + firstCall = false; + } + else + { + pack._Header.ResetList = false; + } + + if (resultLocalIDs.Count > MAX_OBJECTS_PER_PACKET) + { + data = new ForceObjectSelectPacket.DataBlock[MAX_OBJECTS_PER_PACKET]; + } + else + { + data = new ForceObjectSelectPacket.DataBlock[resultLocalIDs.Count]; + } + + int i; + for (i = 0; i < MAX_OBJECTS_PER_PACKET && resultLocalIDs.Count > 0; i++) + { + data[i] = new ForceObjectSelectPacket.DataBlock(); + data[i].LocalID = Convert.ToUInt32(resultLocalIDs[0]); + resultLocalIDs.RemoveAt(0); + } + pack.Data = data; + remote_client.OutPacket((Packet)pack); + } + + } + public void sendLandObjectOwners(IClientAPI remote_client) + { + Dictionary ownersAndCount = new Dictionary(); + foreach (SceneObjectGroup obj in primsOverMe) + { + if (!ownersAndCount.ContainsKey(obj.OwnerID)) + { + ownersAndCount.Add(obj.OwnerID, 0); + } + ownersAndCount[obj.OwnerID] += obj.PrimCount; + } + if (ownersAndCount.Count > 0) + { + + ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock = new ParcelObjectOwnersReplyPacket.DataBlock[32]; + + if (ownersAndCount.Count < 32) + { + dataBlock = new ParcelObjectOwnersReplyPacket.DataBlock[ownersAndCount.Count]; + } + + + int num = 0; + foreach (LLUUID owner in ownersAndCount.Keys) + { + dataBlock[num] = new ParcelObjectOwnersReplyPacket.DataBlock(); + dataBlock[num].Count = ownersAndCount[owner]; + dataBlock[num].IsGroupOwned = false; //TODO: fix me when group support is added + dataBlock[num].OnlineStatus = true; //TODO: fix me later + dataBlock[num].OwnerID = owner; + + num++; + } + + ParcelObjectOwnersReplyPacket pack = new ParcelObjectOwnersReplyPacket(); + pack.Data = dataBlock; + remote_client.OutPacket(pack); + } + } + #endregion + + #region Object Returning + public void returnObject(SceneObjectGroup obj) + { + } + public void returnLandObjects(int type, LLUUID owner) + { + + } + #endregion + + #region Object Adding/Removing from Parcel + public void resetLandPrimCounts() + { + landData.groupPrims = 0; + landData.ownerPrims = 0; + landData.otherPrims = 0; + landData.selectedPrims = 0; + primsOverMe.Clear(); + } + + public void addPrimToCount(SceneObjectGroup obj) + { + LLUUID prim_owner = obj.OwnerID; + int prim_count = obj.PrimCount; + + if (obj.IsSelected) + { + landData.selectedPrims += prim_count; + } + else + { + if (prim_owner == landData.ownerID) + { + landData.ownerPrims += prim_count; + } + else + { + landData.otherPrims += prim_count; + } + } + + primsOverMe.Add(obj); + + } + + public void removePrimFromCount(SceneObjectGroup obj) + { + if (primsOverMe.Contains(obj)) + { + LLUUID prim_owner = obj.OwnerID; + int prim_count = obj.PrimCount; + + if (prim_owner == landData.ownerID) + { + landData.ownerPrims -= prim_count; + } + else if (prim_owner == landData.groupID) + { + landData.groupPrims -= prim_count; + } + else + { + landData.otherPrims -= prim_count; + } + + primsOverMe.Remove(obj); + } + } + #endregion + + #endregion + + + } + #endregion +} diff --git a/OpenSim/Region/Environment/LandManagement/LandManager.cs b/OpenSim/Region/Environment/LandManagement/LandManager.cs new file mode 100644 index 0000000000..bf9151b3c8 --- /dev/null +++ b/OpenSim/Region/Environment/LandManagement/LandManager.cs @@ -0,0 +1,617 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Region.Environment.Scenes; + +namespace OpenSim.Region.Environment.LandManagement +{ + + + #region LandManager Class + /// + /// Handles Land objects and operations requiring information from other Land objects (divide, join, etc) + /// + public class LandManager + { + + #region Constants + //Land types set with flags in ParcelOverlay. + //Only one of these can be used. + public const byte LAND_TYPE_PUBLIC = (byte)0; //Equals 00000000 + public const byte LAND_TYPE_OWNED_BY_OTHER = (byte)1; //Equals 00000001 + public const byte LAND_TYPE_OWNED_BY_GROUP = (byte)2; //Equals 00000010 + public const byte LAND_TYPE_OWNED_BY_REQUESTER = (byte)3; //Equals 00000011 + public const byte LAND_TYPE_IS_FOR_SALE = (byte)4; //Equals 00000100 + public const byte LAND_TYPE_IS_BEING_AUCTIONED = (byte)5; //Equals 00000101 + + + //Flags that when set, a border on the given side will be placed + //NOTE: North and East is assumable by the west and south sides (if land to east has a west border, then I have an east border; etc) + //This took forever to figure out -- jeesh. /blame LL for even having to send these + public const byte LAND_FLAG_PROPERTY_BORDER_WEST = (byte)64; //Equals 01000000 + public const byte LAND_FLAG_PROPERTY_BORDER_SOUTH = (byte)128; //Equals 10000000 + + //RequestResults (I think these are right, they seem to work): + public const int LAND_RESULT_SINGLE = 0; // The request they made contained only a single piece of land + public const int LAND_RESULT_MULTIPLE = 1; // The request they made contained more than a single peice of land + + //ParcelSelectObjects + public const int LAND_SELECT_OBJECTS_OWNER = 2; + public const int LAND_SELECT_OBJECTS_GROUP = 4; + public const int LAND_SELECT_OBJECTS_OTHER = 8; + + + //These are other constants. Yay! + public const int START_LAND_LOCAL_ID = 1; + #endregion + + #region Member Variables + public Dictionary landList = new Dictionary(); + private int lastLandLocalID = START_LAND_LOCAL_ID - 1; + private int[,] landIDList = new int[64, 64]; + + /// + /// Set to true when a prim is moved, created, added. Performs a prim count update + /// + public bool landPrimCountTainted = false; + + private Scene m_scene; + private RegionInfo m_regInfo; + + #endregion + + #region Constructors + public LandManager(Scene scene, RegionInfo reginfo) + { + + m_scene = scene; + m_regInfo = reginfo; + landIDList.Initialize(); + + } + #endregion + + #region Member Functions + + #region Parcel From Storage Functions + public void LandFromStorage(LandData data) + { + Land new_land = new Land(data.ownerID, data.isGroupOwned, m_scene); + new_land.landData = data.Copy(); + new_land.setLandBitmapFromByteArray(); + addLandObject(new_land); + + } + + public void NoLandDataFromStorage() + { + resetSimLandObjects(); + } + #endregion + + #region Parcel Add/Remove/Get/Create + /// + /// Creates a basic Parcel object without an owner (a zeroed key) + /// + /// + public Land createBaseLand() + { + return new Land(new LLUUID(), false, m_scene); + } + + /// + /// Adds a land object to the stored list and adds them to the landIDList to what they own + /// + /// The land object being added + public Land addLandObject(Land new_land) + { + lastLandLocalID++; + new_land.landData.localID = lastLandLocalID; + landList.Add(lastLandLocalID, new_land.Copy()); + + + bool[,] landBitmap = new_land.getLandBitmap(); + int x, y; + for (x = 0; x < 64; x++) + { + for (y = 0; y < 64; y++) + { + if (landBitmap[x, y]) + { + landIDList[x, y] = lastLandLocalID; + } + } + } + landList[lastLandLocalID].forceUpdateLandInfo(); + + return new_land; + + } + /// + /// Removes a land object from the list. Will not remove if local_id is still owning an area in landIDList + /// + /// Land.localID of the peice of land to remove. + public void removeLandObject(int local_id) + { + int x, y; + for (x = 0; x < 64; x++) + { + for (y = 0; y < 64; y++) + { + if (landIDList[x, y] == local_id) + { + throw new Exception("Could not remove land object. Still being used at " + x + ", " + y); + } + } + } + // TODO: Put event here for storage manager to bind to. + landList.Remove(local_id); + } + + private void performFinalLandJoin(Land master, Land slave) + { + int x, y; + bool[,] landBitmapSlave = slave.getLandBitmap(); + for (x = 0; x < 64; x++) + { + for (y = 0; y < 64; y++) + { + if (landBitmapSlave[x, y]) + { + landIDList[x, y] = master.landData.localID; + } + } + } + removeLandObject(slave.landData.localID); + } + /// + /// Get the land object at the specified point + /// + /// Value between 0 - 256 on the x axis of the point + /// Value between 0 - 256 on the y axis of the point + /// Land object at the point supplied + public Land getLandObject(float x_float, float y_float) + { + int x = Convert.ToInt32(Math.Floor(Convert.ToDouble(x_float) / Convert.ToDouble(4.0))); + int y = Convert.ToInt32(Math.Floor(Convert.ToDouble(y_float) / Convert.ToDouble(4.0))); + + if (x > 63 || y > 63 || x < 0 || y < 0) + { + throw new Exception("Error: Parcel not found at point " + x + ", " + y); + } + else + { + // Console.WriteLine("Point (" + x + ", " + y + ") determined from point (" + x_float + ", " + y_float + ")"); + return landList[landIDList[x, y]]; + } + } + + public Land getLandObject(int x, int y) + { + if (x > 256 || y > 256 || x < 0 || y < 0) + { + throw new Exception("Error: Parcel not found at point " + x + ", " + y); + } + else + { + return landList[landIDList[x / 4, y / 4]]; + } + } + #endregion + + #region Parcel Modification + /// + /// Subdivides a piece of land + /// + /// West Point + /// South Point + /// East Point + /// North Point + /// LLUUID of user who is trying to subdivide + /// Returns true if successful + private bool subdivide(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) + { + + //First, lets loop through the points and make sure they are all in the same peice of land + //Get the land object at start + Land startLandObject = getLandObject(start_x, start_y); + if (startLandObject == null) return false; //No such land object at the beginning + + //Loop through the points + try + { + int totalX = end_x - start_x; + int totalY = end_y - start_y; + int x, y; + for (y = 0; y < totalY; y++) + { + for (x = 0; x < totalX; x++) + { + Land tempLandObject = getLandObject(start_x + x, start_y + y); + if (tempLandObject == null) return false; //No such land object at that point + if (tempLandObject != startLandObject) return false; //Subdividing over 2 land objects; no-no + } + } + } + catch (Exception) + { + return false; //Exception. For now, lets skip subdivision + } + + //If we are still here, then they are subdividing within one piece of land + //Check owner + if (startLandObject.landData.ownerID != attempting_user_id) + { + return false; //They cant do this! + } + + //Lets create a new land object with bitmap activated at that point (keeping the old land objects info) + Land newLand = startLandObject.Copy(); + newLand.landData.landName = "Subdivision of " + newLand.landData.landName; + newLand.landData.globalID = LLUUID.Random(); + + newLand.setLandBitmap(Land.getSquareLandBitmap(start_x, start_y, end_x, end_y)); + + //Now, lets set the subdivision area of the original to false + int startLandObjectIndex = startLandObject.landData.localID; + landList[startLandObjectIndex].setLandBitmap(Land.modifyLandBitmapSquare(startLandObject.getLandBitmap(), start_x, start_y, end_x, end_y, false)); + landList[startLandObjectIndex].forceUpdateLandInfo(); + + + this.setPrimsTainted(); + + //Now add the new land object + Land result = addLandObject(newLand); + result.sendLandUpdateToAvatarsOverMe(); + + + + + return true; + } + /// + /// Join 2 land objects together + /// + /// x value in first piece of land + /// y value in first piece of land + /// x value in second peice of land + /// y value in second peice of land + /// LLUUID of the avatar trying to join the land objects + /// Returns true if successful + private bool join(int start_x, int start_y, int end_x, int end_y, LLUUID attempting_user_id) + { + end_x -= 4; + end_y -= 4; + + List selectedLandObjects = new List(); + int stepXSelected = 0; + int stepYSelected = 0; + for (stepYSelected = start_y; stepYSelected <= end_y; stepYSelected += 4) + { + for (stepXSelected = start_x; stepXSelected <= end_x; stepXSelected += 4) + { + Land p = getLandObject(stepXSelected,stepYSelected); + if (!selectedLandObjects.Contains(p)) + { + selectedLandObjects.Add(p); + } + } + } + Land masterLandObject = selectedLandObjects[0]; + selectedLandObjects.RemoveAt(0); + + + if (selectedLandObjects.Count < 1) + { + return false; //Only one piece of land selected + } + if (masterLandObject.landData.ownerID != attempting_user_id) + { + return false; //Not the same owner + } + foreach (Land p in selectedLandObjects) + { + if (p.landData.ownerID != masterLandObject.landData.ownerID) + { + return false; //Over multiple users. TODO: make this just ignore this piece of land? + } + } + foreach (Land slaveLandObject in selectedLandObjects) + { + landList[masterLandObject.landData.localID].setLandBitmap(Land.mergeLandBitmaps(masterLandObject.getLandBitmap(), slaveLandObject.getLandBitmap())); + performFinalLandJoin(masterLandObject, slaveLandObject); + } + + + this.setPrimsTainted(); + + masterLandObject.sendLandUpdateToAvatarsOverMe(); + + return true; + + + + } + #endregion + + #region Parcel Updating + /// + /// Where we send the ParcelOverlay packet to the client + /// + /// The object representing the client + public void sendParcelOverlay(IClientAPI remote_client) + { + const int LAND_BLOCKS_PER_PACKET = 1024; + int x, y = 0; + byte[] byteArray = new byte[LAND_BLOCKS_PER_PACKET]; + int byteArrayCount = 0; + int sequenceID = 0; + ParcelOverlayPacket packet; + + for (y = 0; y < 64; y++) + { + for (x = 0; x < 64; x++) + { + byte tempByte = (byte)0; //This represents the byte for the current 4x4 + Land currentParcelBlock = getLandObject(x * 4, y * 4); + + if (currentParcelBlock.landData.ownerID == remote_client.AgentId) + { + //Owner Flag + tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_REQUESTER); + } + else if (currentParcelBlock.landData.salePrice > 0 && (currentParcelBlock.landData.authBuyerID == LLUUID.Zero || currentParcelBlock.landData.authBuyerID == remote_client.AgentId)) + { + //Sale Flag + tempByte = Convert.ToByte(tempByte | LAND_TYPE_IS_FOR_SALE); + } + else if (currentParcelBlock.landData.ownerID == LLUUID.Zero) + { + //Public Flag + tempByte = Convert.ToByte(tempByte | LAND_TYPE_PUBLIC); + } + else + { + //Other Flag + tempByte = Convert.ToByte(tempByte | LAND_TYPE_OWNED_BY_OTHER); + } + + + //Now for border control + if (x == 0) + { + tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST); + } + else if (getLandObject((x - 1) * 4, y * 4) != currentParcelBlock) + { + tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_WEST); + } + + if (y == 0) + { + tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH); + } + else if (getLandObject(x * 4, (y - 1) * 4) != currentParcelBlock) + { + tempByte = Convert.ToByte(tempByte | LAND_FLAG_PROPERTY_BORDER_SOUTH); + } + + byteArray[byteArrayCount] = tempByte; + byteArrayCount++; + if (byteArrayCount >= LAND_BLOCKS_PER_PACKET) + { + byteArrayCount = 0; + packet = new ParcelOverlayPacket(); + packet.ParcelData.Data = byteArray; + packet.ParcelData.SequenceID = sequenceID; + remote_client.OutPacket((Packet)packet); + sequenceID++; + byteArray = new byte[LAND_BLOCKS_PER_PACKET]; + } + } + } + + + } + + public void handleParcelPropertiesRequest(int start_x, int start_y, int end_x, int end_y, int sequence_id, bool snap_selection, IClientAPI remote_client) + { + //Get the land objects within the bounds + List temp = new List(); + int x, y, i; + int inc_x = end_x - start_x; + int inc_y = end_y - start_y; + for (x = 0; x < inc_x; x++) + { + for (y = 0; y < inc_y; y++) + { + Land currentParcel = getLandObject(start_x + x, start_y + y); + if (!temp.Contains(currentParcel)) + { + currentParcel.forceUpdateLandInfo(); + temp.Add(currentParcel); + } + } + } + + int requestResult = LAND_RESULT_SINGLE; + if (temp.Count > 1) + { + requestResult = LAND_RESULT_MULTIPLE; + } + + for (i = 0; i < temp.Count; i++) + { + temp[i].sendLandProperties(sequence_id, snap_selection, requestResult, remote_client); + } + + + sendParcelOverlay(remote_client); + } + + public void handleParcelPropertiesUpdateRequest(ParcelPropertiesUpdatePacket packet, IClientAPI remote_client) + { + if (landList.ContainsKey(packet.ParcelData.LocalID)) + { + landList[packet.ParcelData.LocalID].updateLandProperties(packet, remote_client); + } + } + public void handleParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client) + { + subdivide(west, south, east, north, remote_client.AgentId); + } + public void handleParcelJoinRequest(int west, int south, int east, int north, IClientAPI remote_client) + { + join(west, south, east, north, remote_client.AgentId); + + } + + public void handleParcelSelectObjectsRequest(int local_id, int request_type, IClientAPI remote_client) + { + landList[local_id].sendForceObjectSelect(local_id, request_type, remote_client); + } + + public void handleParcelObjectOwnersRequest(int local_id, IClientAPI remote_client) + { + landList[local_id].sendLandObjectOwners(remote_client); + } + #endregion + + /// + /// Resets the sim to the default land object (full sim piece of land owned by the default user) + /// + public void resetSimLandObjects() + { + //Remove all the land objects in the sim and add a blank, full sim land object set to public + landList.Clear(); + lastLandLocalID = START_LAND_LOCAL_ID - 1; + landIDList.Initialize(); + + Land fullSimParcel = new Land(LLUUID.Zero, false, m_scene); + + fullSimParcel.setLandBitmap(Land.getSquareLandBitmap(0, 0, 256, 256)); + fullSimParcel.landData.ownerID = m_regInfo.MasterAvatarAssignedUUID; + + addLandObject(fullSimParcel); + + } + + + public void handleSignificantClientMovement(IClientAPI remote_client) + { + ScenePresence clientAvatar = m_scene.RequestAvatar(remote_client.AgentId); + if (clientAvatar != null) + { + Land over = getLandObject(clientAvatar.AbsolutePosition.X,clientAvatar.AbsolutePosition.Y); + if (over != null) + { + over.sendLandProperties(0, false, 0, remote_client); + } + } + } + + public void resetAllLandPrimCounts() + { + foreach (Land p in landList.Values) + { + p.resetLandPrimCounts(); + } + } + public void setPrimsTainted() + { + this.landPrimCountTainted = true; + } + + public void addPrimToLandPrimCounts(SceneObjectGroup obj) + { + LLVector3 position = obj.AbsolutePosition; + Land landUnderPrim = getLandObject(position.X, position.Y); + if (landUnderPrim != null) + { + landUnderPrim.addPrimToCount(obj); + } + } + + public void removePrimFromLandPrimCounts(SceneObjectGroup obj) + { + foreach (Land p in landList.Values) + { + p.removePrimFromCount(obj); + } + } + + public void finalizeLandPrimCountUpdate() + { + //Get Simwide prim count for owner + Dictionary> landOwnersAndParcels = new Dictionary>(); + foreach (Land p in landList.Values) + { + if(!landOwnersAndParcels.ContainsKey(p.landData.ownerID)) + { + List tempList = new List(); + tempList.Add(p); + landOwnersAndParcels.Add(p.landData.ownerID,tempList); + } + else + { + landOwnersAndParcels[p.landData.ownerID].Add(p); + } + } + + foreach (LLUUID owner in landOwnersAndParcels.Keys) + { + int simArea = 0; + int simPrims = 0; + foreach (Land p in landOwnersAndParcels[owner]) + { + simArea += p.landData.area; + simPrims += p.landData.ownerPrims + p.landData.otherPrims + p.landData.groupPrims + p.landData.selectedPrims; + } + + foreach (Land p in landOwnersAndParcels[owner]) + { + p.landData.simwideArea = simArea; + p.landData.simwidePrims = simPrims; + } + } + + } + #endregion + } + #endregion + + + + + +} diff --git a/OpenSim/Region/Environment/PermissionManager.cs b/OpenSim/Region/Environment/PermissionManager.cs new file mode 100644 index 0000000000..55660c5c84 --- /dev/null +++ b/OpenSim/Region/Environment/PermissionManager.cs @@ -0,0 +1,297 @@ +using System.Collections.Generic; +using OpenSim.Framework; +using OpenSim.Framework.Types; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Servers; +using OpenSim.Region.Capabilities; +using OpenSim.Region.Environment.Scenes; +using OpenSim.Region.Environment.LandManagement; + +using libsecondlife; + +namespace OpenSim.Region.Environment +{ + public class PermissionManager + { + protected Scene m_scene; + + // Bypasses the permissions engine (always returns OK) + // disable in any production environment + // TODO: Change this to false when permissions are a desired default + // TODO: Move to configuration option. + private bool bypassPermissions = true; + + public PermissionManager(Scene scene) + { + m_scene = scene; + } + + public void DisablePermissions() + { + bypassPermissions = true; + } + + public void EnablePermissions() + { + bypassPermissions = false; + } + + protected virtual void SendPermissionError(LLUUID user, string reason) + { + m_scene.EventManager.TriggerPermissionError(user, reason); + } + + protected virtual bool IsAdministrator(LLUUID user) + { + if (bypassPermissions) + return bypassPermissions; + + return m_scene.RegionInfo.MasterAvatarAssignedUUID == user; + } + + protected virtual bool IsEstateManager(LLUUID user) + { + if (bypassPermissions) + return bypassPermissions; + + return false; + } + + protected virtual bool IsGridUser(LLUUID user) + { + return true; + } + + protected virtual bool IsGuest(LLUUID user) + { + return false; + } + + public virtual bool CanRezObject(LLUUID user, LLVector3 position) + { + bool permission = false; + + string reason = "Insufficient permission"; + + if (IsAdministrator(user)) + permission = true; + else + reason = "Not an administrator"; + + if (GenericParcelPermission(user, position)) + permission = true; + else + reason = "Not the parcel owner"; + + if (!permission) + SendPermissionError(user, reason); + + return true; + } + + #region Object Permissions + + protected virtual bool GenericObjectPermission(LLUUID user, LLUUID objId) + { + // Default: deny + bool permission = false; + + if( !m_scene.Entities.ContainsKey( objId )) + { + return false; + } + + // If it's not an object, we cant edit it. + if (!(m_scene.Entities[objId] is SceneObjectGroup)) + { + return false; + } + + SceneObjectGroup task = (SceneObjectGroup)m_scene.Entities[objId]; + LLUUID taskOwner = null; + + // Object owners should be able to edit their own content + if (user == taskOwner) + permission = true; + + // Users should be able to edit what is over their land. + if (m_scene.LandManager.getLandObject(task.AbsolutePosition.X, task.AbsolutePosition.Y).landData.ownerID == user) + permission = true; + + // Estate users should be able to edit anything in the sim + if (IsEstateManager(user)) + permission = true; + + // Admin objects should not be editable by the above + if (IsAdministrator(taskOwner)) + permission = false; + + // Admin should be able to edit anything in the sim (including admin objects) + if (IsAdministrator(user)) + permission = true; + + return permission; + } + + /// + /// Permissions check - can user delete an object? + /// + /// User attempting the delete + /// Target object + /// Has permission? + public virtual bool CanDeRezObject(LLUUID user, LLUUID obj) + { + return GenericObjectPermission(user, obj); + } + + public virtual bool CanEditObject(LLUUID user, LLUUID obj) + { + return GenericObjectPermission(user, obj); + } + + public virtual bool CanReturnObject(LLUUID user, LLUUID obj) + { + return GenericObjectPermission(user, obj); + } + + #endregion + + #region Communication Permissions + + public virtual bool GenericCommunicationPermission(LLUUID user, LLUUID target) + { + bool permission = false; + string reason = "Only registered users may communicate with another account."; + + if (IsGridUser(user)) + permission = true; + + if (!IsGridUser(user)) + { + permission = false; + reason = "The person that you are messaging is not a registered user."; + } + if (IsAdministrator(user)) + permission = true; + + if (IsEstateManager(user)) + permission = true; + + if (!permission) + SendPermissionError(user, reason); + + return permission; + } + + public virtual bool CanInstantMessage(LLUUID user, LLUUID target) + { + return GenericCommunicationPermission(user, target); + } + + public virtual bool CanInventoryTransfer(LLUUID user, LLUUID target) + { + return GenericCommunicationPermission(user, target); + } + + #endregion + + public virtual bool CanEditScript(LLUUID user, LLUUID script) + { + return IsAdministrator(user); + } + + public virtual bool CanRunScript(LLUUID user, LLUUID script) + { + return IsAdministrator(user); + } + + public virtual bool CanTerraform(LLUUID user, LLVector3 position) + { + bool permission = false; + + // Estate override + if (GenericEstatePermission(user)) + permission = true; + + // Land owner can terraform too + if (GenericParcelPermission(user, m_scene.LandManager.getLandObject(position.X, position.Y))) + permission = true; + + if (!permission) + SendPermissionError(user, "Not authorized to terraform at this location."); + + return permission; + } + + #region Estate Permissions + + protected virtual bool GenericEstatePermission(LLUUID user) + { + // Default: deny + bool permission = false; + + // Estate admins should be able to use estate tools + if (IsEstateManager(user)) + permission = true; + + // Administrators always have permission + if (IsAdministrator(user)) + permission = true; + + return permission; + } + + public virtual bool CanEditEstateTerrain(LLUUID user) + { + return GenericEstatePermission(user); + } + + #endregion + + #region Parcel Permissions + + protected virtual bool GenericParcelPermission(LLUUID user, Land parcel) + { + bool permission = false; + + if (parcel.landData.ownerID == user) + permission = true; + + if (parcel.landData.isGroupOwned) + { + // TODO: Need to do some extra checks here. Requires group code. + } + + if(IsEstateManager(user)) + permission = true; + + if (IsAdministrator(user)) + permission = true; + + return permission; + } + + protected virtual bool GenericParcelPermission(LLUUID user, LLVector3 pos) + { + return GenericParcelPermission(user, m_scene.LandManager.getLandObject(pos.X, pos.Y)); + } + + public virtual bool CanEditParcel(LLUUID user, Land parcel) + { + return GenericParcelPermission(user, parcel); + } + + public virtual bool CanSellParcel(LLUUID user, Land parcel) + { + return GenericParcelPermission(user, parcel); + } + + public virtual bool CanAbandonParcel(LLUUID user, Land parcel) + { + return GenericParcelPermission(user, parcel); + } + + #endregion + + } +} diff --git a/OpenSim/Region/Environment/RegionManager.cs b/OpenSim/Region/Environment/RegionManager.cs new file mode 100644 index 0000000000..e6ab8cb0e6 --- /dev/null +++ b/OpenSim/Region/Environment/RegionManager.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; +using OpenSim.Framework; +using OpenSim.Framework.Types; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Servers; +using OpenSim.Region.Capabilities; +using OpenSim.Region.Environment.Scenes; +using OpenSim.Region.Environment.LandManagement; + +namespace OpenSim.Region.Environment +{ + public class RegionManager + { + protected AgentCircuitManager authenticateHandler; + protected RegionCommsListener regionCommsHost; + protected CommunicationsManager commsManager; + protected List capsHandlers = new List(); + protected BaseHttpServer httpListener; + + protected Scene m_Scene; + + public LandManager LandManager; + public EstateManager estateManager; + + public RegionManager() + { + + } + + } +} diff --git a/OpenSim/Region/Environment/Scenes/Entity.cs b/OpenSim/Region/Environment/Scenes/Entity.cs new file mode 100644 index 0000000000..cfc93473b4 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Entity.cs @@ -0,0 +1,113 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; +using OpenSim.Physics.Manager; + +namespace OpenSim.Region.Environment.Scenes +{ + public abstract class Entity : EntityBase //this class (Entity) will be phased out + { + protected PhysicsActor _physActor; + + /// + /// + /// + public override LLVector3 AbsolutePosition + { + get + { + if (_physActor != null) + { + m_pos.X = _physActor.Position.X; + m_pos.Y = _physActor.Position.Y; + m_pos.Z = _physActor.Position.Z; + } + + return m_pos; + } + set + { + if (_physActor != null) + { + try + { + lock (m_scene.SyncRoot) + { + _physActor.Position = new PhysicsVector(value.X, value.Y, value.Z); + } + } + catch (Exception e) + { + Console.WriteLine(e.Message); + } + } + + m_pos = value; + } + } + + + /// + /// + /// + public override LLVector3 Velocity + { + get + { + if (_physActor != null) + { + m_velocity.X = _physActor.Velocity.X; + m_velocity.Y = _physActor.Velocity.Y; + m_velocity.Z = _physActor.Velocity.Z; + } + + return m_velocity; + } + set + { + if (_physActor != null) + { + try + { + lock (m_scene.SyncRoot) + { + _physActor.Velocity = new PhysicsVector(value.X, value.Y, value.Z); + } + } + catch (Exception e) + { + Console.WriteLine(e.Message); + } + } + + m_velocity = value; + } + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Environment/Scenes/EntityBase.cs b/OpenSim/Region/Environment/Scenes/EntityBase.cs new file mode 100644 index 0000000000..d10ca63f0f --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/EntityBase.cs @@ -0,0 +1,136 @@ +using System.Collections.Generic; +using Axiom.Math; +using libsecondlife; +using OpenSim.Region.Environment.Scenes.Scripting; + +namespace OpenSim.Region.Environment.Scenes +{ + public abstract class EntityBase : IScriptHost + { + protected List m_children; + + protected Scene m_scene; + + public LLUUID m_uuid; + public virtual LLUUID UUID + { + get + { + return m_uuid; + } + set + { + m_uuid = value; + } + } + + protected string m_name; + /// + /// + /// + public virtual string Name + { + get { return m_name; } + set { m_name = value; } + } + + protected LLVector3 m_pos; + /// + /// + /// + public virtual LLVector3 AbsolutePosition + { + get { return m_pos; } + set { m_pos = value; } + } + + public LLVector3 m_velocity; + /// + /// + /// + public virtual LLVector3 Velocity + { + get { return m_velocity; } + set { m_velocity = value; } + } + + protected Quaternion m_rotation = new Quaternion(0, 0, 1, 0); + public virtual Quaternion Rotation + { + get { return m_rotation; } + set { m_rotation = value; } + } + + protected uint m_localId; + public virtual uint LocalId + { + get { return m_localId; } + set { m_localId = value; } + } + + /// + /// Creates a new Entity (should not occur on it's own) + /// + public EntityBase() + { + m_uuid = new LLUUID(); + + m_pos = new LLVector3(); + m_velocity = new LLVector3(); + Rotation = new Quaternion(); + m_name = "(basic entity)"; + + m_children = new List(); + } + + /// + /// + /// + public virtual void UpdateMovement() + { + foreach (EntityBase child in m_children) + + { + child.UpdateMovement(); + } + } + + /// + /// Performs any updates that need to be done at each frame. This function is overridable from it's children. + /// + public virtual void Update() + { + // Do any per-frame updates needed that are applicable to every type of entity + + foreach (EntityBase child in m_children) + { + child.Update(); + } + } + + /// + /// Called at a set interval to inform entities that they should back themsleves up to the DB + /// + public virtual void BackUp() + { + } + + /// + /// Copies the entity + /// + /// + public virtual EntityBase Copy() + { + return (EntityBase) MemberwiseClone(); + } + + /// + /// Infoms the entity that the land (heightmap) has changed + /// + public virtual void LandRenegerated() + { + } + + public abstract void SetText(string text, Vector3 color, double alpha); + } +} \ No newline at end of file diff --git a/OpenSim/Region/Environment/Scenes/IScenePresenceBody.cs b/OpenSim/Region/Environment/Scenes/IScenePresenceBody.cs new file mode 100644 index 0000000000..7c3a0339fe --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/IScenePresenceBody.cs @@ -0,0 +1,14 @@ +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Interfaces; + +namespace OpenSim.Region.Environment.Scenes +{ + public interface IScenePresenceBody + { + void processMovement(IClientAPI remoteClient, uint flags, LLQuaternion bodyRotation); + void SetAppearance(byte[] texture, AgentSetAppearancePacket.VisualParamBlock[] visualParam); + void SendOurAppearance(IClientAPI OurClient); + void SendAppearanceToOtherAgent(ScenePresence avatarInfo); + } +} diff --git a/OpenSim/Region/Environment/Scenes/Primitive(Old).cs b/OpenSim/Region/Environment/Scenes/Primitive(Old).cs new file mode 100644 index 0000000000..7af879737e --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Primitive(Old).cs @@ -0,0 +1,724 @@ +using System; +using System.Collections.Generic; +using System.Xml; +using System.Xml.Serialization; +using Axiom.Math; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Inventory; +using OpenSim.Framework.Types; + +using InventoryItem = OpenSim.Framework.Inventory.InventoryItem; + +namespace OpenSim.Region.Environment.Scenes +{ + public delegate void PrimCountTaintedDelegate(); + + public class Primitive : EntityBase + { + private const uint FULL_MASK_PERMISSIONS = 2147483647; + + private LLVector3 m_positionLastFrame = new LLVector3(0, 0, 0); + private ulong m_regionHandle; + private byte m_updateFlag; + private uint m_flags = 32 + 65536 + 131072 + 256 + 4 + 8 + 2048 + 524288 + 268435456 + 128; + + private Dictionary m_inventoryItems; + + private string m_description = ""; + + public LLUUID CreatorID; + public LLUUID OwnerID; + public LLUUID LastOwnerID; + + public Int32 CreationDate; + + public uint ParentID = 0; + + public uint OwnerMask = FULL_MASK_PERMISSIONS; + public uint NextOwnerMask = FULL_MASK_PERMISSIONS; + public uint GroupMask = 0;// FULL_MASK_PERMISSIONS; + public uint EveryoneMask = 0;//FULL_MASK_PERMISSIONS; + public uint BaseMask = 0;//FULL_MASK_PERMISSIONS; + + private PrimitiveBaseShape m_shape; + private byte[] m_particleSystem = new byte[0]; + + public SceneObjectOLD m_RootParent; + public bool m_isRootPrim; + public EntityBase m_Parent; + + public event PrimCountTaintedDelegate OnPrimCountTainted; + + #region Properties + + /// + /// If rootprim, will return world position + /// otherwise will return local offset from rootprim + /// + public override LLVector3 AbsolutePosition + { + get + { + if (m_isRootPrim) + { + //if we are rootprim then our offset should be zero + return m_pos + m_Parent.AbsolutePosition; + } + else + { + return m_pos; + } + } + set + { + if (m_isRootPrim) + { + m_Parent.AbsolutePosition = value; + } + m_pos = value - m_Parent.AbsolutePosition; + } + } + + public PrimitiveBaseShape Shape + { + get { return m_shape; } + } + + public LLVector3 WorldPos + { + get + { + if (!m_isRootPrim) + { + Primitive parentPrim = (Primitive)m_Parent; + Vector3 offsetPos = new Vector3(m_pos.X, m_pos.Y, m_pos.Z); + offsetPos = parentPrim.Rotation * offsetPos; + return parentPrim.WorldPos + new LLVector3(offsetPos.x, offsetPos.y, offsetPos.z); + } + else + { + return AbsolutePosition; + } + } + } + + public string Description + { + get { return m_description; } + set { m_description = value; } + } + + public LLVector3 Scale + { + set { m_shape.Scale = value; } + get { return m_shape.Scale; } + } + + private string m_sitName = ""; + public string SitName + { + get { return m_sitName; } + } + + private string m_touchName = ""; + public string TouchName + { + get { return m_touchName; } + } + + private string m_text = ""; + public string Text + { + get { return m_text; } + set + { + m_text = value; + ScheduleFullUpdate(); + } + } + + #endregion + + #region Constructors + + public Primitive(ulong regionHandle, Scene scene, LLUUID ownerID, uint localID, bool isRoot, EntityBase parent, + SceneObjectOLD rootObject, PrimitiveBaseShape shape, LLVector3 pos) + { + m_regionHandle = regionHandle; + m_scene = scene; + m_inventoryItems = new Dictionary(); + m_Parent = parent; + m_isRootPrim = isRoot; + m_RootParent = rootObject; + ClearUpdateSchedule(); + CreateFromShape(ownerID, localID, pos, shape); + + Rotation = Quaternion.Identity; + + m_scene.AcknowledgeNewPrim(this); + + OnPrimCountTainted(); + } + + /// + /// + /// + /// Empty constructor for duplication + public Primitive() + { + } + + #endregion + + #region Destructors + + ~Primitive() + { + if (OnPrimCountTainted != null) + OnPrimCountTainted(); + } + + #endregion + + #region Duplication + + public Primitive Copy(EntityBase parent, SceneObjectOLD rootParent) + { + Primitive dupe = (Primitive)MemberwiseClone(); + + dupe.m_Parent = parent; + dupe.m_RootParent = rootParent; + + // TODO: Copy this properly. + + dupe.m_inventoryItems = m_inventoryItems; + dupe.m_children = new List(); + dupe.m_shape = m_shape.Copy(); + dupe.m_regionHandle = m_regionHandle; + dupe.m_scene = m_scene; + + + uint newLocalID = m_scene.PrimIDAllocate(); + dupe.m_uuid = LLUUID.Random(); + dupe.LocalId = newLocalID; + + if (parent is SceneObjectGroup) + { + dupe.m_isRootPrim = true; + dupe.ParentID = 0; + } + else + { + dupe.m_isRootPrim = false; + dupe.ParentID = ((Primitive)parent).LocalId; + } + + dupe.Scale = new LLVector3(Scale.X, Scale.Y, Scale.Z); + dupe.Rotation = new Quaternion(Rotation.w, Rotation.x, Rotation.y, Rotation.z); + dupe.m_pos = new LLVector3(m_pos.X, m_pos.Y, m_pos.Z); + + rootParent.AddChildToList(dupe); + m_scene.AcknowledgeNewPrim(dupe); + dupe.TriggerOnPrimCountTainted(); + + + foreach (Primitive prim in m_children) + { + Primitive primClone = prim.Copy(dupe, rootParent); + + dupe.m_children.Add(primClone); + } + + return dupe; + } + + #endregion + + #region Override from EntityBase + + /// + /// + /// + public override void Update() + { + if (m_updateFlag == 1) //some change has been made so update the clients + { + SendTerseUpdateToALLClients(); + ClearUpdateSchedule(); + } + else + { + if (m_updateFlag == 2) // is a new prim just been created/reloaded or has major changes + { + SendFullUpdateToAllClients(); + ClearUpdateSchedule(); + } + } + + foreach (EntityBase child in m_children) + { + child.Update(); + } + } + + private void ClearUpdateSchedule() + { + m_updateFlag = 0; + } + + #endregion + + #region Setup + + /// + /// + /// + /// + /// + /// + public void CreateFromShape(LLUUID ownerID, uint localID, LLVector3 pos, PrimitiveBaseShape shape) + { + CreationDate = (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; + OwnerID = ownerID; + CreatorID = OwnerID; + LastOwnerID = LLUUID.Zero; + AbsolutePosition = pos; + m_uuid = LLUUID.Random(); + m_localId = (uint)(localID); + + m_shape = shape; + + ScheduleFullUpdate(); + } + + private void ScheduleFullUpdate() + { + m_updateFlag = 2; + } + + private void ScheduleTerseUpdate() + { + if (m_updateFlag < 1) + { + m_updateFlag = 1; + } + } + + #endregion + + #region Linking / unlinking + + /// + /// + /// + /// + public void AddNewChildren(SceneObjectOLD linkObject) + { + // Console.WriteLine("linking new prims " + linkObject.rootLocalID + " to me (" + this.LocalId + ")"); + //TODO check permissions + + m_children.Add(linkObject.rootPrimitive); + linkObject.rootPrimitive.SetNewParent(this, m_RootParent); + + m_scene.DeleteEntity(linkObject.rootUUID); + linkObject.DeleteAllChildren(); + + OnPrimCountTainted(); + } + + /// + /// + /// + /// + /// + public void SetNewParent(Primitive newParent, SceneObjectOLD rootParent) + { + LLVector3 oldPos = new LLVector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); + m_isRootPrim = false; + m_Parent = newParent; + ParentID = newParent.LocalId; + m_RootParent = rootParent; + m_RootParent.AddChildToList(this); + AbsolutePosition = oldPos; + Vector3 axPos = new Vector3(m_pos.X, m_pos.Y, m_pos.Z); + axPos = m_Parent.Rotation.Inverse() * axPos; + m_pos = new LLVector3(axPos.x, axPos.y, axPos.z); + Quaternion oldRot = new Quaternion(Rotation.w, Rotation.x, Rotation.y, Rotation.z); + Rotation = m_Parent.Rotation.Inverse() * Rotation; + ScheduleFullUpdate(); + + + foreach (Primitive child in m_children) + { + child.SetRootParent(rootParent, newParent, oldPos, oldRot); + } + + m_children.Clear(); + + } + + /// + /// + /// + /// + public void SetRootParent(SceneObjectOLD newRoot, Primitive newParent, LLVector3 oldParentPosition, + Quaternion oldParentRotation) + { + LLVector3 oldPos = new LLVector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); + Vector3 axOldPos = new Vector3(oldPos.X, oldPos.Y, oldPos.Z); + axOldPos = oldParentRotation * axOldPos; + oldPos = new LLVector3(axOldPos.x, axOldPos.y, axOldPos.z); + oldPos += oldParentPosition; + Quaternion oldRot = new Quaternion(Rotation.w, Rotation.x, Rotation.y, Rotation.z); + m_isRootPrim = false; + m_Parent = newParent; + ParentID = newParent.LocalId; + newParent.AddToChildrenList(this); + + m_RootParent = newRoot; + m_RootParent.AddChildToList(this); + AbsolutePosition = oldPos; + Vector3 axPos = new Vector3(m_pos.X, m_pos.Y, m_pos.Z); + axPos = m_Parent.Rotation.Inverse() * axPos; + m_pos = new LLVector3(axPos.x, axPos.y, axPos.z); + Rotation = oldParentRotation * Rotation; + Rotation = m_Parent.Rotation.Inverse() * Rotation; + ScheduleFullUpdate(); + foreach (Primitive child in m_children) + { + child.SetRootParent(newRoot, newParent, oldPos, oldRot); + } + + m_children.Clear(); + + } + + /// + /// + /// + /// + public void AddOffsetToChildren(LLVector3 offset) + { + foreach (Primitive prim in m_children) + { + prim.m_pos += offset; + prim.ScheduleTerseUpdate(); + } + OnPrimCountTainted(); + } + + /// + /// + /// + /// + public void AddToChildrenList(Primitive prim) + { + m_children.Add(prim); + } + + #endregion + + #region Resizing/Scale + + /// + /// + /// + /// + public void ResizeGoup(LLVector3 scale) + { + m_shape.Scale = scale; + + ScheduleFullUpdate(); + } + + #endregion + + #region Position + + /// + /// + /// + /// + public void UpdateGroupPosition(LLVector3 pos) + { + LLVector3 newPos = new LLVector3(pos.X, pos.Y, pos.Z); + + AbsolutePosition = newPos; + ScheduleTerseUpdate(); + + OnPrimCountTainted(); + } + + /// + /// + /// + /// + public void UpdateSinglePosition(LLVector3 pos) + { + // Console.WriteLine("updating single prim position"); + if (m_isRootPrim) + { + LLVector3 newPos = new LLVector3(pos.X, pos.Y, pos.Z); + LLVector3 oldPos = new LLVector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); + LLVector3 diff = oldPos - newPos; + Vector3 axDiff = new Vector3(diff.X, diff.Y, diff.Z); + axDiff = Rotation.Inverse() * axDiff; + diff.X = axDiff.x; + diff.Y = axDiff.y; + diff.Z = axDiff.z; + AbsolutePosition = newPos; + + foreach (Primitive prim in m_children) + { + prim.m_pos += diff; + prim.ScheduleTerseUpdate(); + } + ScheduleTerseUpdate(); + } + else + { + LLVector3 newPos = new LLVector3(pos.X, pos.Y, pos.Z); + m_pos = newPos; + ScheduleTerseUpdate(); + } + } + + #endregion + + #region Rotation + + /// + /// + /// + /// + public void UpdateGroupRotation(LLQuaternion rot) + { + Rotation = new Quaternion(rot.W, rot.X, rot.Y, rot.Z); + ScheduleTerseUpdate(); + } + + /// + /// + /// + /// + /// + public void UpdateGroupMouseRotation(LLVector3 pos, LLQuaternion rot) + { + Rotation = new Quaternion(rot.W, rot.X, rot.Y, rot.Z); + AbsolutePosition = pos; + ScheduleTerseUpdate(); + } + + /// + /// + /// + /// + public void UpdateSingleRotation(LLQuaternion rot) + { + //Console.WriteLine("updating single prim rotation"); + + Quaternion axRot = new Quaternion(rot.W, rot.X, rot.Y, rot.Z); + Quaternion oldParentRot = new Quaternion(Rotation.w, Rotation.x, Rotation.y, Rotation.z); + Rotation = axRot; + foreach (Primitive prim in m_children) + { + Vector3 axPos = new Vector3(prim.m_pos.X, prim.m_pos.Y, prim.m_pos.Z); + axPos = oldParentRot * axPos; + axPos = axRot.Inverse() * axPos; + prim.m_pos = new LLVector3(axPos.x, axPos.y, axPos.z); + prim.Rotation = oldParentRot * prim.Rotation; + prim.Rotation = axRot.Inverse() * prim.Rotation; + prim.ScheduleTerseUpdate(); + } + ScheduleTerseUpdate(); + } + + #endregion + + #region Shape + + /// + /// + /// + /// + public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock) + { + m_shape.PathBegin = shapeBlock.PathBegin; + m_shape.PathEnd = shapeBlock.PathEnd; + m_shape.PathScaleX = shapeBlock.PathScaleX; + m_shape.PathScaleY = shapeBlock.PathScaleY; + m_shape.PathShearX = shapeBlock.PathShearX; + m_shape.PathShearY = shapeBlock.PathShearY; + m_shape.PathSkew = shapeBlock.PathSkew; + m_shape.ProfileBegin = shapeBlock.ProfileBegin; + m_shape.ProfileEnd = shapeBlock.ProfileEnd; + m_shape.PathCurve = shapeBlock.PathCurve; + m_shape.ProfileCurve = shapeBlock.ProfileCurve; + m_shape.ProfileHollow = shapeBlock.ProfileHollow; + m_shape.PathRadiusOffset = shapeBlock.PathRadiusOffset; + m_shape.PathRevolutions = shapeBlock.PathRevolutions; + m_shape.PathTaperX = shapeBlock.PathTaperX; + m_shape.PathTaperY = shapeBlock.PathTaperY; + m_shape.PathTwist = shapeBlock.PathTwist; + m_shape.PathTwistBegin = shapeBlock.PathTwistBegin; + ScheduleFullUpdate(); + } + + #endregion + + #region Inventory + public void GetInventory(IClientAPI client, uint localID) + { + if (localID == this.m_localId) + { + client.SendTaskInventory(this.m_uuid, 0, new byte[0]); + } + } + #endregion + + public void UpdateExtraParam(ushort type, bool inUse, byte[] data) + { + this.m_shape.ExtraParams = new byte[data.Length + 7]; + int i =0; + uint length = (uint) data.Length; + this.m_shape.ExtraParams[i++] = 1; + this.m_shape.ExtraParams[i++] = (byte)(type % 256); + this.m_shape.ExtraParams[i++] = (byte)((type >> 8) % 256); + + this.m_shape.ExtraParams[i++] = (byte)(length % 256); + this.m_shape.ExtraParams[i++] = (byte)((length >> 8) % 256); + this.m_shape.ExtraParams[i++] = (byte)((length >> 16) % 256); + this.m_shape.ExtraParams[i++] = (byte)((length >> 24) % 256); + Array.Copy(data, 0, this.m_shape.ExtraParams, i, data.Length); + + this.ScheduleFullUpdate(); + } + + #region Texture + + /// + /// + /// + /// + public void UpdateTextureEntry(byte[] textureEntry) + { + m_shape.TextureEntry = textureEntry; + ScheduleFullUpdate(); + } + + #endregion + + public void AddNewParticleSystem(libsecondlife.Primitive.ParticleSystem pSystem) + { + this.m_particleSystem = pSystem.GetBytes(); + ScheduleFullUpdate(); + } + + #region Client Update Methods + + /// + /// + /// + /// + public void SendFullUpdateForAllChildren(IClientAPI remoteClient) + { + + SendFullUpdateToClient(remoteClient); + for (int i = 0; i < m_children.Count; i++) + + { + + if (m_children[i] is Primitive) + { + ((Primitive)m_children[i]).SendFullUpdateForAllChildren(remoteClient); + } + } + } + + /// + /// + /// + /// + public void SendFullUpdateToClient(IClientAPI remoteClient) + { + LLVector3 lPos; + lPos = AbsolutePosition; + LLQuaternion lRot; + lRot = new LLQuaternion(Rotation.x, Rotation.y, Rotation.z, Rotation.w); + + remoteClient.SendPrimitiveToClient(m_regionHandle, 64096, LocalId, m_shape, lPos, m_flags, m_uuid, OwnerID, + m_text, ParentID, this.m_particleSystem, lRot); + } + + /// + /// + /// + public void SendFullUpdateToAllClients() + { + List avatars = m_scene.RequestAvatarList(); + for (int i = 0; i < avatars.Count; i++) + { + SendFullUpdateToClient(avatars[i].ControllingClient); + } + } + + /// + /// + /// + /// + public void SendTerseUpdateForAllChildren(IClientAPI remoteClient) + { + + SendTerseUpdateToClient(remoteClient); + for (int i = 0; i < m_children.Count; i++) + { + if (m_children[i] is Primitive) + { + ((Primitive)m_children[i]).SendTerseUpdateForAllChildren(remoteClient); + } + } + } + + /// + /// + /// + /// + public void SendTerseUpdateToClient(IClientAPI RemoteClient) + { + LLVector3 lPos; + Quaternion lRot; + + lPos = AbsolutePosition; + lRot = Rotation; + + LLQuaternion mRot = new LLQuaternion(lRot.x, lRot.y, lRot.z, lRot.w); + RemoteClient.SendPrimTerseUpdate(m_regionHandle, 64096, LocalId, lPos, mRot); + } + + /// + /// + /// + public void SendTerseUpdateToALLClients() + { + List avatars = m_scene.RequestAvatarList(); + for (int i = 0; i < avatars.Count; i++) + { + SendTerseUpdateToClient(avatars[i].ControllingClient); + } + } + + #endregion + + public void TriggerOnPrimCountTainted() + { + OnPrimCountTainted(); + } + + public override void SetText(string text, Vector3 color, double alpha) + { + throw new Exception("The method or operation is not implemented."); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs new file mode 100644 index 0000000000..827eb5e911 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs @@ -0,0 +1,851 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.IO; +using System.Collections.Generic; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Framework.Communications.Caches; +using OpenSim.Framework.Data; +using OpenSim.Framework.Utilities; + +namespace OpenSim.Region.Environment.Scenes +{ + public partial class Scene + { + /// + /// Modifies terrain using the specified information + /// + /// The height at which the user started modifying the terrain + /// The number of seconds the modify button was pressed + /// The size of the brush used + /// The action to be performed + /// Distance from the north border where the cursor is located + /// Distance from the west border where the cursor is located + public void ModifyTerrain(float height, float seconds, byte brushsize, byte action, float north, float west, IClientAPI remoteUser) + { + // Do a permissions check before allowing terraforming. + // random users are now no longer allowed to terraform + // if permissions are enabled. + if (!PermissionsMngr.CanTerraform(remoteUser.AgentId, new LLVector3(north, west, 0))) + return; + + // Shiny. + double size = (double)(1 << brushsize); + + switch (action) + { + case 0: + // flatten terrain + Terrain.FlattenTerrain(west, north, size, (double)seconds / 5.0); + break; + case 1: + // raise terrain + Terrain.RaiseTerrain(west, north, size, (double)seconds / 5.0); + break; + case 2: + //lower terrain + Terrain.LowerTerrain(west, north, size, (double)seconds / 5.0); + break; + case 3: + // smooth terrain + Terrain.SmoothTerrain(west, north, size, (double)seconds / 5.0); + break; + case 4: + // noise + Terrain.NoiseTerrain(west, north, size, (double)seconds / 5.0); + break; + case 5: + // revert + Terrain.RevertTerrain(west, north, size, (double)seconds / 5.0); + break; + + // CLIENT EXTENSIONS GO HERE + case 128: + // erode-thermal + break; + case 129: + // erode-aerobic + break; + case 130: + // erode-hydraulic + break; + } + + for (int x = 0; x < 16; x++) + { + for (int y = 0; y < 16; y++) + { + if (Terrain.Tainted(x * 16, y * 16)) + { + remoteUser.SendLayerData(x, y, Terrain.GetHeights1D()); + } + } + } + + return; + } + + /// + /// + /// + /// Inefficient. TODO: Fixme + /// + /// + /// + /// + /// + public void InstantMessage(LLUUID fromAgentID, LLUUID toAgentID, uint timestamp, string fromAgentName, string message) + { + if (this.Avatars.ContainsKey(toAgentID)) + { + if (this.Avatars.ContainsKey(fromAgentID)) + { + // Local sim message + ScenePresence fromAvatar = this.Avatars[fromAgentID]; + ScenePresence toAvatar = this.Avatars[toAgentID]; + string fromName = fromAvatar.Firstname + " " + fromAvatar.Lastname; + toAvatar.ControllingClient.SendInstantMessage(message, toAgentID, fromName); + } + else + { + // Message came from a user outside the sim, ignore? + } + } + else + { + // Grid message + } + } + + /// + /// + /// + /// + /// + /// + /// + /// + public void SimChat(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID) + { + ScenePresence avatar = null; + if (this.Avatars.ContainsKey(fromAgentID)) + { + avatar = this.Avatars[fromAgentID]; + fromPos = avatar.AbsolutePosition; + fromName = avatar.Firstname + " " + avatar.Lastname; + avatar = null; + } + + this.ForEachScenePresence(delegate(ScenePresence presence) + { + int dis = -1000; + if (this.Avatars.ContainsKey(presence.ControllingClient.AgentId)) + { + avatar = this.Avatars[presence.ControllingClient.AgentId]; + dis = (int)avatar.AbsolutePosition.GetDistanceTo(fromPos); + } + + switch (type) + { + case 0: // Whisper + if ((dis < 10) && (dis > -10)) + { + //should change so the message is sent through the avatar rather than direct to the ClientView + presence.ControllingClient.SendChatMessage(message, type, fromPos, fromName, + fromAgentID); + } + break; + case 1: // Say + if ((dis < 30) && (dis > -30)) + { + //Console.WriteLine("sending chat"); + presence.ControllingClient.SendChatMessage(message, type, fromPos, fromName, + fromAgentID); + } + break; + case 2: // Shout + if ((dis < 100) && (dis > -100)) + { + presence.ControllingClient.SendChatMessage(message, type, fromPos, fromName, + fromAgentID); + } + break; + + case 0xff: // Broadcast + presence.ControllingClient.SendChatMessage(message, type, fromPos, fromName, + fromAgentID); + break; + } + }); + } + + /// + /// + /// + /// + /// + public void DeRezObject(Packet packet, IClientAPI remoteClient) + { + DeRezObjectPacket DeRezPacket = (DeRezObjectPacket)packet; + + + if (DeRezPacket.AgentBlock.DestinationID == LLUUID.Zero) + { + //currently following code not used (or don't know of any case of destination being zero + } + else + { + foreach (DeRezObjectPacket.ObjectDataBlock Data in DeRezPacket.ObjectData) + { + EntityBase selectedEnt = null; + //OpenSim.Framework.Console.MainConsole.Instance.WriteLine("LocalID:" + Data.ObjectLocalID.ToString()); + foreach (EntityBase ent in this.Entities.Values) + { + if (ent.LocalId == Data.ObjectLocalID) + { + selectedEnt = ent; + break; + } + } + if (selectedEnt != null) + { + if (PermissionsMngr.CanDeRezObject(remoteClient.AgentId,((SceneObjectGroup)selectedEnt).UUID)) + { + string sceneObjectXml = ((SceneObjectGroup)selectedEnt).ToXmlString(); + CachedUserInfo userInfo = commsManager.UserProfiles.GetUserDetails(remoteClient.AgentId); + if (userInfo != null) + { + AssetBase asset = new AssetBase(); + asset.Name = ((SceneObjectGroup)selectedEnt).GetPartName(selectedEnt.LocalId); + asset.Description = ((SceneObjectGroup)selectedEnt).GetPartDescription(selectedEnt.LocalId); + asset.InvType = 6; + asset.Type = 6; + asset.FullID = LLUUID.Random(); + asset.Data = Helpers.StringToField(sceneObjectXml); + this.assetCache.AddAsset(asset); + + + InventoryItemBase item = new InventoryItemBase(); + item.avatarID = remoteClient.AgentId; + item.creatorsID = remoteClient.AgentId; + item.inventoryID = LLUUID.Random(); + item.assetID = asset.FullID; + item.inventoryDescription = asset.Description; + item.inventoryName = asset.Name; + item.assetType = asset.Type; + item.invType = asset.InvType; + item.parentFolderID = DeRezPacket.AgentBlock.DestinationID; + item.inventoryCurrentPermissions = 2147483647; + item.inventoryNextPermissions = 2147483647; + + userInfo.AddItem(remoteClient.AgentId, item); + remoteClient.SendInventoryItemUpdate(item); + } + + storageManager.DataStore.RemoveObject(((SceneObjectGroup)selectedEnt).UUID); + ((SceneObjectGroup)selectedEnt).DeleteGroup(); + + lock (Entities) + { + Entities.Remove(((SceneObjectGroup) selectedEnt).UUID); + } + } + } + } + } + } + + public void RezObject(IClientAPI remoteClient, LLUUID itemID, LLVector3 pos) + { + CachedUserInfo userInfo = commsManager.UserProfiles.GetUserDetails(remoteClient.AgentId); + if (userInfo != null) + { + if(userInfo.RootFolder != null) + { + InventoryItemBase item = userInfo.RootFolder.HasItem(itemID); + if (item != null) + { + AssetBase rezAsset = this.assetCache.GetAsset(item.assetID, false); + if (rezAsset != null) + { + this.AddRezObject(Util.FieldToString(rezAsset.Data), pos); + userInfo.DeleteItem(remoteClient.AgentId, item); + remoteClient.SendRemoveInventoryItem(itemID); + } + else + { + rezAsset = this.assetCache.GetAsset(item.assetID, false); + if (rezAsset != null) + { + this.AddRezObject(Util.FieldToString(rezAsset.Data), pos); + userInfo.DeleteItem(remoteClient.AgentId, item); + remoteClient.SendRemoveInventoryItem(itemID); + } + } + } + } + } + } + + private void AddRezObject(string xmlData, LLVector3 pos) + { + SceneObjectGroup group = new SceneObjectGroup(this, this.m_regionHandle, xmlData); + this.AddEntity(group); + group.AbsolutePosition = pos; + } + + /// + /// + /// + /// + public void SendAvatarsToClient(IClientAPI remoteClient) + { + + } + + /// + /// + /// + /// + /// + /// + public void DuplicateObject(uint originalPrim, LLVector3 offset, uint flags) + { + SceneObjectGroup originPrim = null; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + if (((SceneObjectGroup)ent).LocalId == originalPrim) + { + originPrim = (SceneObjectGroup)ent; + break; + } + } + } + + if (originPrim != null) + { + SceneObjectGroup copy = originPrim.Copy(); + copy.AbsolutePosition = copy.AbsolutePosition + offset; + this.Entities.Add(copy.UUID, copy); + + copy.ScheduleGroupForFullUpdate(); + /* List avatars = this.RequestAvatarList(); + for (int i = 0; i < avatars.Count; i++) + { + // copy.SendAllChildPrimsToClient(avatars[i].ControllingClient); + }*/ + + } + else + { + OpenSim.Framework.Console.MainLog.Instance.Warn("client", "Attempted to duplicate nonexistant prim"); + } + + } + + /// + /// + /// + /// + /// + public void LinkObjects(uint parentPrim, List childPrims) + { + SceneObjectGroup parenPrim = null; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + if (((SceneObjectGroup)ent).LocalId == parentPrim) + { + parenPrim = (SceneObjectGroup)ent; + break; + } + } + } + + List children = new List(); + if (parenPrim != null) + { + for (int i = 0; i < childPrims.Count; i++) + { + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + if (((SceneObjectGroup)ent).LocalId == childPrims[i]) + { + children.Add((SceneObjectGroup)ent); + } + } + } + } + } + + foreach (SceneObjectGroup sceneObj in children) + { + parenPrim.LinkToGroup(sceneObj); + } + } + + /// + /// + /// + /// + /// + public void UpdatePrimShape(uint primLocalID, ObjectShapePacket.ObjectDataBlock shapeBlock) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(primLocalID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).UpdateShape(shapeBlock, primLocalID); + break; + } + } + } + } + + public void UpdateExtraParam(uint primLocalID, ushort type, bool inUse, byte[] data) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(primLocalID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).UpdateExtraParam(primLocalID, type, inUse, data); + break; + } + } + } + } + + /// + /// + /// + /// + /// + public void RequestTaskInventory(IClientAPI remoteClient, uint primLocalID) + { + + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(primLocalID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).GetPartInventoryFileName(remoteClient, primLocalID); + break; + } + } + } + } + + /// + /// + /// + /// + /// + public void SelectPrim(uint primLocalID, IClientAPI remoteClient) + { + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + if (((SceneObjectGroup)ent).LocalId == primLocalID) + { + ((SceneObjectGroup)ent).GetProperites(remoteClient); + ((SceneObjectGroup)ent).IsSelected = true; + this.LandManager.setPrimsTainted(); + break; + } + } + } + } + + /// + /// + /// + /// + /// + public void DeselectPrim(uint primLocalID, IClientAPI remoteClient) + { + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + if (((SceneObjectGroup)ent).LocalId == primLocalID) + { + ((SceneObjectGroup)ent).IsSelected = false; + this.LandManager.setPrimsTainted(); + break; + } + } + } + } + + /// + /// + /// + /// + /// + public void PrimDescription(uint primLocalID, string description) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(primLocalID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).SetPartDescription(description, primLocalID); + break; + } + } + } + } + + /// + /// + /// + /// + /// + public void PrimName(uint primLocalID, string name) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(primLocalID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).SetPartName(name, primLocalID); + break; + } + } + } + } + + public void MoveObject(LLUUID objectID, LLVector3 offset, LLVector3 pos, IClientAPI remoteClient) + { + if (PermissionsMngr.CanEditObject(remoteClient.AgentId, objectID)) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(objectID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).GrabMovement(offset, pos, remoteClient); + break; + } + } + } + } + } + + /// + /// + /// + /// + /// + /// + public void UpdatePrimFlags(uint localID, Packet packet, IClientAPI remoteClient) + { + + } + + /// + /// + /// + /// + /// + /// + public void UpdatePrimTexture(uint localID, byte[] texture, IClientAPI remoteClient) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(localID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).UpdateTextureEntry(localID, texture); + break; + } + } + } + } + + /// + /// + /// + /// + /// + /// + public void UpdatePrimPosition(uint localID, LLVector3 pos, IClientAPI remoteClient) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(localID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).UpdateGroupPosition(pos); + break; + } + } + } + } + + public void UpdatePrimSinglePosition(uint localID, LLVector3 pos, IClientAPI remoteClient) + { + Primitive prim = null; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + //prim = ((SceneObject)ent).HasChildPrim(localID); + if (prim != null) + { + prim.UpdateSinglePosition(pos); + break; + } + } + } + } + + /// + /// + /// + /// + /// + /// + /// + public void UpdatePrimRotation(uint localID, LLVector3 pos, LLQuaternion rot, IClientAPI remoteClient) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(localID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).UpdateGroupRotation(pos, rot); + // prim.UpdateGroupMouseRotation(pos, rot); + break; + } + } + } + } + + /// + /// + /// + /// + /// + /// + public void UpdatePrimRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(localID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).UpdateGroupRotation(rot); + //prim.UpdateGroupRotation(rot); + break; + } + } + } + } + + /// + /// + /// + /// + /// + /// + public void UpdatePrimSingleRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient) + { + //Console.WriteLine("trying to update single prim rotation"); + Primitive prim = null; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + // prim = ((SceneObject)ent).HasChildPrim(localID); + if (prim != null) + { + prim.UpdateSingleRotation(rot); + break; + } + } + } + } + + /// + /// + /// + /// + /// + /// + public void UpdatePrimScale(uint localID, LLVector3 scale, IClientAPI remoteClient) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(localID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).Resize(scale, localID); + // prim.ResizeGoup(scale); + break; + } + } + } + } + + /// + /// + /// + /// + /// + public void RequestAvatarProperty(IClientAPI remoteClient, LLUUID avatarID) + { + string about = "OpenSim crash test dummy"; + string bornOn = "Before now"; + string flAbout = "First life? What is one of those? OpenSim is my life!"; + LLUUID partner = new LLUUID("11111111-1111-0000-0000-000100bba000"); + remoteClient.SendAvatarProperties(avatarID, about, bornOn, "", flAbout, 0, LLUUID.Zero, LLUUID.Zero, "", partner); + } + + /// + /// + /// + /// + /// + /// + public void RequestXfer(IClientAPI remoteClient, ulong xferID, string fileName) + { + /* + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + ((SceneObjectGroup)ent).RequestInventoryFile(remoteClient, ((SceneObjectGroup)ent).LocalId, xferID); + break; + } + }*/ + } + + /// + /// temporary method to test out creating new inventory items + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public void CreateNewInventoryItem(IClientAPI remoteClient, LLUUID transActionID, LLUUID folderID, uint callbackID, string description, string name, sbyte invType, sbyte type, byte wearableType, uint nextOwnerMask) + { + if (transActionID == LLUUID.Zero) + { + CachedUserInfo userInfo = commsManager.UserProfiles.GetUserDetails(remoteClient.AgentId); + if (userInfo != null) + { + AssetBase asset = new AssetBase(); + asset.Name = name; + asset.Description = description; + asset.InvType = invType; + asset.Type = type; + asset.FullID = LLUUID.Random(); + asset.Data = new byte[1]; + this.assetCache.AddAsset(asset); + + InventoryItemBase item = new InventoryItemBase(); + item.avatarID = remoteClient.AgentId; + item.creatorsID = remoteClient.AgentId; + item.inventoryID = LLUUID.Random(); + item.assetID = asset.FullID; + item.inventoryDescription = description; + item.inventoryName = name; + item.assetType = invType; + item.invType = invType; + item.parentFolderID = folderID; + item.inventoryCurrentPermissions = 2147483647; + item.inventoryNextPermissions = nextOwnerMask; + + userInfo.AddItem(remoteClient.AgentId, item); + remoteClient.SendInventoryItemUpdate(item); + } + } + else + { + commsManager.TransactionsManager.HandleInventoryFromTransaction(remoteClient, transActionID, folderID, callbackID, description, name, invType, type, wearableType, nextOwnerMask); + //System.Console.WriteLine("request to create inventory item from transaction " + transActionID); + } + } + + public virtual void ProcessObjectGrab(uint localID, LLVector3 offsetPos, IClientAPI remoteClient) + { + this.EventManager.TriggerObjectGrab(localID, offsetPos, remoteClient); + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs new file mode 100644 index 0000000000..9a914d5d41 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -0,0 +1,1222 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Threading; +using System.Timers; +using System.IO; +using System.Xml; +using libsecondlife; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Console; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Types; +using OpenSim.Framework.Utilities; +using OpenSim.Physics.Manager; +using OpenSim.Framework.Communications.Caches; +using OpenSim.Region.Environment.LandManagement; +using OpenSim.Region.Scripting; +using OpenSim.Region.Terrain; +using OpenSim.Framework.Data; +using Caps = OpenSim.Region.Capabilities.Caps; +using Timer = System.Timers.Timer; + +namespace OpenSim.Region.Environment.Scenes +{ + public delegate bool FilterAvatarList(ScenePresence avatar); + + public delegate void ForEachScenePresenceDelegate(ScenePresence presence); + + public partial class Scene : SceneBase + { + protected Timer m_heartbeatTimer = new Timer(); + protected Dictionary Avatars; + protected Dictionary Prims; + protected PhysicsScene phyScene; + protected float timeStep = 0.1f; + private Random Rand = new Random(); + private uint _primCount = 702000; + private Mutex _primAllocateMutex = new Mutex(false); + private int storageCount; + private int terrainCheckCount; + private int landPrimCheckCount; + + private int m_timePhase = 24; + private int m_timeUpdateCount; + + private Mutex updateLock; + + protected StorageManager storageManager; + protected AgentCircuitManager authenticateHandler; + protected RegionCommsListener regionCommsHost; + protected CommunicationsManager commsManager; + + protected Dictionary capsHandlers = new Dictionary(); + protected BaseHttpServer httpListener; + + #region Properties + + public AgentCircuitManager AuthenticateHandler + { + get { return this.authenticateHandler; } + } + /// + /// + /// + public PhysicsScene PhysScene + { + set { phyScene = value; } + get { return (phyScene); } + } + + private LandManager m_LandManager; + + public LandManager LandManager + { + get { return m_LandManager; } + } + + private EstateManager m_estateManager; + + public EstateManager EstateManager + { + get { return m_estateManager; } + } + + private ScriptManager m_scriptManager; + + public ScriptManager ScriptManager + { + get { return m_scriptManager; } + } + + private PermissionManager m_permissionManager; + + public PermissionManager PermissionsMngr + { + get { return m_permissionManager; } + } + + public Dictionary Objects + { + get { return Prims; } + } + + public int TimePhase + { + get { return this.m_timePhase; } + } + + #endregion + + #region Constructors + + /// + /// Creates a new Scene class, and a region to go with it. + /// + /// Dictionary to contain client threads + /// Region Handle for this region + /// Region Name for this region + public Scene(RegionInfo regInfo, AgentCircuitManager authen, CommunicationsManager commsMan, + AssetCache assetCach, StorageManager storeManager, BaseHttpServer httpServer) + { + updateLock = new Mutex(false); + authenticateHandler = authen; + commsManager = commsMan; + storageManager = storeManager; + assetCache = assetCach; + m_regInfo = regInfo; + m_regionHandle = m_regInfo.RegionHandle; + m_regionName = m_regInfo.RegionName; + m_datastore = m_regInfo.DataStore; + RegisterRegionWithComms(); + + m_LandManager = new LandManager(this, m_regInfo); + m_estateManager = new EstateManager(this, m_regInfo); + m_scriptManager = new ScriptManager(this); + m_eventManager = new EventManager(); + m_permissionManager = new PermissionManager(this); + + m_eventManager.OnParcelPrimCountAdd += + m_LandManager.addPrimToLandPrimCounts; + + m_eventManager.OnPermissionError += SendPermissionAlert; + + MainLog.Instance.Verbose("Creating new entitities instance"); + Entities = new Dictionary(); + Avatars = new Dictionary(); + Prims = new Dictionary(); + + MainLog.Instance.Verbose("Creating LandMap"); + Terrain = new TerrainEngine((int)this.RegionInfo.RegionLocX, (int)this.RegionInfo.RegionLocY); + + ScenePresence.LoadAnims(); + + httpListener = httpServer; + } + + #endregion + + #region Script Handling Methods + + public void SendCommandToScripts(string[] args) + { + m_eventManager.TriggerOnScriptConsole(args); + } + + #endregion + + /// + /// + /// + public void StartTimer() + { + m_heartbeatTimer.Enabled = true; + m_heartbeatTimer.Interval = 100; + m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); + } + + #region Update Methods + + /// + /// Performs per-frame updates regularly + /// + /// + /// + private void Heartbeat(object sender, EventArgs e) + { + Update(); + } + + /// + /// Performs per-frame updates on the scene, this should be the central scene loop + /// + public override void Update() + { + updateLock.WaitOne(); + try + { + if (phyScene.IsThreaded) + { + phyScene.GetResults(); + } + + List moveEntities = new List(Entities.Values); + + foreach (EntityBase entity in moveEntities) + { + entity.UpdateMovement(); + } + + lock (m_syncRoot) + { + phyScene.Simulate(timeStep); + } + + List updateEntities = new List(Entities.Values); + + foreach (EntityBase entity in updateEntities) + { + entity.Update(); + } + + // General purpose event manager + m_eventManager.TriggerOnFrame(); + + //backup scene data + storageCount++; + if (storageCount > 600) //set to how often you want to backup + { + Backup(); + storageCount = 0; + } + + terrainCheckCount++; + if (terrainCheckCount >= 50) + { + terrainCheckCount = 0; + + if (Terrain.Tainted()) + { + CreateTerrainTexture(); + + lock (Terrain.heightmap) + { + lock (m_syncRoot) + { + phyScene.SetTerrain(Terrain.GetHeights1D()); + } + + storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD()); + + float[] terData = Terrain.GetHeights1D(); + + ForEachScenePresence(delegate(ScenePresence presence) + { + for (int x = 0; x < 16; x++) + { + for (int y = 0; y < 16; y++) + { + if (Terrain.Tainted(x * 16, y * 16)) + { + SendLayerData(x, y, presence.ControllingClient, terData); + } + } + } + }); + + foreach (LLUUID UUID in Entities.Keys) + { + Entities[UUID].LandRenegerated(); + } + + Terrain.ResetTaint(); + } + } + } + + landPrimCheckCount++; + if (landPrimCheckCount > 50) //check every 5 seconds for tainted prims + { + if (m_LandManager.landPrimCountTainted) + { + //Perform land update of prim count + performParcelPrimCountUpdate(); + landPrimCheckCount = 0; + } + } + + m_timeUpdateCount++; + if (m_timeUpdateCount > 600) + { + List Avatars = this.RequestAvatarList(); + foreach (ScenePresence avatar in Avatars) + { + if (!avatar.childAgent) + { + //Console.WriteLine("sending time update " + timePhase + " from region " + m_regionHandle + " to avatar " + avatar.Firstname); + avatar.ControllingClient.SendViewerTime(m_timePhase); + } + } + m_timeUpdateCount = 0; + m_timePhase++; + if (m_timePhase > 94) + { + m_timePhase = 0; + } + } + } + catch (NotImplementedException) + { + throw; + } + catch (Exception e) + { + MainLog.Instance.Error("Scene", "Failed with exception " + e.ToString()); + } + updateLock.ReleaseMutex(); + } + + /// + /// + /// + /// + public bool Backup() + { + EventManager.TriggerOnBackup(storageManager.DataStore); + return true; + } + + #endregion + + #region Regenerate Terrain + + /// + /// Rebuilds the terrain using a procedural algorithm + /// + public void RegenerateTerrain() + { + try + { + Terrain.HillsGenerator(); + + lock (m_syncRoot) + { + phyScene.SetTerrain(Terrain.GetHeights1D()); + } + + storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD()); + + ForEachScenePresence(delegate(ScenePresence presence) + { + SendLayerData(presence.ControllingClient); + }); + + foreach (LLUUID UUID in Entities.Keys) + { + Entities[UUID].LandRenegerated(); + } + } + catch (Exception e) + { + MainLog.Instance.Error("terrain", "Failed with exception " + e.ToString()); + } + } + + /// + /// Rebuilds the terrain using a 2D float array + /// + /// 256,256 float array containing heights + public void RegenerateTerrain(float[,] newMap) + { + try + { + Terrain.SetHeights2D(newMap); + lock (m_syncRoot) + { + phyScene.SetTerrain(Terrain.GetHeights1D()); + } + storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD()); + + ForEachScenePresence(delegate(ScenePresence presence) + { + SendLayerData(presence.ControllingClient); + }); + + foreach (LLUUID UUID in Entities.Keys) + { + Entities[UUID].LandRenegerated(); + } + } + catch (Exception e) + { + MainLog.Instance.Warn("terrain", "World.cs: RegenerateTerrain() - Failed with exception " + e.ToString()); + } + } + + #endregion + + #region Load Terrain + + /// + /// Loads the World heightmap + /// + /// + public override void LoadWorldMap() + { + try + { + double[,] map = storageManager.DataStore.LoadTerrain(); + if (map == null) + { + if (string.IsNullOrEmpty(m_regInfo.estateSettings.terrainFile)) + { + Console.WriteLine("No default terrain, procedurally generating..."); + Terrain.HillsGenerator(); + + storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD()); + } + else + { + try + { + Terrain.LoadFromFileF32(m_regInfo.estateSettings.terrainFile); + Terrain *= m_regInfo.estateSettings.terrainMultiplier; + } + catch + { + Console.WriteLine("Unable to load default terrain, procedurally generating instead..."); + Terrain.HillsGenerator(); + } + storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD()); + } + } + else + { + Terrain.SetHeights2D(map); + } + + CreateTerrainTexture(); + } + catch (Exception e) + { + MainLog.Instance.Warn("terrain", "World.cs: LoadWorldMap() - Failed with exception " + e.ToString()); + } + } + + /// + /// + /// + public void CreateTerrainTexture() + { + //create a texture asset of the terrain + byte[] data = Terrain.ExportJpegImage("defaultstripe.png"); + m_regInfo.estateSettings.terrainImageID = LLUUID.Random(); + AssetBase asset = new AssetBase(); + asset.FullID = m_regInfo.estateSettings.terrainImageID; + asset.Data = data; + asset.Name = "terrainImage"; + asset.Type = 0; + assetCache.AddAsset(asset); + } + + #endregion + + #region Primitives Methods + + /// + /// Loads the World's objects + /// + public void LoadPrimsFromStorage() + { + MainLog.Instance.Verbose("Loading objects from datastore"); + List PrimsFromDB = storageManager.DataStore.LoadObjects(); + foreach (SceneObjectGroup prim in PrimsFromDB) + { + AddEntityFromStorage(prim); + } + MainLog.Instance.Verbose("Loaded " + PrimsFromDB.Count.ToString() + " SceneObject(s)"); + } + + /// + /// Loads a specific object from storage + /// + /// The object to load + public void PrimFromStorage(PrimData prim) + { + } + + /// + /// Returns a new unallocated primitive ID + /// + /// A brand new primitive ID + public uint PrimIDAllocate() + { + uint myID; + + _primAllocateMutex.WaitOne(); + ++_primCount; + myID = _primCount; + _primAllocateMutex.ReleaseMutex(); + + return myID; + } + + /// + /// + /// + /// + /// + public void AddNewPrim(LLUUID ownerID, LLVector3 pos, PrimitiveBaseShape shape) + { + SceneObjectGroup sceneOb = new SceneObjectGroup(this, this.m_regionHandle, ownerID, PrimIDAllocate(), pos, shape); + AddEntity(sceneOb); + } + + public void RemovePrim(uint localID, LLUUID avatar_deleter) + { + foreach (EntityBase obj in Entities.Values) + { + if (obj is SceneObjectGroup) + { + if (((SceneObjectGroup)obj).LocalId == localID) + { + RemoveEntity((SceneObjectGroup)obj); + return; + } + } + } + } + + public void AddEntityFromStorage(SceneObjectGroup sceneObject) + { + sceneObject.RegionHandle = this.m_regionHandle; + sceneObject.SetScene(this); + foreach (SceneObjectPart part in sceneObject.Children.Values) + { + part.LocalID = this.PrimIDAllocate(); + } + sceneObject.UpdateParentIDs(); + this.AddEntity(sceneObject); + } + + public void AddEntity(SceneObjectGroup sceneObject) + { + if (!Entities.ContainsKey(sceneObject.UUID)) + { + Entities.Add(sceneObject.UUID, sceneObject); + } + } + + public void RemoveEntity(SceneObjectGroup sceneObject) + { + if (Entities.ContainsKey(sceneObject.UUID)) + { + m_LandManager.removePrimFromLandPrimCounts(sceneObject); + Entities.Remove(sceneObject.UUID); + m_LandManager.setPrimsTainted(); + } + } + + /// + /// Called by a prim when it has been created/cloned, so that its events can be subscribed to + /// + /// + public void AcknowledgeNewPrim(Primitive prim) + { + prim.OnPrimCountTainted += m_LandManager.setPrimsTainted; + } + + public void LoadPrimsFromXml(string fileName) + { + XmlDocument doc = new XmlDocument(); + XmlNode rootNode; + int primCount = 0; + if (File.Exists(fileName)) + { + XmlTextReader reader = new XmlTextReader(fileName); + reader.WhitespaceHandling = WhitespaceHandling.None; + doc.Load(reader); + reader.Close(); + rootNode = doc.FirstChild; + foreach (XmlNode aPrimNode in rootNode.ChildNodes) + { + SceneObjectGroup obj = new SceneObjectGroup(this, + this.m_regionHandle, aPrimNode.OuterXml); + AddEntity(obj); + primCount++; + } + } + else + { + throw new Exception("Could not open file " + fileName + " for reading"); + } + } + + public void SavePrimsToXml(string fileName) + { + FileStream file = new FileStream(fileName, FileMode.Create); + StreamWriter stream = new StreamWriter(file); + int primCount = 0; + stream.WriteLine("\n"); + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + stream.WriteLine(((SceneObjectGroup)ent).ToXmlString()); + primCount++; + } + } + stream.WriteLine("\n"); + stream.Close(); + file.Close(); + } + + + #endregion + + #region Add/Remove Avatar Methods + + /// + /// + /// + /// + /// + public override void AddNewClient(IClientAPI client, bool child) + { + SubscribeToClientEvents(client); + m_estateManager.sendRegionHandshake(client); + CreateAndAddScenePresence(client); + m_LandManager.sendParcelOverlay(client); + commsManager.UserProfiles.AddNewUser(client.AgentId); + commsManager.TransactionsManager.AddUser(client.AgentId); + } + + protected virtual void SubscribeToClientEvents(IClientAPI client) + { + client.OnRegionHandShakeReply += SendLayerData; + //remoteClient.OnRequestWearables += new GenericCall(this.GetInitialPrims); + client.OnModifyTerrain += ModifyTerrain; + client.OnChatFromViewer += SimChat; + client.OnInstantMessage += InstantMessage; + client.OnRequestWearables += InformClientOfNeighbours; + client.OnAddPrim += AddNewPrim; + client.OnUpdatePrimGroupPosition += UpdatePrimPosition; + client.OnUpdatePrimSinglePosition += UpdatePrimSinglePosition; + client.OnUpdatePrimGroupRotation += UpdatePrimRotation; + client.OnUpdatePrimGroupMouseRotation += UpdatePrimRotation; + client.OnUpdatePrimSingleRotation += UpdatePrimSingleRotation; + client.OnUpdatePrimScale += UpdatePrimScale; + client.OnUpdateExtraParams += UpdateExtraParam; + client.OnUpdatePrimShape += UpdatePrimShape; + client.OnRequestMapBlocks += RequestMapBlocks; + client.OnUpdatePrimTexture += UpdatePrimTexture; + client.OnTeleportLocationRequest += RequestTeleportLocation; + client.OnObjectSelect += SelectPrim; + client.OnObjectDeselect += DeselectPrim; + client.OnGrabUpdate += MoveObject; + client.OnDeRezObject += DeRezObject; + client.OnRezObject += RezObject; + client.OnNameFromUUIDRequest += commsManager.HandleUUIDNameRequest; + client.OnObjectDescription += PrimDescription; + client.OnObjectName += PrimName; + client.OnLinkObjects += LinkObjects; + client.OnObjectDuplicate += DuplicateObject; + + client.OnParcelPropertiesRequest += new ParcelPropertiesRequest(m_LandManager.handleParcelPropertiesRequest); + client.OnParcelDivideRequest += new ParcelDivideRequest(m_LandManager.handleParcelDivideRequest); + client.OnParcelJoinRequest += new ParcelJoinRequest(m_LandManager.handleParcelJoinRequest); + client.OnParcelPropertiesUpdateRequest += + new ParcelPropertiesUpdateRequest(m_LandManager.handleParcelPropertiesUpdateRequest); + client.OnParcelSelectObjects += new ParcelSelectObjects(m_LandManager.handleParcelSelectObjectsRequest); + client.OnParcelObjectOwnerRequest += + new ParcelObjectOwnerRequest(m_LandManager.handleParcelObjectOwnersRequest); + + client.OnEstateOwnerMessage += new EstateOwnerMessageRequest(m_estateManager.handleEstateOwnerMessage); + + client.OnCreateNewInventoryItem += CreateNewInventoryItem; + client.OnCreateNewInventoryFolder += commsManager.UserProfiles.HandleCreateInventoryFolder; + client.OnFetchInventoryDescendents += commsManager.UserProfiles.HandleFecthInventoryDescendents; + client.OnRequestTaskInventory += RequestTaskInventory; + client.OnFetchInventory += commsManager.UserProfiles.HandleFetchInventory; + client.OnAssetUploadRequest += commsManager.TransactionsManager.HandleUDPUploadRequest; + client.OnXferReceive += commsManager.TransactionsManager.HandleXfer; + // client.OnRequestXfer += RequestXfer; + + client.OnRequestAvatarProperties += RequestAvatarProperty; + + client.OnGrabObject += ProcessObjectGrab; + } + + protected ScenePresence CreateAndAddScenePresence(IClientAPI client) + { + ScenePresence newAvatar = null; + + MainLog.Instance.Verbose("World.cs:AddViewerAgent() - Creating new avatar for remote viewer agent"); + newAvatar = new ScenePresence(client, this, m_regInfo); + MainLog.Instance.Verbose("World.cs:AddViewerAgent() - Adding new avatar to world"); + MainLog.Instance.Verbose("World.cs:AddViewerAgent() - Starting RegionHandshake "); + + PhysicsVector pVec = new PhysicsVector(newAvatar.AbsolutePosition.X, newAvatar.AbsolutePosition.Y, newAvatar.AbsolutePosition.Z); + lock (m_syncRoot) + { + newAvatar.PhysActor = phyScene.AddAvatar(pVec); + } + + lock (Entities) + { + if (!Entities.ContainsKey(client.AgentId)) + { + Entities.Add(client.AgentId, newAvatar); + } + else + { + Entities[client.AgentId] = newAvatar; + } + } + lock (Avatars) + { + if (Avatars.ContainsKey(client.AgentId)) + { + Avatars[client.AgentId] = newAvatar; + } + else + { + Avatars.Add(client.AgentId, newAvatar); + } + } + newAvatar.OnSignificantClientMovement += m_LandManager.handleSignificantClientMovement; + return newAvatar; + } + + + /// + /// + /// + /// + public override void RemoveClient(LLUUID agentID) + { + m_eventManager.TriggerOnRemovePresence(agentID); + + ScenePresence avatar = RequestAvatar(agentID); + + ForEachScenePresence( + delegate(ScenePresence presence) + { + presence.ControllingClient.SendKillObject(avatar.RegionHandle, avatar.LocalId); + }); + + lock (Avatars) + { + if (Avatars.ContainsKey(agentID)) + { + Avatars.Remove(agentID); + } + } + lock (Entities) + { + if (Entities.ContainsKey(agentID)) + { + Entities.Remove(agentID); + } + } + // TODO: Add the removal from physics ? + + // Remove client agent from profile, so new logins will work + commsManager.UserServer.clearUserAgent(agentID); + + return; + } + + #endregion + + #region Request Avatars List Methods + + //The idea is to have a group of method that return a list of avatars meeting some requirement + // ie it could be all Avatars within a certain range of the calling prim/avatar. + + /// + /// Request a List of all Avatars in this World + /// + /// + public List RequestAvatarList() + { + List result = new List(); + + foreach (ScenePresence avatar in Avatars.Values) + { + result.Add(avatar); + } + + return result; + } + + /// + /// Request a filtered list of Avatars in this World + /// + /// + public List RequestAvatarList(FilterAvatarList filter) + { + List result = new List(); + + foreach (ScenePresence avatar in Avatars.Values) + { + if (filter(avatar)) + { + result.Add(avatar); + } + } + + return result; + } + + /// + /// Request a Avatar by UUID + /// + /// + /// + public ScenePresence RequestAvatar(LLUUID avatarID) + { + if (Avatars.ContainsKey(avatarID)) + { + return Avatars[avatarID]; + } + return null; + } + + /// + /// + /// + /// + public void ForEachScenePresence(ForEachScenePresenceDelegate whatToDo) + { + foreach (ScenePresence presence in Avatars.Values) + { + whatToDo(presence); + } + } + + #endregion + + /// + /// + /// + /// + /// + public bool DeleteEntity(LLUUID entID) + { + if (Entities.ContainsKey(entID)) + { + Entities.Remove(entID); + return true; + } + return false; + } + + public void SendAllSceneObjectsToClient(IClientAPI client) + { + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + ((SceneObjectGroup)ent).SendFullUpdateToClient(client); + } + } + } + + #region RegionCommsHost + + /// + /// + /// + public void RegisterRegionWithComms() + { + regionCommsHost = commsManager.GridServer.RegisterRegion(m_regInfo); + if (regionCommsHost != null) + { + regionCommsHost.OnExpectUser += NewUserConnection; + regionCommsHost.OnAvatarCrossingIntoRegion += AgentCrossing; + } + } + + /// + /// + /// + /// + /// + public void NewUserConnection(ulong regionHandle, AgentCircuitData agent) + { + // Console.WriteLine("World.cs - add new user connection"); + //should just check that its meant for this region + if (regionHandle == m_regInfo.RegionHandle) + { + if (agent.CapsPath != "") + { + //Console.WriteLine("new user, so creating caps handler for it"); + Caps cap = + new Caps(assetCache, httpListener, m_regInfo.ExternalHostName, m_regInfo.ExternalEndPoint.Port, + agent.CapsPath, agent.AgentID); + Util.SetCapsURL(agent.AgentID, "http://" + m_regInfo.ExternalHostName + ":" + httpListener.Port.ToString() + "/CAPS/" + agent.CapsPath + "0000/"); + cap.RegisterHandlers(); + cap.AddNewInventoryItem = this.AddInventoryItem; + cap.ItemUpdatedCall = this.UpdateInventoryItemAsset; + if (capsHandlers.ContainsKey(agent.AgentID)) + { + MainLog.Instance.Warn("client", "Adding duplicate CAPS entry for user " + + agent.AgentID.ToStringHyphenated()); + capsHandlers[agent.AgentID] = cap; + } + else + { + capsHandlers.Add(agent.AgentID, cap); + } + } + authenticateHandler.AddNewCircuit(agent.circuitcode, agent); + } + } + + public void AgentCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying) + { + if (regionHandle == m_regInfo.RegionHandle) + { + if (Avatars.ContainsKey(agentID)) + { + Avatars[agentID].MakeAvatar(position, isFlying); + } + } + } + + /// + /// + /// + public void InformClientOfNeighbours(IClientAPI remoteClient) + { + List neighbours = commsManager.GridServer.RequestNeighbours(m_regInfo); + + if (neighbours != null) + { + for (int i = 0; i < neighbours.Count; i++) + { + AgentCircuitData agent = remoteClient.RequestClientInfo(); + agent.BaseFolder = LLUUID.Zero; + agent.InventoryFolder = LLUUID.Zero; + agent.startpos = new LLVector3(128, 128, 70); + agent.child = true; + commsManager.InterRegion.InformRegionOfChildAgent(neighbours[i].RegionHandle, agent); + remoteClient.InformClientOfNeighbour(neighbours[i].RegionHandle, neighbours[i].ExternalEndPoint); + //this.capsHandlers[remoteClient.AgentId].CreateEstablishAgentComms("", System.Net.IPAddress.Parse(neighbours[i].CommsIPListenAddr) + ":" + neighbours[i].CommsIPListenPort); + } + } + } + + /// + /// + /// + /// + /// + public RegionInfo RequestNeighbouringRegionInfo(ulong regionHandle) + { + return commsManager.GridServer.RequestNeighbourInfo(regionHandle); + } + + /// + /// + /// + /// + /// + /// + /// + public void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY) + { + List mapBlocks; + mapBlocks = commsManager.GridServer.RequestNeighbourMapBlocks(minX, minY, maxX, maxY); + remoteClient.SendMapBlock(mapBlocks); + } + + /// + /// + /// + /// + /// + /// + /// + /// + public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, LLVector3 position, + LLVector3 lookAt, uint flags) + { + if (regionHandle == m_regionHandle) + { + if (Avatars.ContainsKey(remoteClient.AgentId)) + { + remoteClient.SendTeleportLocationStart(); + remoteClient.SendLocalTeleport(position, lookAt, flags); + Avatars[remoteClient.AgentId].Teleport(position); + } + } + else + { + RegionInfo reg = RequestNeighbouringRegionInfo(regionHandle); + if (reg != null) + { + remoteClient.SendTeleportLocationStart(); + AgentCircuitData agent = remoteClient.RequestClientInfo(); + agent.BaseFolder = LLUUID.Zero; + agent.InventoryFolder = LLUUID.Zero; + // agent.startpos = new LLVector3(128, 128, 70); + agent.startpos = position; + agent.child = true; + commsManager.InterRegion.InformRegionOfChildAgent(regionHandle, agent); + commsManager.InterRegion.ExpectAvatarCrossing(regionHandle, remoteClient.AgentId, position, false); + + //TODO: following line is hard coded to port 9000, really need to change this as soon as possible + AgentCircuitData circuitdata = remoteClient.RequestClientInfo(); + string capsPath = Util.GetCapsURL(remoteClient.AgentId); + remoteClient.SendRegionTeleport(regionHandle, 13, reg.ExternalEndPoint, 4, (1 << 4), capsPath); + } + } + } + + /// + /// + /// + /// + /// + /// + public bool InformNeighbourOfCrossing(ulong regionhandle, LLUUID agentID, LLVector3 position, bool isFlying) + { + return commsManager.InterRegion.ExpectAvatarCrossing(regionhandle, agentID, position, isFlying); + } + + public void performParcelPrimCountUpdate() + { + m_LandManager.resetAllLandPrimCounts(); + m_eventManager.TriggerParcelPrimCountUpdate(); + m_LandManager.finalizeLandPrimCountUpdate(); + m_LandManager.landPrimCountTainted = false; + } + + #endregion + + #region Alert Methods + + void SendPermissionAlert(LLUUID user, string reason) + { + SendAlertToUser(user, reason, false); + } + + public void SendGeneralAlert(string message) + { + foreach (ScenePresence presence in this.Avatars.Values) + { + presence.ControllingClient.SendAlertMessage(message); + } + } + + public void SendAlertToUser(LLUUID agentID, string message, bool modal) + { + if (this.Avatars.ContainsKey(agentID)) + { + this.Avatars[agentID].ControllingClient.SendAgentAlertMessage(message, modal); + } + } + + public void SendAlertToUser(string firstName, string lastName, string message, bool modal) + { + foreach (ScenePresence presence in this.Avatars.Values) + { + if ((presence.Firstname == firstName) && (presence.Lastname == lastName)) + { + presence.ControllingClient.SendAgentAlertMessage(message, modal); + break; + } + } + } + + public void HandleAlertCommand(string[] commandParams) + { + if (commandParams[0] == "general") + { + string message = this.CombineParams(commandParams, 1); + this.SendGeneralAlert(message); + } + else + { + string message = this.CombineParams(commandParams, 2); + this.SendAlertToUser(commandParams[0], commandParams[1], message, false); + } + } + + private string CombineParams(string[] commandParams, int pos) + { + string result = ""; + for (int i = pos; i < commandParams.Length; i++) + { + result += commandParams[i] + " "; + } + return result; + } + #endregion + + #region Script Engine + private List ScriptEngines = new List(); + public void AddScriptEngine(OpenSim.Region.Environment.Scenes.Scripting.ScriptEngineInterface ScriptEngine, LogBase m_logger) + { + ScriptEngines.Add(ScriptEngine); + + ScriptEngine.InitializeEngine(this, m_logger); + } + #endregion + + public LLUUID ConvertLocalIDToFullID(uint localID) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(localID); + if (hasPrim != false) + { + return ((SceneObjectGroup)ent).GetPartsFullID(localID); + } + } + } + return LLUUID.Zero; + } + + public void AddInventoryItem(LLUUID userID, InventoryItemBase item) + { + if (this.Avatars.ContainsKey(userID)) + { + this.AddInventoryItem(this.Avatars[userID].ControllingClient, item); + } + } + + public void AddInventoryItem(IClientAPI remoteClient, InventoryItemBase item) + { + CachedUserInfo userInfo = commsManager.UserProfiles.GetUserDetails(remoteClient.AgentId); + if (userInfo != null) + { + userInfo.AddItem(remoteClient.AgentId, item); + remoteClient.SendInventoryItemUpdate(item); + } + } + + public LLUUID UpdateInventoryItemAsset(LLUUID userID, LLUUID itemID, byte[] data) + { + if (this.Avatars.ContainsKey(userID)) + { + return this.UpdateInventoryItemAsset(this.Avatars[userID].ControllingClient, itemID, data); + } + return LLUUID.Zero; + } + + public LLUUID UpdateInventoryItemAsset(IClientAPI remoteClient, LLUUID itemID, byte[] data) + { + CachedUserInfo userInfo = commsManager.UserProfiles.GetUserDetails(remoteClient.AgentId); + if (userInfo != null) + { + if (userInfo.RootFolder != null) + { + InventoryItemBase item = userInfo.RootFolder.HasItem(itemID); + if (item != null) + { + AssetBase asset; + asset = new AssetBase(); + asset.FullID = LLUUID.Random(); + asset.Type = (sbyte)item.assetType; + asset.InvType = (sbyte)item.invType; + asset.Name = item.inventoryName; + asset.Data = data; + this.assetCache.AddAsset(asset); + + item.assetID = asset.FullID; + userInfo.UpdateItem(remoteClient.AgentId, item); + + // remoteClient.SendInventoryItemUpdate(item); + if (item.invType == 7) + { + //do we want to know about updated note cards? + } + else if (item.invType == 10) + { + // do we want to know about updated scripts + } + + return (asset.FullID); + } + } + } + return LLUUID.Zero; + } + + } +} diff --git a/OpenSim/Region/Environment/Scenes/SceneBase.cs b/OpenSim/Region/Environment/Scenes/SceneBase.cs new file mode 100644 index 0000000000..8cce42e75e --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/SceneBase.cs @@ -0,0 +1,161 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Reflection; +using libsecondlife; +using OpenSim.Framework.Console; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Framework.Communications.Caches; +using OpenSim.Region.Terrain; +using OpenSim.Framework; + +namespace OpenSim.Region.Environment.Scenes +{ + public abstract class SceneBase : IScene + { + public Dictionary Entities; + protected ulong m_regionHandle; + protected string m_regionName; + protected RegionInfo m_regInfo; + + public TerrainEngine Terrain; + + protected EventManager m_eventManager; + + public EventManager EventManager + { + get { return m_eventManager; } + } + + public RegionInfo RegionsInfo + { + get { return m_regInfo; } + } + + protected string m_datastore; + + protected object m_syncRoot = new object(); + private uint m_nextLocalId = 8880000; + protected AssetCache assetCache; + + #region Update Methods + /// + /// Normally called once every frame/tick to let the world preform anything required (like running the physics simulation) + /// + public abstract void Update(); + + #endregion + + #region Terrain Methods + + /// + /// Loads the World heightmap + /// + public abstract void LoadWorldMap(); + + /// + /// Send the region heightmap to the client + /// + /// Client to send to + public virtual void SendLayerData(IClientAPI RemoteClient) + { + RemoteClient.SendLayerData(Terrain.GetHeights1D()); + } + + /// + /// Sends a specified patch to a client + /// + /// Patch coordinate (x) 0..16 + /// Patch coordinate (y) 0..16 + /// The client to send to + public virtual void SendLayerData(int px, int py, IClientAPI RemoteClient, float[] terrain) + { + RemoteClient.SendLayerData(px, py, terrain); + } + + #endregion + + #region Add/Remove Agent/Avatar + /// + /// + /// + /// + /// + /// + public abstract void AddNewClient(IClientAPI client, bool child); + + /// + /// + /// + /// + public abstract void RemoveClient(LLUUID agentID); + + #endregion + + /// + /// + /// + /// + public virtual RegionInfo RegionInfo + { + get { return this.m_regInfo; } + } + + public object SyncRoot + { + get { return m_syncRoot; } + } + + public uint NextLocalId + { + get { return m_nextLocalId++; } + } + + #region Shutdown + /// + /// Tidy before shutdown + /// + public virtual void Close() + { + try + { + this.EventManager.TriggerShutdown(); + } + catch (Exception e) + { + MainLog.Instance.Error("SCENE", "World.cs: Close() - Failed with exception " + e.ToString()); + } + } + + #endregion + + + } +} diff --git a/OpenSim/Region/Environment/Scenes/SceneEvents.cs b/OpenSim/Region/Environment/Scenes/SceneEvents.cs new file mode 100644 index 0000000000..313a756cbd --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/SceneEvents.cs @@ -0,0 +1,110 @@ +using libsecondlife; +using OpenSim.Framework.Interfaces; + +namespace OpenSim.Region.Environment.Scenes +{ + /// + /// A class for triggering remote scene events. + /// + public class EventManager + { + public delegate void OnFrameDelegate(); + public event OnFrameDelegate OnFrame; + + public delegate void OnBackupDelegate(Interfaces.IRegionDataStore datastore); + public event OnBackupDelegate OnBackup; + + public delegate void OnNewPresenceDelegate(ScenePresence presence); + public event OnNewPresenceDelegate OnNewPresence; + + public delegate void OnRemovePresenceDelegate(LLUUID uuid); + public event OnRemovePresenceDelegate OnRemovePresence; + + public delegate void OnParcelPrimCountUpdateDelegate(); + public event OnParcelPrimCountUpdateDelegate OnParcelPrimCountUpdate; + + public delegate void OnParcelPrimCountAddDelegate(SceneObjectGroup obj); + public event OnParcelPrimCountAddDelegate OnParcelPrimCountAdd; + + public delegate void OnScriptConsoleDelegate(string[] args); + public event OnScriptConsoleDelegate OnScriptConsole; + + public delegate void OnShutdownDelegate(); + public event OnShutdownDelegate OnShutdown; + + public delegate void ObjectGrabDelegate(uint localID, LLVector3 offsetPos, IClientAPI remoteClient); + public delegate void OnPermissionErrorDelegate(LLUUID user, string reason); + public event ObjectGrabDelegate OnObjectGrab; + public event OnPermissionErrorDelegate OnPermissionError; + + + public void TriggerPermissionError(LLUUID user, string reason) + { + if (OnPermissionError != null) + OnPermissionError(user, reason); + } + + public void TriggerOnScriptConsole(string[] args) + { + if (OnScriptConsole != null) + OnScriptConsole(args); + } + + public void TriggerOnFrame() + { + if (OnFrame != null) + { + OnFrame(); + } + } + + public void TriggerOnNewPresence(ScenePresence presence) + { + if (OnNewPresence != null) + OnNewPresence(presence); + } + + public void TriggerOnRemovePresence(LLUUID uuid) + { + if (OnRemovePresence != null) + { + OnRemovePresence(uuid); + } + } + + public void TriggerOnBackup(Interfaces.IRegionDataStore dstore) + { + if (OnBackup != null) + { + OnBackup(dstore); + } + } + + public void TriggerParcelPrimCountUpdate() + { + if (OnParcelPrimCountUpdate != null) + { + OnParcelPrimCountUpdate(); + } + } + public void TriggerParcelPrimCountAdd(SceneObjectGroup obj) + { + if (OnParcelPrimCountAdd != null) + { + OnParcelPrimCountAdd(obj); + } + } + + public void TriggerShutdown() + { + if (OnShutdown != null) + OnShutdown(); + } + + public void TriggerObjectGrab(uint localID, LLVector3 offsetPos, IClientAPI remoteClient) + { + if (OnObjectGrab != null) + OnObjectGrab(localID, offsetPos, remoteClient); + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/SceneObject(Old).cs b/OpenSim/Region/Environment/Scenes/SceneObject(Old).cs new file mode 100644 index 0000000000..cc01db3c78 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/SceneObject(Old).cs @@ -0,0 +1,319 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Collections.Generic; +using System.Text; +using System.IO; +using System.Xml; +using System.Xml.Serialization; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Physics.Manager; + +namespace OpenSim.Region.Environment.Scenes +{ + public class SceneObjectOLD : EntityBase + { + private Encoding enc = Encoding.ASCII; + private Dictionary ChildPrimitives = new Dictionary(); //list of all primitive id's that are part of this group + public Primitive rootPrimitive; + protected ulong m_regionHandle; + + private EventManager m_eventManager; + + public bool isSelected = false; + + public LLUUID rootUUID + { + get + { + this.m_uuid = this.rootPrimitive.m_uuid; + return this.m_uuid; + } + } + + public uint rootLocalID + { + get + { + this.m_localId = this.rootPrimitive.LocalId; + return this.LocalId; + } + } + + public int primCount + { + get + { + return this.ChildPrimitives.Count; + } + } + + public Dictionary Children + { + get + { + return this.ChildPrimitives; + } + } + + /// + /// + /// + public SceneObjectOLD(Scene world, EventManager eventManager, LLUUID ownerID, uint localID, LLVector3 pos, PrimitiveBaseShape shape) + { + m_regionHandle = world.RegionInfo.RegionHandle; + m_scene = world; + m_eventManager = eventManager; + + this.AbsolutePosition = pos; + this.CreateRootFromShape(ownerID, localID, shape, pos); + + registerEvents(); + } + + /// + /// + /// + /// Need a null constructor for duplication + public SceneObjectOLD() + { + + } + + public void registerEvents() + { + m_eventManager.OnBackup += new EventManager.OnBackupDelegate(ProcessBackup); + m_eventManager.OnParcelPrimCountUpdate += new EventManager.OnParcelPrimCountUpdateDelegate(ProcessParcelPrimCountUpdate); + } + + public void unregisterEvents() + { + m_eventManager.OnBackup -= new EventManager.OnBackupDelegate(ProcessBackup); + m_eventManager.OnParcelPrimCountUpdate -= new EventManager.OnParcelPrimCountUpdateDelegate(ProcessParcelPrimCountUpdate); + } + + /// + /// Processes backup + /// + /// + public void ProcessBackup(OpenSim.Region.Interfaces.IRegionDataStore datastore) + { + // datastore.StoreObject(this); + } + + /// + /// Sends my primitive info to the land manager for it to keep tally of all of the prims! + /// + private void ProcessParcelPrimCountUpdate() + { + + // m_eventManager.TriggerParcelPrimCountAdd(this); + } + + /// + /// + /// + /// + /// + /// + public void CreateRootFromShape(LLUUID agentID, uint localID, PrimitiveBaseShape shape, LLVector3 pos) + { + + // this.rootPrimitive = new Primitive(this.m_regionHandle, this.m_scene, agentID, localID, true, this, this, shape, pos); + this.m_children.Add(rootPrimitive); + + this.ChildPrimitives.Add(this.rootUUID, this.rootPrimitive); + } + + /// + /// + /// + /// + public void CreateFromBytes(byte[] data) + { + + } + + /// + /// Makes a copy of this SceneObject (and child primitives) + /// + /// A complete copy of the object + public new SceneObjectOLD Copy() + { + SceneObjectOLD dupe = new SceneObjectOLD(); + + dupe.m_scene = this.m_scene; + dupe.m_eventManager = this.m_eventManager; + dupe.m_regionHandle = this.m_regionHandle; + Primitive newRoot = this.rootPrimitive.Copy(dupe, dupe); + dupe.rootPrimitive = newRoot; + + dupe.m_children.Add(dupe.rootPrimitive); + dupe.rootPrimitive.AbsolutePosition = this.AbsolutePosition; + dupe.Rotation = this.Rotation; + dupe.LocalId = m_scene.PrimIDAllocate(); + + dupe.registerEvents(); + return dupe; + } + + /// + /// + /// + public void Serialise() + { + + } + + /// + /// + /// + public void DeleteAllChildren() + { + this.m_children.Clear(); + this.ChildPrimitives.Clear(); + this.rootPrimitive = null; + unregisterEvents(); + } + + /// + /// + /// + /// + public void AddNewChildPrims(SceneObjectOLD primObject) + { + this.rootPrimitive.AddNewChildren(primObject); + } + + public void AddChildToList(Primitive prim) + { + if (!this.ChildPrimitives.ContainsKey(prim.m_uuid)) + { + this.ChildPrimitives.Add(prim.m_uuid, prim); + } + } + /// + /// + /// + /// + /// + public Primitive HasChildPrim(LLUUID primID) + { + if (this.ChildPrimitives.ContainsKey(primID)) + { + return this.ChildPrimitives[primID]; + } + + return null; + } + + /// + /// + /// + /// + /// + public Primitive HasChildPrim(uint localID) + { + Primitive returnPrim = null; + foreach (Primitive prim in this.ChildPrimitives.Values) + { + if (prim.LocalId == localID) + { + returnPrim = prim; + break; + } + } + return returnPrim; + } + + public void SendAllChildPrimsToClient(IClientAPI client) + { + this.rootPrimitive.SendFullUpdateForAllChildren(client); + } + + /// + /// + /// + public override void BackUp() + { + + } + + /// + /// + /// + /// + /// + /// + public void GrapMovement(LLVector3 offset, LLVector3 pos, IClientAPI remoteClient) + { + this.rootPrimitive.AbsolutePosition = pos; + this.rootPrimitive.SendTerseUpdateForAllChildren(remoteClient); + } + + /// + /// + /// + /// + public void GetProperites(IClientAPI client) + { + ObjectPropertiesPacket proper = new ObjectPropertiesPacket(); + proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[1]; + proper.ObjectData[0] = new ObjectPropertiesPacket.ObjectDataBlock(); + proper.ObjectData[0].ItemID = LLUUID.Zero; + proper.ObjectData[0].CreationDate = (ulong)this.rootPrimitive.CreationDate; + proper.ObjectData[0].CreatorID = this.rootPrimitive.CreatorID; + proper.ObjectData[0].FolderID = LLUUID.Zero; + proper.ObjectData[0].FromTaskID = LLUUID.Zero; + proper.ObjectData[0].GroupID = LLUUID.Zero; + proper.ObjectData[0].InventorySerial = 0; + proper.ObjectData[0].LastOwnerID = this.rootPrimitive.LastOwnerID; + proper.ObjectData[0].ObjectID = this.rootUUID; + proper.ObjectData[0].OwnerID = this.rootPrimitive.OwnerID; + proper.ObjectData[0].TouchName = enc.GetBytes(this.rootPrimitive.TouchName + "\0"); + proper.ObjectData[0].TextureID = new byte[0]; + proper.ObjectData[0].SitName = enc.GetBytes(this.rootPrimitive.SitName + "\0"); + proper.ObjectData[0].Name = enc.GetBytes(this.rootPrimitive.Name + "\0"); + proper.ObjectData[0].Description = enc.GetBytes(this.rootPrimitive.Description + "\0"); + proper.ObjectData[0].OwnerMask = this.rootPrimitive.OwnerMask; + proper.ObjectData[0].NextOwnerMask = this.rootPrimitive.NextOwnerMask; + proper.ObjectData[0].GroupMask = this.rootPrimitive.GroupMask; + proper.ObjectData[0].EveryoneMask = this.rootPrimitive.EveryoneMask; + proper.ObjectData[0].BaseMask = this.rootPrimitive.BaseMask; + + client.OutPacket(proper); + } + + public override void SetText(string text, Axiom.Math.Vector3 color, double alpha) + { + throw new System.Exception("The method or operation is not implemented."); + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs new file mode 100644 index 0000000000..c77338d2bc --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs @@ -0,0 +1,968 @@ +using System.Collections.Generic; +using System.Text; +using System.Xml; +using System.Xml.Serialization; +using System.IO; +using System; +using Axiom.Math; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Physics.Manager; + +namespace OpenSim.Region.Environment.Scenes +{ + // public delegate void PrimCountTaintedDelegate(); + + public class SceneObjectGroup : EntityBase + { + private Encoding enc = Encoding.ASCII; + + protected SceneObjectPart m_rootPart; + protected Dictionary m_parts = new Dictionary(); + + protected ulong m_regionHandle; + + public event PrimCountTaintedDelegate OnPrimCountTainted; + + #region Properties + /// + /// + /// + public int PrimCount + { + get { return 1; } + } + + public LLQuaternion GroupRotation + { + get { return m_rootPart.RotationOffset; } + } + + /// + /// + /// + public LLVector3 GroupCentrePoint + { + get { return new LLVector3(0, 0, 0); } + } + + public Dictionary Children + { + get { return this.m_parts; } + set { m_parts = value; } + } + + public SceneObjectPart RootPart + { + set { m_rootPart = value; } + } + + public ulong RegionHandle + { + get { return m_regionHandle; } + set + { + m_regionHandle = value; + lock (this.m_parts) + { + foreach (SceneObjectPart part in this.m_parts.Values) + { + part.RegionHandle = m_regionHandle; + } + } + } + } + + public override LLVector3 AbsolutePosition + { + get { return m_rootPart.GroupPosition; } + set + { + lock (this.m_parts) + { + foreach (SceneObjectPart part in this.m_parts.Values) + { + part.GroupPosition = value; + } + } + } + } + + public override uint LocalId + { + get { return m_rootPart.LocalID; } + set { m_rootPart.LocalID = value; } + } + + public override LLUUID UUID + { + get { return m_rootPart.UUID; } + set { m_rootPart.UUID = value; } + } + + public LLUUID OwnerID + { + get { return m_rootPart.OwnerID; } + } + + public string Text + { + get { return m_rootPart.Text; } + set { m_rootPart.Text = value; } + } + + /// + /// Added because the Parcel code seems to use it + /// but not sure a object should have this + /// as what does it tell us? that some avatar has selected it (but not what Avatar/user) + /// think really there should be a list (or whatever) in each scenepresence + /// saying what prim(s) that user has selected. + /// + protected bool m_isSelected = false; + public bool IsSelected + { + get { return m_isSelected; } + set { m_isSelected = value; } + } + + #endregion + + #region Constructors + /// + /// + /// + public SceneObjectGroup() + { + + } + + /// + /// + /// + public SceneObjectGroup(Scene scene, ulong regionHandle, string xmlData) + { + m_scene = scene; + m_regionHandle = regionHandle; + + StringReader sr = new StringReader(xmlData); + XmlTextReader reader = new XmlTextReader(sr); + reader.Read(); + reader.ReadStartElement("SceneObjectGroup"); + reader.ReadStartElement("RootPart"); + this.m_rootPart = SceneObjectPart.FromXml(reader); + reader.ReadEndElement(); + + while (reader.Read()) + { + switch (reader.NodeType) + { + case XmlNodeType.Element: + if (reader.Name == "Part") + { + reader.Read(); + SceneObjectPart Part = SceneObjectPart.FromXml(reader); + Part.LocalID = m_scene.PrimIDAllocate(); + this.AddPart(Part); + Part.RegionHandle = m_regionHandle; + } + break; + case XmlNodeType.EndElement: + break; + } + } + reader.Close(); + sr.Close(); + this.m_rootPart.SetParent(this); + this.m_parts.Add(m_rootPart.UUID, m_rootPart); + this.m_rootPart.LocalID = m_scene.PrimIDAllocate(); + this.m_rootPart.ParentID = 0; + this.m_rootPart.RegionHandle = m_regionHandle; + this.UpdateParentIDs(); + m_scene.EventManager.OnBackup += this.ProcessBackup; + this.ScheduleGroupForFullUpdate(); + } + + /// + /// + /// + public SceneObjectGroup(byte[] data) + { + + } + + /// + /// + /// + public SceneObjectGroup(Scene scene, ulong regionHandle, LLUUID ownerID, uint localID, LLVector3 pos, PrimitiveBaseShape shape) + { + m_regionHandle = regionHandle; + m_scene = scene; + + // this.Pos = pos; + LLVector3 rootOffset = new LLVector3(0, 0, 0); + SceneObjectPart newPart = new SceneObjectPart(m_regionHandle, this, ownerID, localID, shape, pos, rootOffset); + this.m_parts.Add(newPart.UUID, newPart); + this.SetPartAsRoot(newPart); + m_scene.EventManager.OnBackup += this.ProcessBackup; + } + #endregion + + public string ToXmlString() + { + StringWriter sw = new StringWriter(); + XmlTextWriter writer = new XmlTextWriter(sw); + writer.WriteStartElement(String.Empty, "SceneObjectGroup", String.Empty); + writer.WriteStartElement(String.Empty, "RootPart", String.Empty); + m_rootPart.ToXml(writer); + writer.WriteEndElement(); + writer.WriteStartElement(String.Empty, "OtherParts", String.Empty); + foreach (SceneObjectPart part in this.m_parts.Values) + { + if (part.UUID != this.m_rootPart.UUID) + { + writer.WriteStartElement(String.Empty, "Part", String.Empty); + part.ToXml(writer); + writer.WriteEndElement(); + } + } + writer.WriteEndElement(); + writer.WriteEndElement(); + writer.Close(); + return sw.ToString(); + } + + #region Copying + /// + /// + /// + /// + public new SceneObjectGroup Copy() + { + SceneObjectGroup dupe = (SceneObjectGroup)this.MemberwiseClone(); + dupe.m_parts.Clear(); + dupe.AbsolutePosition = new LLVector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); + dupe.m_scene = m_scene; + dupe.m_regionHandle = this.m_regionHandle; + + dupe.CopyRootPart(this.m_rootPart); + + List partList = new List(this.m_parts.Values); + foreach (SceneObjectPart part in partList) + { + if (part.UUID != this.m_rootPart.UUID) + { + dupe.CopyPart(part); + } + } + dupe.UpdateParentIDs(); + + m_scene.EventManager.OnBackup += dupe.ProcessBackup; + return dupe; + } + + /// + /// + /// + /// + public void CopyRootPart(SceneObjectPart part) + { + SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate()); + newPart.SetParent(this); + this.m_parts.Add(newPart.UUID, newPart); + this.SetPartAsRoot(newPart); + } + + /// + /// + /// + /// + public void CopyPart(SceneObjectPart part) + { + SceneObjectPart newPart = part.Copy(m_scene.PrimIDAllocate()); + this.m_parts.Add(newPart.UUID, newPart); + this.SetPartAsNonRoot(newPart); + } + #endregion + + #region Scheduling + /// + /// + /// + public override void Update() + { + foreach (SceneObjectPart part in this.m_parts.Values) + { + part.SendScheduledUpdates(); + } + } + + /// + /// + /// + public void ScheduleGroupForFullUpdate() + { + foreach (SceneObjectPart part in this.m_parts.Values) + { + part.ScheduleFullUpdate(); + } + } + + /// + /// + /// + public void ScheduleGroupForTerseUpdate() + { + foreach (SceneObjectPart part in this.m_parts.Values) + { + part.ScheduleTerseUpdate(); + } + } + + /// + /// + /// + public void SendGroupFullUpdate() + { + foreach (SceneObjectPart part in this.m_parts.Values) + { + part.SendFullUpdateToAllClients(); + } + } + + /// + /// + /// + public void SendGroupTerseUpdate() + { + foreach (SceneObjectPart part in this.m_parts.Values) + { + part.SendTerseUpdateToAllClients(); + } + } + + #endregion + + #region SceneGroupPart Methods + /// + /// + /// + /// + /// + private SceneObjectPart GetChildPrim(LLUUID primID) + { + SceneObjectPart childPart = null; + if (this.m_parts.ContainsKey(primID)) + { + childPart = this.m_parts[primID]; + } + return childPart; + } + + /// + /// + /// + /// + /// + private SceneObjectPart GetChildPrim(uint localID) + { + foreach (SceneObjectPart part in this.m_parts.Values) + { + if (part.LocalID == localID) + { + return part; + } + } + return null; + } + + /// + /// Does this group contain the child prim + /// should be able to remove these methods once we have a entity index in scene + /// + /// + /// + public bool HasChildPrim(LLUUID primID) + { + SceneObjectPart childPart = null; + if (this.m_parts.ContainsKey(primID)) + { + childPart = this.m_parts[primID]; + return true; + } + return false; + } + + /// + /// Does this group contain the child prim + /// should be able to remove these methods once we have a entity index in scene + /// + /// + /// + public bool HasChildPrim(uint localID) + { + foreach (SceneObjectPart part in this.m_parts.Values) + { + if (part.LocalID == localID) + { + return true; + } + } + return false; + } + #endregion + + #region Packet Handlers + /// + /// + /// + /// + public void LinkToGroup(SceneObjectGroup objectGroup) + { + SceneObjectPart linkPart = objectGroup.m_rootPart; + linkPart.OffsetPosition = linkPart.GroupPosition - this.AbsolutePosition; + linkPart.GroupPosition = this.AbsolutePosition; + + Vector3 axPos = new Vector3(linkPart.OffsetPosition.X, linkPart.OffsetPosition.Y, linkPart.OffsetPosition.Z); + Quaternion parentRot = new Quaternion(this.m_rootPart.RotationOffset.W, this.m_rootPart.RotationOffset.X, this.m_rootPart.RotationOffset.Y, this.m_rootPart.RotationOffset.Z); + axPos = parentRot.Inverse() * axPos; + linkPart.OffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z); + Quaternion oldRot = new Quaternion(linkPart.RotationOffset.W, linkPart.RotationOffset.X, linkPart.RotationOffset.Y, linkPart.RotationOffset.Z); + Quaternion newRot = parentRot * oldRot; + linkPart.RotationOffset = new LLQuaternion(newRot.x, newRot.y, newRot.z, newRot.w); + linkPart.ParentID = this.m_rootPart.LocalID; + this.m_parts.Add(linkPart.UUID, linkPart); + linkPart.SetParent(this); + + //TODO: rest of parts + + m_scene.EventManager.OnBackup -= objectGroup.ProcessBackup; + m_scene.DeleteEntity(objectGroup.UUID); + this.ScheduleGroupForFullUpdate(); + } + + /// + /// + /// + /// + /// + /// + public void GrabMovement(LLVector3 offset, LLVector3 pos, IClientAPI remoteClient) + { + this.AbsolutePosition = pos; + this.m_rootPart.SendTerseUpdateToAllClients(); + } + + /// + /// + /// + /// + public void GetProperites(IClientAPI client) + { + ObjectPropertiesPacket proper = new ObjectPropertiesPacket(); + proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[1]; + proper.ObjectData[0] = new ObjectPropertiesPacket.ObjectDataBlock(); + proper.ObjectData[0].ItemID = LLUUID.Zero; + proper.ObjectData[0].CreationDate = (ulong)this.m_rootPart.CreationDate; + proper.ObjectData[0].CreatorID = this.m_rootPart.CreatorID; + proper.ObjectData[0].FolderID = LLUUID.Zero; + proper.ObjectData[0].FromTaskID = LLUUID.Zero; + proper.ObjectData[0].GroupID = LLUUID.Zero; + proper.ObjectData[0].InventorySerial = 0; + proper.ObjectData[0].LastOwnerID = this.m_rootPart.LastOwnerID; + proper.ObjectData[0].ObjectID = this.UUID; + proper.ObjectData[0].OwnerID = this.m_rootPart.OwnerID; + proper.ObjectData[0].TouchName = enc.GetBytes(this.m_rootPart.TouchName + "\0"); + proper.ObjectData[0].TextureID = new byte[0]; + proper.ObjectData[0].SitName = enc.GetBytes(this.m_rootPart.SitName + "\0"); + proper.ObjectData[0].Name = enc.GetBytes(this.m_rootPart.Name + "\0"); + proper.ObjectData[0].Description = enc.GetBytes(this.m_rootPart.Description + "\0"); + proper.ObjectData[0].OwnerMask = this.m_rootPart.OwnerMask; + proper.ObjectData[0].NextOwnerMask = this.m_rootPart.NextOwnerMask; + proper.ObjectData[0].GroupMask = this.m_rootPart.GroupMask; + proper.ObjectData[0].EveryoneMask = this.m_rootPart.EveryoneMask; + proper.ObjectData[0].BaseMask = this.m_rootPart.BaseMask; + + client.OutPacket(proper); + } + + /// + /// + /// + /// + public void SetPartName(string name, uint localID) + { + SceneObjectPart part = this.GetChildPrim(localID); + if (part != null) + { + part.Name = name; + } + } + + public void SetPartDescription(string des, uint localID) + { + SceneObjectPart part = this.GetChildPrim(localID); + if (part != null) + { + part.Description = des; + } + } + + public void SetPartText(string text, uint localID) + { + SceneObjectPart part = this.GetChildPrim(localID); + if (part != null) + { + part.Text = text; + } + } + + public void SetPartText(string text, LLUUID partID) + { + SceneObjectPart part = this.GetChildPrim(partID); + if (part != null) + { + part.Text = text; + } + } + + public string GetPartName(uint localID) + { + SceneObjectPart part = this.GetChildPrim(localID); + if (part != null) + { + return part.Name; + } + return ""; + } + + public string GetPartDescription(uint localID) + { + SceneObjectPart part = this.GetChildPrim(localID); + if (part != null) + { + return part.Description; + } + return ""; + } + + /// + /// + /// + /// + /// + public void GetPartInventoryFileName(IClientAPI remoteClient, uint localID) + { + SceneObjectPart part = this.GetChildPrim(localID); + if (part != null) + { + part.GetInventoryFileName(remoteClient, localID); + } + } + + /// + /// + /// + /// + /// + public void RequestInventoryFile(IClientAPI remoteClient, uint localID, ulong xferID) + { + SceneObjectPart part = this.GetChildPrim(localID); + if (part != null) + { + part.RequestInventoryFile(remoteClient, xferID); + } + } + + /// + /// + /// + /// + /// + /// + /// + public void UpdateExtraParam(uint localID, ushort type, bool inUse, byte[] data) + { + SceneObjectPart part = this.GetChildPrim(localID); + if (part != null) + { + part.UpdateExtraParam(type, inUse, data); + } + } + + /// + /// + /// + /// + /// + public void UpdateTextureEntry(uint localID, byte[] textureEntry) + { + SceneObjectPart part = this.GetChildPrim(localID); + if (part != null) + { + part.UpdateTextureEntry(textureEntry); + } + } + #endregion + + #region Shape + /// + /// + /// + /// + public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock, uint localID) + { + SceneObjectPart part = this.GetChildPrim(localID); + if (part != null) + { + part.UpdateShape(shapeBlock); + } + } + #endregion + + #region Resize + /// + /// + /// + /// + /// + public void Resize(LLVector3 scale, uint localID) + { + SceneObjectPart part = this.GetChildPrim(localID); + if (part != null) + { + part.Resize(scale); + } + } + #endregion + + #region Position + /// + /// + /// + /// + public void UpdateGroupPosition(LLVector3 pos) + { + this.AbsolutePosition = pos; + + } + + /// + /// + /// + /// + /// + public void UpdateSinglePosition(LLVector3 pos, uint localID) + { + SceneObjectPart part = this.GetChildPrim(localID); + if (part != null) + { + if (part.UUID == this.m_rootPart.UUID) + { + this.UpdateRootPosition(pos); + } + else + { + part.UpdateOffSet(pos); + } + } + } + + /// + /// + /// + /// + private void UpdateRootPosition(LLVector3 pos) + { + LLVector3 newPos = new LLVector3(pos.X, pos.Y, pos.Z); + LLVector3 oldPos = new LLVector3(this.AbsolutePosition.X + this.m_rootPart.OffsetPosition.X, this.AbsolutePosition.Y + this.m_rootPart.OffsetPosition.Y, this.AbsolutePosition.Z + this.m_rootPart.OffsetPosition.Z); + LLVector3 diff = oldPos - newPos; + Axiom.Math.Vector3 axDiff = new Vector3(diff.X, diff.Y, diff.Z); + Axiom.Math.Quaternion partRotation = new Quaternion(this.m_rootPart.RotationOffset.W, this.m_rootPart.RotationOffset.X, this.m_rootPart.RotationOffset.Y, this.m_rootPart.RotationOffset.Z); + axDiff = partRotation.Inverse() * axDiff; + diff.X = axDiff.x; + diff.Y = axDiff.y; + diff.Z = axDiff.z; + + foreach (SceneObjectPart obPart in this.m_parts.Values) + { + if (obPart.UUID != this.m_rootPart.UUID) + { + obPart.OffsetPosition = obPart.OffsetPosition + diff; + } + } + this.AbsolutePosition = newPos; + pos.X = newPos.X; + pos.Y = newPos.Y; + pos.Z = newPos.Z; + } + #endregion + + #region Rotation + /// + /// + /// + /// + public void UpdateGroupRotation(LLQuaternion rot) + { + this.m_rootPart.UpdateRotation(rot); + } + + /// + /// + /// + /// + /// + public void UpdateGroupRotation(LLVector3 pos, LLQuaternion rot) + { + this.m_rootPart.UpdateRotation(rot); + this.AbsolutePosition = pos; + } + + /// + /// + /// + /// + /// + public void UpdateSingleRotation(LLQuaternion rot, uint localID) + { + SceneObjectPart part = this.GetChildPrim(localID); + if (part != null) + { + if (part.UUID == this.m_rootPart.UUID) + { + this.UpdateRootRotation(rot); + } + else + { + part.UpdateRotation(rot); + } + } + } + + /// + /// + /// + /// + private void UpdateRootRotation(LLQuaternion rot) + { + this.m_rootPart.UpdateRotation(rot); + Axiom.Math.Quaternion axRot = new Quaternion(rot.W, rot.X, rot.Y, rot.Z); + Axiom.Math.Quaternion oldParentRot = new Quaternion(this.m_rootPart.RotationOffset.W, this.m_rootPart.RotationOffset.X, this.m_rootPart.RotationOffset.Y, this.m_rootPart.RotationOffset.Z); + + foreach (SceneObjectPart prim in this.m_parts.Values) + { + if (prim.UUID != this.m_rootPart.UUID) + { + Vector3 axPos = new Vector3(prim.OffsetPosition.X, prim.OffsetPosition.Y, prim.OffsetPosition.Z); + axPos = oldParentRot * axPos; + axPos = axRot.Inverse() * axPos; + prim.OffsetPosition = new LLVector3(axPos.x, axPos.y, axPos.z); + Axiom.Math.Quaternion primsRot = new Quaternion(prim.RotationOffset.W, prim.RotationOffset.X, prim.RotationOffset.Y, prim.RotationOffset.Z); + Axiom.Math.Quaternion newRot = oldParentRot * primsRot; + newRot = axRot.Inverse() * newRot; + prim.RotationOffset = new LLQuaternion(newRot.w, newRot.x, newRot.y, newRot.z); + } + } + } + #endregion + /// + /// + /// + /// + private void SetPartAsRoot(SceneObjectPart part) + { + this.m_rootPart = part; + } + + /// + /// + /// + /// + private void SetPartAsNonRoot(SceneObjectPart part) + { + part.ParentID = this.m_rootPart.LocalID; + } + + /// + /// + /// + /// + public List RequestSceneAvatars() + { + return m_scene.RequestAvatarList(); + } + + #region Events + /// + /// + /// + public void TriggerTainted() + { + if (OnPrimCountTainted != null) + { + this.OnPrimCountTainted(); + } + } + + /// + /// Processes backup + /// + /// + public void ProcessBackup(OpenSim.Region.Interfaces.IRegionDataStore datastore) + { + datastore.StoreObject(this); + } + #endregion + + #region Client Updating + public void SendFullUpdateToClient(IClientAPI remoteClient) + { + lock (this.m_parts) + { + foreach (SceneObjectPart part in this.m_parts.Values) + { + this.SendPartFullUpdate(remoteClient, part); + } + } + } + + /// + /// + /// + /// + /// + internal void SendPartFullUpdate(IClientAPI remoteClient, SceneObjectPart part) + { + if (m_rootPart == part) + { + part.SendFullUpdateToClient(remoteClient, AbsolutePosition); + } + else + { + part.SendFullUpdateToClient(remoteClient); + } + } + + /// + /// + /// + /// + /// + internal void SendPartTerseUpdate(IClientAPI remoteClient, SceneObjectPart part) + { + if (m_rootPart == part) + { + part.SendTerseUpdateToClient(remoteClient, AbsolutePosition); + } + else + { + part.SendTerseUpdateToClient(remoteClient); + } + } + #endregion + + public override void UpdateMovement() + { + foreach (SceneObjectPart part in m_parts.Values) + { + part.UpdateMovement(); + } + + base.UpdateMovement(); + } + + /// + /// Added as a way for the storage provider to reset the scene, + /// most likely a better way to do this sort of thing but for now... + /// + /// + public void SetScene(Scene scene) + { + m_scene = scene; + m_scene.EventManager.OnBackup += this.ProcessBackup; + } + + /// + /// + /// + /// + public void AddPart(SceneObjectPart part) + { + part.SetParent(this); + this.m_parts.Add(part.UUID, part); + } + + /// + /// + /// + public void UpdateParentIDs() + { + foreach (SceneObjectPart part in this.m_parts.Values) + { + if (part.UUID != this.m_rootPart.UUID) + { + part.ParentID = this.m_rootPart.LocalID; + } + } + } + + public LLUUID GetPartsFullID(uint localID) + { + SceneObjectPart part = this.GetChildPrim(localID); + if (part != null) + { + return part.UUID; + } + return null; + } + + public void UpdateText(string text) + { + m_rootPart.Text = text; + m_rootPart.ScheduleTerseUpdate(); + } + + public void ObjectGrabHandler(uint localId, LLVector3 offsetPos, IClientAPI remoteClient) + { + if (m_rootPart.LocalID == localId) + { + OnGrabGroup(offsetPos, remoteClient); + } + else + { + SceneObjectPart part = GetChildPrim(localId); + OnGrabPart(part, offsetPos, remoteClient); + } + } + + public virtual void OnGrabPart(SceneObjectPart part, LLVector3 offsetPos, IClientAPI remoteClient) + { + part.OnGrab(offsetPos, remoteClient); + } + + public virtual void OnGrabGroup(LLVector3 offsetPos, IClientAPI remoteClient) + { + + } + + public void DeleteGroup() + { + m_scene.EventManager.OnBackup -= this.ProcessBackup; + foreach (SceneObjectPart part in this.m_parts.Values) + { + List avatars = this.RequestSceneAvatars(); + for (int i = 0; i < avatars.Count; i++) + { + avatars[i].ControllingClient.SendKillObject(this.m_regionHandle, part.LocalID); + } + } + } + + public override void SetText(string text, Vector3 color, double alpha) + { + Text = text; + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs new file mode 100644 index 0000000000..7e96051648 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs @@ -0,0 +1,672 @@ +using System.Collections.Generic; +using System.Text; +using System.Xml; +using System.Xml.Serialization; +using System.IO; +using System; +using Axiom.Math; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Region.Environment.Scenes.Scripting; + +namespace OpenSim.Region.Environment.Scenes +{ + + public class SceneObjectPart : IScriptHost + { + private const uint FULL_MASK_PERMISSIONS = 2147483647; + + + public LLUUID CreatorID; + public LLUUID OwnerID; + public LLUUID GroupID; + public LLUUID LastOwnerID; + public Int32 CreationDate; + public uint ParentID = 0; + + public uint OwnerMask = FULL_MASK_PERMISSIONS; + public uint NextOwnerMask = FULL_MASK_PERMISSIONS; + public uint GroupMask = FULL_MASK_PERMISSIONS; + public uint EveryoneMask = FULL_MASK_PERMISSIONS; + public uint BaseMask = FULL_MASK_PERMISSIONS; + + protected byte[] m_particleSystem = new byte[0]; + + protected SceneObjectGroup m_parentGroup; + + /// + /// Only used internally to schedule client updates + /// + private byte m_updateFlag; + + #region Properties + + protected LLUUID m_uuid; + public LLUUID UUID + { + get { return m_uuid; } + set { m_uuid = value; } + } + + protected uint m_localID; + public uint LocalID + { + get { return m_localID; } + set { m_localID = value; } + } + + protected string m_name; + public virtual string Name + { + get { return m_name; } + set { m_name = value; } + } + + protected LLObject.ObjectFlags m_flags = (LLObject.ObjectFlags)32 + 65536 + 131072 + 256 + 4 + 8 + 268435456 + 128; + public uint ObjectFlags + { + get { return (uint)m_flags; } + set { m_flags = (LLObject.ObjectFlags)value; } + } + + protected LLObject.MaterialType m_material; + public byte Material + { + get { return (byte)m_material; } + set { m_material = (LLObject.MaterialType)value; } + } + + protected ulong m_regionHandle; + public ulong RegionHandle + { + get { return m_regionHandle; } + set { m_regionHandle = value; } + } + + //unkown if this will be kept, added as a way of removing the group position from the group class + protected LLVector3 m_groupPosition; + public LLVector3 GroupPosition + { + get { return m_groupPosition; } + set { m_groupPosition = value; } + } + + protected LLVector3 m_offsetPosition; + public LLVector3 OffsetPosition + { + get { return m_offsetPosition; } + set { m_offsetPosition = value; } + } + + public LLVector3 AbsolutePosition + { + get { return m_offsetPosition + m_groupPosition; } + } + + protected LLQuaternion m_rotationOffset; + public LLQuaternion RotationOffset + { + get { return m_rotationOffset; } + set { m_rotationOffset = value; } + } + + protected LLVector3 m_velocity; + /// + public LLVector3 Velocity + { + get { return m_velocity; } + set { m_velocity = value; } + } + + protected LLVector3 m_angularVelocity; + /// + public LLVector3 AngularVelocity + { + get { return m_angularVelocity; } + set { m_angularVelocity = value; } + } + + protected LLVector3 m_acceleration; + /// + public LLVector3 Acceleration + { + get { return m_acceleration; } + set { m_acceleration = value; } + } + + private string m_description = ""; + public string Description + { + get { return this.m_description; } + set { this.m_description = value; } + } + + private string m_text = ""; + public string Text + { + get { return m_text; } + set + { + m_text = value; + ScheduleFullUpdate(); + } + } + + private string m_sitName = ""; + public string SitName + { + get { return m_sitName; } + set { m_sitName = value; } + } + + private string m_touchName = ""; + public string TouchName + { + get { return m_touchName; } + set { m_touchName = value; } + } + + protected PrimitiveBaseShape m_shape; + public PrimitiveBaseShape Shape + { + get { return this.m_shape; } + set { m_shape = value; } + } + + public LLVector3 Scale + { + set { this.m_shape.Scale = value; } + get { return this.m_shape.Scale; } + } + #endregion + + #region Constructors + /// + /// + /// + public SceneObjectPart() + { + + } + + /// + /// Create a completely new SceneObjectPart (prim) + /// + /// + /// + /// + /// + /// + /// + public SceneObjectPart(ulong regionHandle, SceneObjectGroup parent, LLUUID ownerID, uint localID, PrimitiveBaseShape shape, LLVector3 groupPosition, LLVector3 offsetPosition) + { + this.m_name = "Primitive"; + this.m_regionHandle = regionHandle; + this.m_parentGroup = parent; + + this.CreationDate = (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; + this.OwnerID = ownerID; + this.CreatorID = this.OwnerID; + this.LastOwnerID = LLUUID.Zero; + this.UUID = LLUUID.Random(); + this.LocalID = (uint)(localID); + this.Shape = shape; + + this.GroupPosition = groupPosition; + this.OffsetPosition = offsetPosition; + this.RotationOffset = LLQuaternion.Identity; + this.Velocity = new LLVector3(0, 0, 0); + this.AngularVelocity = new LLVector3(0, 0, 0); + this.Acceleration = new LLVector3(0, 0, 0); + + + //temporary code just so the m_flags field doesn't give a compiler warning + if (m_flags == LLObject.ObjectFlags.AllowInventoryDrop) + { + + } + ScheduleFullUpdate(); + } + + /// + /// Re/create a SceneObjectPart (prim) + /// currently not used, and maybe won't be + /// + /// + /// + /// + /// + /// + /// + public SceneObjectPart(ulong regionHandle, SceneObjectGroup parent, int creationDate, LLUUID ownerID, LLUUID creatorID, LLUUID lastOwnerID, uint localID, PrimitiveBaseShape shape, LLVector3 position, LLQuaternion rotation, uint flags) + { + this.m_regionHandle = regionHandle; + this.m_parentGroup = parent; + + this.CreationDate = creationDate; + this.OwnerID = ownerID; + this.CreatorID = creatorID; + this.LastOwnerID = lastOwnerID; + this.UUID = LLUUID.Random(); + this.LocalID = (uint)(localID); + this.Shape = shape; + + this.OffsetPosition = position; + this.RotationOffset = rotation; + this.ObjectFlags = flags; + } + #endregion + + /// + /// + /// + /// + /// + public static SceneObjectPart FromXml(XmlReader xmlReader) + { + XmlSerializer serializer = new XmlSerializer(typeof(SceneObjectPart)); + return (SceneObjectPart)serializer.Deserialize(xmlReader); + } + + /// + /// + /// + /// + public void ToXml(XmlWriter xmlWriter) + { + XmlSerializer serializer = new XmlSerializer(typeof(SceneObjectPart)); + serializer.Serialize(xmlWriter, this); + } + + /// + /// + /// + public void SetParent(SceneObjectGroup parent) + { + m_parentGroup = parent; + + } + + #region Copying + /// + /// + /// + /// + public SceneObjectPart Copy(uint localID) + { + SceneObjectPart dupe = (SceneObjectPart)this.MemberwiseClone(); + dupe.m_shape = m_shape.Copy(); + dupe.m_regionHandle = m_regionHandle; + dupe.UUID = LLUUID.Random(); + dupe.LocalID = localID; + dupe.GroupPosition = new LLVector3(GroupPosition.X, GroupPosition.Y, GroupPosition.Z); + dupe.OffsetPosition = new LLVector3(OffsetPosition.X, OffsetPosition.Y, OffsetPosition.Z); + dupe.RotationOffset = new LLQuaternion(RotationOffset.X, RotationOffset.Y, RotationOffset.Z, RotationOffset.W); + dupe.Velocity = new LLVector3(0, 0, 0); + dupe.Acceleration = new LLVector3(0, 0, 0); + dupe.AngularVelocity = new LLVector3(0, 0, 0); + dupe.ObjectFlags = this.ObjectFlags; + + byte[] extraP = new byte[this.Shape.ExtraParams.Length]; + Array.Copy(this.Shape.ExtraParams, extraP, extraP.Length); + dupe.Shape.ExtraParams = extraP; + + return dupe; + } + #endregion + + #region Update Scheduling + /// + /// + /// + private void ClearUpdateSchedule() + { + m_updateFlag = 0; + } + + /// + /// + /// + public void ScheduleFullUpdate() + { + m_updateFlag = 2; + } + + /// + /// + /// + public void ScheduleTerseUpdate() + { + if (m_updateFlag < 1) + { + m_updateFlag = 1; + } + } + + /// + /// + /// + public void SendScheduledUpdates() + { + if (m_updateFlag == 1) //some change has been made so update the clients + { + SendTerseUpdateToAllClients(); + ClearUpdateSchedule(); + } + else + { + if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes + { + SendFullUpdateToAllClients(); + ClearUpdateSchedule(); + } + } + } + #endregion + + #region Shape + /// + /// + /// + /// + public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock) + { + this.m_shape.PathBegin = shapeBlock.PathBegin; + this.m_shape.PathEnd = shapeBlock.PathEnd; + this.m_shape.PathScaleX = shapeBlock.PathScaleX; + this.m_shape.PathScaleY = shapeBlock.PathScaleY; + this.m_shape.PathShearX = shapeBlock.PathShearX; + this.m_shape.PathShearY = shapeBlock.PathShearY; + this.m_shape.PathSkew = shapeBlock.PathSkew; + this.m_shape.ProfileBegin = shapeBlock.ProfileBegin; + this.m_shape.ProfileEnd = shapeBlock.ProfileEnd; + this.m_shape.PathCurve = shapeBlock.PathCurve; + this.m_shape.ProfileCurve = shapeBlock.ProfileCurve; + this.m_shape.ProfileHollow = shapeBlock.ProfileHollow; + this.m_shape.PathRadiusOffset = shapeBlock.PathRadiusOffset; + this.m_shape.PathRevolutions = shapeBlock.PathRevolutions; + this.m_shape.PathTaperX = shapeBlock.PathTaperX; + this.m_shape.PathTaperY = shapeBlock.PathTaperY; + this.m_shape.PathTwist = shapeBlock.PathTwist; + this.m_shape.PathTwistBegin = shapeBlock.PathTwistBegin; + ScheduleFullUpdate(); + } + #endregion + + #region Inventory + /// + /// + /// + /// + /// + public void GetInventoryFileName(IClientAPI client, uint localID) + { + if (localID == this.m_localID) + { + // client.SendTaskInventory(this.m_uuid, 0, Helpers.StringToField("primInventory")); + client.SendTaskInventory(this.m_uuid, 0, new byte[0]); + } + } + + /// + /// + /// + /// + /// + public void RequestInventoryFile(IClientAPI client, ulong xferID) + { + // a test item + InventoryStringBuilder invString = new InventoryStringBuilder(); + invString.AddItemStart(); + invString.AddNameValueLine("item_id", LLUUID.Random().ToStringHyphenated()); + invString.AddNameValueLine("parent_id", this.UUID.ToStringHyphenated()); + + invString.AddPermissionsStart(); + invString.AddNameValueLine("base_mask", "0x7FFFFFFF"); + invString.AddNameValueLine("owner_mask", "0x7FFFFFFF"); + invString.AddNameValueLine("group_mask", "0x7FFFFFFF"); + invString.AddNameValueLine("everyone_mask", "0x7FFFFFFF"); + invString.AddNameValueLine("next_owner_mask", "0x7FFFFFFF"); + invString.AddNameValueLine("creator_id", client.AgentId.ToStringHyphenated()); + invString.AddNameValueLine("owner_id", client.AgentId.ToStringHyphenated()); + invString.AddNameValueLine("last_owner_id", LLUUID.Zero.ToStringHyphenated()); + invString.AddNameValueLine("group_id", LLUUID.Zero.ToStringHyphenated()); + invString.AddSectionEnd(); + + invString.AddNameValueLine("asset_id", "00000000-0000-0000-9999-000000000002"); + invString.AddNameValueLine("type", "texture"); + invString.AddNameValueLine("inv_type" , "texture"); + invString.AddNameValueLine("flags", "0x00"); + invString.AddNameValueLine("name", "Test inventory" + "|"); + invString.AddNameValueLine("desc", "test description" + "|"); + invString.AddNameValueLine("creation_date", "10000"); + invString.AddSectionEnd(); + + byte[] fileInv = Helpers.StringToField(invString.BuildString); + byte[] data = new byte[fileInv.Length + 4]; + Array.Copy(fileInv, 0,data , 4, fileInv.Length); + client.SendXferPacket(xferID, 0 + 0x80000000, data); + } + #endregion + + #region ExtraParams + public void UpdateExtraParam(ushort type, bool inUse, byte[] data) + { + this.m_shape.ExtraParams = new byte[data.Length + 7]; + int i = 0; + uint length = (uint)data.Length; + this.m_shape.ExtraParams[i++] = 1; + this.m_shape.ExtraParams[i++] = (byte)(type % 256); + this.m_shape.ExtraParams[i++] = (byte)((type >> 8) % 256); + + this.m_shape.ExtraParams[i++] = (byte)(length % 256); + this.m_shape.ExtraParams[i++] = (byte)((length >> 8) % 256); + this.m_shape.ExtraParams[i++] = (byte)((length >> 16) % 256); + this.m_shape.ExtraParams[i++] = (byte)((length >> 24) % 256); + Array.Copy(data, 0, this.m_shape.ExtraParams, i, data.Length); + + this.ScheduleFullUpdate(); + + } + #endregion + + #region Texture + /// + /// + /// + /// + public void UpdateTextureEntry(byte[] textureEntry) + { + this.m_shape.TextureEntry = textureEntry; + ScheduleFullUpdate(); + } + #endregion + + #region ParticleSystem + public void AddNewParticleSystem(libsecondlife.Primitive.ParticleSystem pSystem) + { + this.m_particleSystem = pSystem.GetBytes(); + } + #endregion + + #region Position + /// + /// + /// + /// + public void UpdateOffSet(LLVector3 pos) + { + LLVector3 newPos = new LLVector3(pos.X, pos.Y, pos.Z); + this.OffsetPosition = newPos; + ScheduleTerseUpdate(); + } + #endregion + + #region rotation + public void UpdateRotation(LLQuaternion rot) + { + this.RotationOffset = new LLQuaternion(rot.X, rot.Y, rot.Z, rot.W); + ScheduleTerseUpdate(); + } + #endregion + + #region Resizing/Scale + /// + /// + /// + /// + public void Resize(LLVector3 scale) + { + this.m_shape.Scale = scale; + ScheduleFullUpdate(); + } + #endregion + + #region Client Update Methods + /// + /// + /// + public void SendFullUpdateToAllClients() + { + List avatars = this.m_parentGroup.RequestSceneAvatars(); + for (int i = 0; i < avatars.Count; i++) + { + m_parentGroup.SendPartFullUpdate(avatars[i].ControllingClient, this); + } + } + + /// + /// + /// + /// + public void SendFullUpdate(IClientAPI remoteClient) + { + m_parentGroup.SendPartFullUpdate(remoteClient, this); + } + + /// + /// + /// + /// + public void SendFullUpdateToClient(IClientAPI remoteClient) + { + LLVector3 lPos; + lPos = OffsetPosition; + SendFullUpdateToClient(remoteClient, lPos); + } + + /// + /// + /// + /// + /// + public void SendFullUpdateToClient(IClientAPI remoteClient, LLVector3 lPos) + { + LLQuaternion lRot; + lRot = RotationOffset; + + remoteClient.SendPrimitiveToClient(m_regionHandle, 64096, LocalID, m_shape, lPos, this.ObjectFlags, m_uuid, OwnerID, + m_text, ParentID, this.m_particleSystem, lRot); + } + + /// + /// + /// + public void SendTerseUpdateToAllClients() + { + List avatars = this.m_parentGroup.RequestSceneAvatars(); + for (int i = 0; i < avatars.Count; i++) + { + m_parentGroup.SendPartTerseUpdate(avatars[i].ControllingClient, this); + } + } + + /// + /// + /// + /// + public void SendTerseUpdate(IClientAPI remoteClient) + { + m_parentGroup.SendPartTerseUpdate(remoteClient, this); + } + + /// + /// + /// + /// + public void SendTerseUpdateToClient(IClientAPI remoteClient) + { + LLVector3 lPos; + lPos = this.OffsetPosition; + LLQuaternion mRot = this.RotationOffset; + remoteClient.SendPrimTerseUpdate(m_regionHandle, 64096, LocalID, lPos, mRot); + } + + /// + /// + /// + /// + /// + public void SendTerseUpdateToClient(IClientAPI remoteClient, LLVector3 lPos) + { + LLQuaternion mRot = this.RotationOffset; + remoteClient.SendPrimTerseUpdate(m_regionHandle, 64096, LocalID, lPos, mRot); + } + #endregion + + public virtual void UpdateMovement() + { + } + + public virtual void OnGrab(LLVector3 offsetPos, IClientAPI remoteClient) + { + } + + public void SetText(string text, Vector3 color, double alpha) + { + Text = text; + } + + public class InventoryStringBuilder + { + public string BuildString = ""; + + public InventoryStringBuilder() + { + + } + + public void AddItemStart() + { + BuildString += "\tinv_item\t0\n"; + BuildString += "\t{\n"; + } + + public void AddPermissionsStart() + { + BuildString += "\tpermissions 0\n"; + BuildString += "\t{\n"; + } + + public void AddSectionEnd() + { + BuildString += "\t}\n"; + } + + public void AddLine(string addLine) + { + BuildString += addLine; + } + + public void AddNameValueLine(string name, string value) + { + BuildString += "\t\t"; + BuildString += name + "\t"; + BuildString += value + "\n"; + } + } + } +} + diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.Animations.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.Animations.cs new file mode 100644 index 0000000000..d1f75ed4d1 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.Animations.cs @@ -0,0 +1,74 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Collections.Generic; +using System.Xml; +using libsecondlife; + +namespace OpenSim.Region.Environment.Scenes +{ + partial class ScenePresence + { + public class AvatarAnimations + { + + public Dictionary AnimsLLUUID = new Dictionary(); + public Dictionary AnimsNames = new Dictionary(); + + public AvatarAnimations() + { + } + + public void LoadAnims() + { + //OpenSim.Framework.Console.MainLog.Instance.Verbose("Avatar.cs:LoadAnims() - Loading avatar animations"); + XmlTextReader reader = new XmlTextReader("data/avataranimations.xml"); + + XmlDocument doc = new XmlDocument(); + doc.Load(reader); + foreach (XmlNode nod in doc.DocumentElement.ChildNodes) + { + + if (nod.Attributes["name"] != null) + { + AnimsLLUUID.Add(nod.Attributes["name"].Value, nod.InnerText); + } + + } + + reader.Close(); + + // OpenSim.Framework.Console.MainLog.Instance.Verbose("Loaded " + AnimsLLUUID.Count.ToString() + " animation(s)"); + + foreach (KeyValuePair kp in Animations.AnimsLLUUID) + { + AnimsNames.Add(kp.Value, kp.Key); + } + } + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.Body.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.Body.cs new file mode 100644 index 0000000000..dbb5d3f51b --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.Body.cs @@ -0,0 +1,85 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Interfaces; + +namespace OpenSim.Region.Environment.Scenes +{ + partial class ScenePresence + { + public class Avatar : IScenePresenceBody + { + public Avatar() + { + + } + + public void processMovement(IClientAPI remoteClient, uint flags, LLQuaternion bodyRotation) + { + } + + public void SetAppearance(byte[] texture, AgentSetAppearancePacket.VisualParamBlock[] visualParam) + { + } + + public void SendOurAppearance(IClientAPI OurClient) + { + } + + public void SendAppearanceToOtherAgent(ScenePresence avatarInfo) + { + } + } + + public class ChildAgent : IScenePresenceBody //is a ghost + { + public ChildAgent() + { + + } + + public void processMovement(IClientAPI remoteClient, uint flags, LLQuaternion bodyRotation) + { + } + + public void SetAppearance(byte[] texture, AgentSetAppearancePacket.VisualParamBlock[] visualParam) + { + } + + public void SendOurAppearance(IClientAPI OurClient) + { + } + + public void SendAppearanceToOtherAgent(ScenePresence avatarInfo) + { + } + } + } + +} diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs new file mode 100644 index 0000000000..81d14a9652 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs @@ -0,0 +1,701 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.IO; +using Axiom.Math; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework.Console; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Framework.Utilities; +using OpenSim.Physics.Manager; + +namespace OpenSim.Region.Environment.Scenes +{ + public partial class ScenePresence : Entity + { + public static bool PhysicsEngineFlying = false; + public static AvatarAnimations Animations; + public static byte[] DefaultTexture; + public IClientAPI ControllingClient; + public LLUUID current_anim; + public int anim_seq; + private bool updateflag = false; + private byte movementflag = 0; + private List forcesList = new List(); + private short _updateCount = 0; + + private Quaternion bodyRot; + private byte[] visualParams; + private AvatarWearable[] Wearables; + private LLObject.TextureEntry m_textureEntry; + + private ulong m_regionHandle; + + public bool childAgent = true; + public bool IsRestrictedToRegion = false; + + private bool newForce = false; + private bool newAvatar = false; + + protected RegionInfo m_regionInfo; + protected ulong crossingFromRegion = 0; + + private IScenePresenceBody m_body; + + private Vector3[] Dir_Vectors = new Vector3[6]; + private enum Dir_ControlFlags + { + DIR_CONTROL_FLAG_FOWARD = MainAvatar.ControlFlags.AGENT_CONTROL_AT_POS, + DIR_CONTROL_FLAG_BACK = MainAvatar.ControlFlags.AGENT_CONTROL_AT_NEG, + DIR_CONTROL_FLAG_LEFT = MainAvatar.ControlFlags.AGENT_CONTROL_LEFT_POS, + DIR_CONTROL_FLAG_RIGHT = MainAvatar.ControlFlags.AGENT_CONTROL_LEFT_NEG, + DIR_CONTROL_FLAG_UP = MainAvatar.ControlFlags.AGENT_CONTROL_UP_POS, + DIR_CONTROL_FLAG_DOWN = MainAvatar.ControlFlags.AGENT_CONTROL_UP_NEG + } + /// + /// Position at which a significant movement was made + /// + private LLVector3 posLastSignificantMove = new LLVector3(); + + public delegate void SignificantClientMovement(IClientAPI remote_client); + public event SignificantClientMovement OnSignificantClientMovement; + + #region Properties + /// + /// + /// + public PhysicsActor PhysActor + { + set + { + this._physActor = value; + } + get + { + return _physActor; + } + } + + public bool Updated + { + set + { + this.updateflag = value; + } + get + { + return this.updateflag; + } + } + + public ulong RegionHandle + { + get { return m_regionHandle; } + } + + private string m_firstname; + public string Firstname + { + get { return m_firstname; } + } + + private string m_lastname; + public string Lastname + { + get { return m_lastname; } + } + + #endregion + + #region Constructor(s) + /// + /// + /// + /// + /// + /// + /// + public ScenePresence(IClientAPI theClient, Scene world, RegionInfo reginfo) + { + + m_scene = world; + this.m_uuid = theClient.AgentId; + + m_regionInfo = reginfo; + m_regionHandle = reginfo.RegionHandle; + MainLog.Instance.Verbose("Avatar.cs "); + ControllingClient = theClient; + this.m_firstname = ControllingClient.FirstName; + this.m_lastname = ControllingClient.LastName; + m_localId = m_scene.NextLocalId; + AbsolutePosition = ControllingClient.StartPos; + + visualParams = new byte[218]; + for (int i = 0; i < 218; i++) + { + visualParams[i] = 100; + } + + Wearables = AvatarWearable.DefaultWearables; + Animations = new ScenePresence.AvatarAnimations(); + Animations.LoadAnims(); + + //register for events + ControllingClient.OnRequestWearables += this.SendOurAppearance; + ControllingClient.OnSetAppearance += new SetAppearance(this.SetAppearance); + ControllingClient.OnCompleteMovementToRegion += this.CompleteMovement; + ControllingClient.OnCompleteMovementToRegion += this.SendInitialData; + ControllingClient.OnAgentUpdate += this.HandleAgentUpdate; + // ControllingClient.OnStartAnim += new StartAnim(this.SendAnimPack); + // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); + //ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); + + Dir_Vectors[0] = new Vector3(1, 0, 0); //FOWARD + Dir_Vectors[1] = new Vector3(-1, 0, 0); //BACK + Dir_Vectors[2] = new Vector3(0, 1, 0); //LEFT + Dir_Vectors[3] = new Vector3(0, -1, 0); //RIGHT + Dir_Vectors[4] = new Vector3(0, 0, 1); //UP + Dir_Vectors[5] = new Vector3(0, 0, -1); //DOWN + + this.m_textureEntry = new LLObject.TextureEntry(DefaultTexture, 0, DefaultTexture.Length); + + //temporary until we move some code into the body classes + this.m_body = new ChildAgent(); + + } + #endregion + + #region Status Methods + /// + /// Not Used, most likely can be deleted + /// + /// + public void ChildStatusChange(bool status) + { + this.childAgent = status; + + if (this.childAgent == true) + { + this.Velocity = new LLVector3(0, 0, 0); + this.AbsolutePosition = new LLVector3(128, 128, 70); + + } + } + + /// + /// + /// + /// + public void MakeAvatar(LLVector3 pos, bool isFlying) + { + //this.childAvatar = false; + this.AbsolutePosition = pos; + this._physActor.Flying = isFlying; + this.newAvatar = true; + this.childAgent = false; + } + + protected void MakeChildAgent() + { + this.Velocity = new LLVector3(0, 0, 0); + this.childAgent = true; + //this.Pos = new LLVector3(128, 128, 70); + } + + /// + /// + /// + /// + public void Teleport(LLVector3 pos) + { + this.AbsolutePosition = pos; + this.SendTerseUpdateToALLClients(); + } + + /// + /// + /// + public void StopMovement() + { + + } + #endregion + + #region Event Handlers + /// + /// + /// + /// + /// + public void SetAppearance(byte[] texture, AgentSetAppearancePacket.VisualParamBlock[] visualParam) + { + LLObject.TextureEntry textureEnt = new LLObject.TextureEntry(texture, 0, texture.Length); + this.m_textureEntry = textureEnt; + + for (int i = 0; i < visualParam.Length; i++) + { + this.visualParams[i] = visualParam[i].ParamValue; + } + + this.SendArrearanceToAllOtherAgents(); + } + + /// + /// Complete Avatar's movement into the region + /// + public void CompleteMovement() + { + LLVector3 look = this.Velocity; + if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) + { + look = new LLVector3(0.99f, 0.042f, 0); + } + this.ControllingClient.MoveAgentIntoRegion(m_regionInfo, AbsolutePosition, look); + if (this.childAgent) + { + this.childAgent = false; + } + } + + /// + /// + /// + /// + public void HandleAgentUpdate(IClientAPI remoteClient, uint flags, LLQuaternion bodyRotation) + { + int i = 0; + bool update_movementflag = false; + bool update_rotation = false; + bool DCFlagKeyPressed = false; + Vector3 agent_control_v3 = new Vector3(0, 0, 0); + Quaternion q = new Quaternion(bodyRotation.W, bodyRotation.X, bodyRotation.Y, bodyRotation.Z); + bool oldflying = this.PhysActor.Flying; + this.PhysActor.Flying = ((flags & (uint)MainAvatar.ControlFlags.AGENT_CONTROL_FLY) != 0); + if (this.PhysActor.Flying != oldflying) + { + update_movementflag = true; + } + + if (q != this.bodyRot) + { + this.bodyRot = q; + update_rotation = true; + } + foreach (Dir_ControlFlags DCF in Enum.GetValues(typeof(Dir_ControlFlags))) + { + if ((flags & (uint)DCF) != 0) + { + DCFlagKeyPressed = true; + agent_control_v3 += Dir_Vectors[i]; + if ((movementflag & (uint)DCF) == 0) + { + movementflag += (byte)(uint)DCF; + update_movementflag = true; + } + } + else + { + if ((movementflag & (uint)DCF) != 0) + { + movementflag -= (byte)(uint)DCF; + update_movementflag = true; + + } + } + i++; + } + if ((update_movementflag) || (update_rotation && DCFlagKeyPressed)) + { + this.AddNewMovement(agent_control_v3, q); + } + UpdateMovementAnimations(update_movementflag); + + } + + protected void UpdateMovementAnimations(bool update_movementflag) + { + if (update_movementflag) + { + if (movementflag != 0) + { + if (this._physActor.Flying) + { + this.SendAnimPack(Animations.AnimsLLUUID["FLY"], 1); + } + else + { + this.SendAnimPack(Animations.AnimsLLUUID["WALK"], 1); + } + } + else + { + this.SendAnimPack(Animations.AnimsLLUUID["STAND"], 1); + } + } + + } + + + protected void AddNewMovement(Vector3 vec, Quaternion rotation) + { + NewForce newVelocity = new NewForce(); + Vector3 direc = rotation * vec; + direc.Normalize(); + + direc = direc * ((0.03f) * 128f); + if (this._physActor.Flying) + direc *= 4; + + newVelocity.X = direc.x; + newVelocity.Y = direc.y; + newVelocity.Z = direc.z; + this.forcesList.Add(newVelocity); + } + + #endregion + + #region Overridden Methods + /// + /// + /// + public override void LandRenegerated() + { + + } + + /// + /// + /// + public override void Update() + { + if (this.childAgent == false) + { + if (this.newForce) + { + this.SendTerseUpdateToALLClients(); + _updateCount = 0; + } + else if (movementflag != 0) + { + _updateCount++; + if (_updateCount > 3) + { + this.SendTerseUpdateToALLClients(); + _updateCount = 0; + } + } + + this.CheckForSignificantMovement(); + this.CheckForBorderCrossing(); + + } + } + #endregion + + #region Update Client(s) + /// + /// + /// + /// + public void SendTerseUpdateToClient(IClientAPI RemoteClient) + { + LLVector3 pos = this.AbsolutePosition; + LLVector3 vel = this.Velocity; + RemoteClient.SendAvatarTerseUpdate(this.m_regionHandle, 64096, this.LocalId, new LLVector3(pos.X, pos.Y, pos.Z), new LLVector3(vel.X, vel.Y, vel.Z)); + } + + /// + /// + /// + public void SendTerseUpdateToALLClients() + { + List avatars = this.m_scene.RequestAvatarList(); + for (int i = 0; i < avatars.Count; i++) + { + this.SendTerseUpdateToClient(avatars[i].ControllingClient); + } + } + + /// + /// + /// + /// + public void SendFullUpdateToOtherClient(ScenePresence remoteAvatar) + { + remoteAvatar.ControllingClient.SendAvatarData(m_regionInfo.RegionHandle, this.m_firstname, this.m_lastname, this.m_uuid, this.LocalId, this.AbsolutePosition, this.m_textureEntry.ToBytes()); + } + + public void SendFullUpdateToALLClients() + { + List avatars = this.m_scene.RequestAvatarList(); + foreach (ScenePresence avatar in this.m_scene.RequestAvatarList()) + { + this.SendFullUpdateToOtherClient(avatar); + if (avatar.LocalId != this.LocalId) + { + avatar.SendFullUpdateToOtherClient(this); + avatar.SendAppearanceToOtherAgent(this); + } + } + } + + /// + /// + /// + public void SendInitialData() + { + this.ControllingClient.SendAvatarData(m_regionInfo.RegionHandle, this.m_firstname, this.m_lastname, this.m_uuid, this.LocalId, this.AbsolutePosition, this.m_textureEntry.ToBytes()); + if (!this.childAgent) + { + this.m_scene.InformClientOfNeighbours(this.ControllingClient); + this.newAvatar = false; + } + + // this.SendFullUpdateToALLClients(); + // this.SendArrearanceToAllOtherAgents(); + } + + /// + /// + /// + /// + public void SendOurAppearance(IClientAPI OurClient) + { + this.ControllingClient.SendWearables(this.Wearables); + + this.SendFullUpdateToALLClients(); + this.SendArrearanceToAllOtherAgents(); + + this.m_scene.SendAllSceneObjectsToClient(this.ControllingClient); + this.ControllingClient.SendViewerTime(this.m_scene.TimePhase); + } + + /// + /// + /// + public void SendArrearanceToAllOtherAgents() + { + List avatars = this.m_scene.RequestAvatarList(); + foreach (ScenePresence avatar in this.m_scene.RequestAvatarList()) + { + this.SendAppearanceToOtherAgent(avatar); + } + } + + /// + /// + /// + /// + public void SendAppearanceToOtherAgent(ScenePresence avatarInfo) + { + avatarInfo.ControllingClient.SendAppearance(this.ControllingClient.AgentId, this.visualParams, this.m_textureEntry.ToBytes()); + } + + /// + /// + /// + /// + /// + public void SendAnimPack(LLUUID animID, int seq) + { + this.current_anim = animID; + this.anim_seq = seq; + List avatars = this.m_scene.RequestAvatarList(); + for (int i = 0; i < avatars.Count; i++) + { + avatars[i].ControllingClient.SendAnimation(animID, seq, this.ControllingClient.AgentId); + } + } + + /// + /// + /// + public void SendAnimPack() + { + this.SendAnimPack(this.current_anim, this.anim_seq); + } + #endregion + + #region Significant Movement Method + + protected void CheckForSignificantMovement() + { + if (libsecondlife.Helpers.VecDist(this.AbsolutePosition, this.posLastSignificantMove) > 2.0) + { + this.posLastSignificantMove = this.AbsolutePosition; + if (OnSignificantClientMovement != null) + { + OnSignificantClientMovement(this.ControllingClient); + } + } + } + #endregion + + #region Border Crossing Methods + /// + /// + /// + protected void CheckForBorderCrossing() + { + LLVector3 pos2 = this.AbsolutePosition; + LLVector3 vel = this.Velocity; + + float timeStep = 0.1f; + pos2.X = pos2.X + (vel.X * timeStep); + pos2.Y = pos2.Y + (vel.Y * timeStep); + pos2.Z = pos2.Z + (vel.Z * timeStep); + + if ((pos2.X < 0) || (pos2.X > 256)) + { + this.CrossToNewRegion(); + } + + if ((pos2.Y < 0) || (pos2.Y > 256)) + { + this.CrossToNewRegion(); + } + } + + /// + /// + /// + protected void CrossToNewRegion() + { + LLVector3 pos = this.AbsolutePosition; + LLVector3 newpos = new LLVector3(pos.X, pos.Y, pos.Z); + uint neighbourx = this.m_regionInfo.RegionLocX; + uint neighboury = this.m_regionInfo.RegionLocY; + + if (pos.X < 1.7F) + { + neighbourx -= 1; + newpos.X = 255.9F; + } + if (pos.X > 254.3F) + { + neighbourx += 1; + newpos.X = 0.1F; + } + if (pos.Y < 1.7F) + { + neighboury -= 1; + newpos.Y = 255.9F; + } + if (pos.Y > 254.3F) + { + neighboury += 1; + newpos.Y = 0.1F; + } + + LLVector3 vel = this.m_velocity; + ulong neighbourHandle = Helpers.UIntsToLong((uint)(neighbourx * 256), (uint)(neighboury * 256)); + RegionInfo neighbourRegion = this.m_scene.RequestNeighbouringRegionInfo(neighbourHandle); + if (neighbourRegion != null) + { + bool res = this.m_scene.InformNeighbourOfCrossing(neighbourHandle, this.ControllingClient.AgentId, newpos, this._physActor.Flying); + if (res) + { + //TODO: following line is hard coded to port 9000, really need to change this as soon as possible + AgentCircuitData circuitdata = this.ControllingClient.RequestClientInfo(); + string capsPath = Util.GetCapsURL(this.ControllingClient.AgentId); + this.ControllingClient.CrossRegion(neighbourHandle, newpos, vel, neighbourRegion.ExternalEndPoint, capsPath); + this.MakeChildAgent(); + } + } + } + #endregion + + /// + /// + /// + public static void LoadAnims() + { + + } + + /// + /// + /// + public override void UpdateMovement() + { + newForce = false; + lock (this.forcesList) + { + if (this.forcesList.Count > 0) + { + for (int i = 0; i < this.forcesList.Count; i++) + { + NewForce force = this.forcesList[i]; + + this.updateflag = true; + this.Velocity = new LLVector3(force.X, force.Y, force.Z); + this.newForce = true; + } + for (int i = 0; i < this.forcesList.Count; i++) + { + this.forcesList.RemoveAt(0); + } + } + } + } + + public static void CreateDefaultTextureEntry() + { + LLObject.TextureEntry textu = new LLObject.TextureEntry(new LLUUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97")); + textu.CreateFace(0).TextureID = new LLUUID("00000000-0000-1111-9999-000000000012"); + textu.CreateFace(1).TextureID = new LLUUID("5748decc-f629-461c-9a36-a35a221fe21f"); + textu.CreateFace(2).TextureID = new LLUUID("5748decc-f629-461c-9a36-a35a221fe21f"); + textu.CreateFace(3).TextureID = new LLUUID("6522E74D-1660-4E7F-B601-6F48C1659A77"); + textu.CreateFace(4).TextureID = new LLUUID("7CA39B4C-BD19-4699-AFF7-F93FD03D3E7B"); + textu.CreateFace(5).TextureID = new LLUUID("00000000-0000-1111-9999-000000000010"); + textu.CreateFace(6).TextureID = new LLUUID("00000000-0000-1111-9999-000000000011"); + DefaultTexture = textu.ToBytes(); + } + + public class NewForce + { + public float X; + public float Y; + public float Z; + + public NewForce() + { + + } + } + + public override void SetText(string text, Vector3 color, double alpha) + { + throw new Exception("The method or operation is not implemented."); + } + } + +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/CSharpEngine/CSharpScriptEngine.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/CSharpEngine/CSharpScriptEngine.cs new file mode 100644 index 0000000000..40873d7e9f --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/CSharpEngine/CSharpScriptEngine.cs @@ -0,0 +1,102 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.CodeDom.Compiler; +using System.Collections.Generic; +using Microsoft.CSharp; +using OpenSim.Framework.Console; + +namespace OpenSim.Region.Scripting +{ + public class CSharpScriptEngine : IScriptCompiler + { + public string FileExt() + { + return ".cs"; + } + + private Dictionary LoadDotNetScript(CodeDomProvider compiler, string filename) + { + CompilerParameters compilerParams = new CompilerParameters(); + CompilerResults compilerResults; + compilerParams.GenerateExecutable = false; + compilerParams.GenerateInMemory = true; + compilerParams.IncludeDebugInformation = false; + compilerParams.ReferencedAssemblies.Add("OpenSim.Region.dll"); + compilerParams.ReferencedAssemblies.Add("OpenSim.Region.Environment.dll"); + compilerParams.ReferencedAssemblies.Add("OpenSim.Framework.dll"); + compilerParams.ReferencedAssemblies.Add("libsecondlife.dll"); + compilerParams.ReferencedAssemblies.Add("System.dll"); + + compilerResults = compiler.CompileAssemblyFromFile(compilerParams, filename); + + if (compilerResults.Errors.Count > 0) + { + MainLog.Instance.Error("Compile errors"); + foreach (CompilerError error in compilerResults.Errors) + { + MainLog.Instance.Error(error.Line.ToString() + ": " + error.ErrorText.ToString()); + } + } + else + { + Dictionary scripts = new Dictionary(); + + foreach (Type pluginType in compilerResults.CompiledAssembly.GetExportedTypes()) + { + Type testInterface = pluginType.GetInterface("IScript", true); + + if (testInterface != null) + { + IScript script = (IScript)compilerResults.CompiledAssembly.CreateInstance(pluginType.ToString()); + + string scriptName = "C#/" + script.Name; + Console.WriteLine("Script: " + scriptName + " loaded."); + + if (!scripts.ContainsKey(scriptName)) + { + scripts.Add(scriptName, script); + } + else + { + scripts[scriptName] = script; + } + } + } + return scripts; + } + return null; + } + + public Dictionary compile(string filename) + { + CSharpCodeProvider csharpProvider = new CSharpCodeProvider(); + return LoadDotNetScript(csharpProvider, filename); + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/CSharpEngine/Examples/ExportRegionToLSL.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/CSharpEngine/Examples/ExportRegionToLSL.cs new file mode 100644 index 0000000000..402e32d159 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/CSharpEngine/Examples/ExportRegionToLSL.cs @@ -0,0 +1,72 @@ +using OpenSim.Framework.Console; +using OpenSim.Framework; +using OpenSim.Region.Environment; +using OpenSim.Region.Environment.Scenes; + +using System.Collections.Generic; +using libsecondlife; + +namespace OpenSim.Region.Scripting.Examples +{ + public class LSLExportScript : IScript + { + ScriptInfo script; + + public string Name + { + get { return "LSL Export Script 0.1"; } + } + + public void Initialise(ScriptInfo scriptInfo) + { + script = scriptInfo; + + script.events.OnScriptConsole += new EventManager.OnScriptConsoleDelegate(ProcessConsoleMsg); + } + + void ProcessConsoleMsg(string[] args) + { + /*if (args[0].ToLower() == "lslexport") + { + string sequence = ""; + + foreach (KeyValuePair obj in script.world.Objects) + { + SceneObject root = obj.Value; + + sequence += "NEWOBJ::" + obj.Key.ToStringHyphenated() + "\n"; + + string rootPrim = processPrimitiveToString(root.rootPrimitive); + + sequence += "ROOT:" + rootPrim; + + foreach (KeyValuePair prim in root.Children) + { + string child = processPrimitiveToString(prim.Value); + sequence += "CHILD:" + child; + } + } + + System.Console.WriteLine(sequence); + }*/ + } + + string processPrimitiveToString(OpenSim.Region.Environment.Scenes.Primitive prim) + { + /*string desc = prim.Description; + string name = prim.Name; + LLVector3 pos = prim.Pos; + LLQuaternion rot = new LLQuaternion(prim.Rotation.x, prim.Rotation.y, prim.Rotation.z, prim.Rotation.w); + LLVector3 scale = prim.Scale; + LLVector3 rootPos = prim.WorldPos; + + string setPrimParams = ""; + + setPrimParams += "[PRIM_SCALE, " + scale.ToString() + ", PRIM_POS, " + rootPos.ToString() + ", PRIM_ROTATION, " + rot.ToString() + "]\n"; + + return setPrimParams; + */ + return ""; + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JScriptEngine/JScriptEngine.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JScriptEngine/JScriptEngine.cs new file mode 100644 index 0000000000..f8d5bfa20d --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JScriptEngine/JScriptEngine.cs @@ -0,0 +1,102 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.CodeDom.Compiler; +using System.Collections.Generic; +using Microsoft.JScript; +using OpenSim.Framework.Console; + +namespace OpenSim.Region.Scripting +{ + public class JScriptEngine : IScriptCompiler + { + public string FileExt() + { + return ".js"; + } + + private Dictionary LoadDotNetScript(CodeDomProvider compiler, string filename) + { + CompilerParameters compilerParams = new CompilerParameters(); + CompilerResults compilerResults; + compilerParams.GenerateExecutable = false; + compilerParams.GenerateInMemory = true; + compilerParams.IncludeDebugInformation = false; + compilerParams.ReferencedAssemblies.Add("OpenSim.Region.dll"); + compilerParams.ReferencedAssemblies.Add("OpenSim.Region.Environment.dll"); + compilerParams.ReferencedAssemblies.Add("OpenSim.Framework.dll"); + compilerParams.ReferencedAssemblies.Add("libsecondlife.dll"); + compilerParams.ReferencedAssemblies.Add("System.dll"); + + compilerResults = compiler.CompileAssemblyFromFile(compilerParams, filename); + + if (compilerResults.Errors.Count > 0) + { + MainLog.Instance.Error("Compile errors"); + foreach (CompilerError error in compilerResults.Errors) + { + MainLog.Instance.Error(error.Line.ToString() + ": " + error.ErrorText.ToString()); + } + } + else + { + Dictionary scripts = new Dictionary(); + + foreach (Type pluginType in compilerResults.CompiledAssembly.GetExportedTypes()) + { + Type testInterface = pluginType.GetInterface("IScript", true); + + if (testInterface != null) + { + IScript script = (IScript)compilerResults.CompiledAssembly.CreateInstance(pluginType.ToString()); + + string scriptName = "JS.NET/" + script.Name; + Console.WriteLine("Script: " + scriptName + " loaded."); + + if (!scripts.ContainsKey(scriptName)) + { + scripts.Add(scriptName, script); + } + else + { + scripts[scriptName] = script; + } + } + } + return scripts; + } + return null; + } + + public Dictionary compile(string filename) + { + JScriptCodeProvider jscriptProvider = new JScriptCodeProvider(); + return LoadDotNetScript(jscriptProvider, filename); + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/ClassInstance.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/ClassInstance.cs new file mode 100644 index 0000000000..ebec1321be --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/ClassInstance.cs @@ -0,0 +1,46 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; +using OpenSim.Region.Scripting.EmbeddedJVM.Types; + +namespace OpenSim.Region.Scripting.EmbeddedJVM +{ + public class ClassInstance : Object + { + public int Size; + public ClassRecord ClassRec; + public Dictionary Fields = new Dictionary(); + + public ClassInstance() + { + + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/ClassRecord.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/ClassRecord.cs new file mode 100644 index 0000000000..b7bb8a7ee2 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/ClassRecord.cs @@ -0,0 +1,640 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.IO; +using System.Collections.Generic; +using System.Text; +using OpenSim.Region.Scripting.EmbeddedJVM.Types; +using OpenSim.Region.Scripting.EmbeddedJVM.Types.PrimitiveTypes; + +namespace OpenSim.Region.Scripting.EmbeddedJVM +{ + public class ClassRecord + { + private ushort m_majorVersion; + private ushort m_minorVersion; + private ushort m_constantPoolCount; + private ushort m_accessFlags; + private ushort m_thisClass; + private ushort m_supperClass; + private ushort m_interfaceCount; + private ushort m_fieldCount; + private ushort m_methodCount; + //private ushort _attributeCount; + //private string _name; + public Dictionary StaticFields = new Dictionary(); + public PoolClass MClass; + + public List m_constantsPool = new List(); + private List m_methodsList = new List(); + private List m_fieldList = new List(); + + public ClassRecord() + { + + } + + public ClassInstance CreateNewInstance() + { + ClassInstance classInst = new ClassInstance(); + classInst.ClassRec = this; + //TODO: set fields + + return classInst; + } + + public void LoadClassFromFile(string fileName) + { + Console.WriteLine("loading script " + fileName); + FileStream fs = File.OpenRead(fileName); + this.LoadClassFromBytes(ReadFully(fs)); + fs.Close(); + } + + public void LoadClassFromBytes(byte[] data) + { + int i = 0; + i += 4; + m_minorVersion = (ushort)((data[i++] << 8) + data[i++]); + m_majorVersion = (ushort)((data[i++] << 8) + data[i++]); + m_constantPoolCount = (ushort)((data[i++] << 8) + data[i++]); + Console.WriteLine("there should be " + m_constantPoolCount + " items in the pool"); + for (int count = 0; count < (m_constantPoolCount - 1); count++) + { + //read in the constant pool + byte pooltype = data[i++]; + Console.WriteLine("#" + count + ": new constant type = " + pooltype); + //Console.WriteLine("start position is: " + i); + switch (pooltype) + { + case 1: //Utf8 + ushort uLength = (ushort)((data[i++] << 8) + data[i++]); + + // Console.WriteLine("new utf8 type, length is " + uLength); + PoolUtf8 utf8 = new PoolUtf8(); + utf8.readValue(data, ref i, uLength); + this.m_constantsPool.Add(utf8); + break; + case 3: //Int + break; + case 4: //Float + break; + case 7: //Class + PoolClass pClass = new PoolClass(this); + pClass.readValue(data, ref i); + this.m_constantsPool.Add(pClass); + break; + case 9: //FieldRef + PoolFieldRef pField = new PoolFieldRef(this); + pField.readValue(data, ref i); + this.m_constantsPool.Add(pField); + break; + case 10: //Method + PoolMethodRef pMeth = new PoolMethodRef(this); + pMeth.readValue(data, ref i); + this.m_constantsPool.Add(pMeth); + break; + case 12: //NamedType + PoolNamedType pNamed = new PoolNamedType(this); + pNamed.readValue(data, ref i); + this.m_constantsPool.Add(pNamed); + break; + } + } + + m_accessFlags = (ushort)((data[i++] << 8) + data[i++]); + m_thisClass = (ushort)((data[i++] << 8) + data[i++]); + m_supperClass = (ushort)((data[i++] << 8) + data[i++]); + + if (this.m_constantsPool[this.m_thisClass - 1] is PoolClass) + { + this.MClass = ((PoolClass)this.m_constantsPool[this.m_thisClass - 1]); + } + + m_interfaceCount = (ushort)((data[i++] << 8) + data[i++]); + //should now read in the info for each interface + + m_fieldCount = (ushort)((data[i++] << 8) + data[i++]); + //should now read in the info for each field + for (int count = 0; count < m_fieldCount; count++) + { + FieldInfo fieldInf = new FieldInfo(this); + fieldInf.ReadData(data, ref i); + this.m_fieldList.Add(fieldInf); + } + + m_methodCount = (ushort)((data[i++] << 8) + data[i++]); + for (int count = 0; count < m_methodCount; count++) + { + MethodInfo methInf = new MethodInfo(this); + methInf.ReadData(data, ref i); + this.m_methodsList.Add(methInf); + } + } + + public void AddMethodsToMemory(MethodMemory memory) + { + for (int count = 0; count < m_methodCount; count++) + { + this.m_methodsList[count].AddMethodCode(memory); + } + } + + public bool StartMethod(Thread thread, string methodName) + { + for (int count = 0; count < m_methodCount; count++) + { + if (this.m_constantsPool[this.m_methodsList[count].NameIndex - 1] is PoolUtf8) + { + if (((PoolUtf8)this.m_constantsPool[this.m_methodsList[count].NameIndex - 1]).Value == methodName) + { + //Console.WriteLine("found method: " + ((PoolUtf8)this._constantsPool[this._methodsList[count].NameIndex - 1]).Value); + thread.SetPC(this.m_methodsList[count].CodePointer); + return true; + } + } + } + return false; + } + + public void PrintToConsole() + { + Console.WriteLine("Class File:"); + Console.WriteLine("Major version: " + m_majorVersion); + Console.WriteLine("Minor version: " + m_minorVersion); + Console.WriteLine("Pool size: " + m_constantPoolCount); + + for (int i = 0; i < m_constantsPool.Count; i++) + { + this.m_constantsPool[i].Print(); + } + + Console.WriteLine("Access flags: " + m_accessFlags); + Console.WriteLine("This class: " + m_thisClass); + Console.WriteLine("Super class: " + m_supperClass); + + for (int count = 0; count < m_fieldCount; count++) + { + Console.WriteLine(); + this.m_fieldList[count].Print(); + } + + for (int count = 0; count < m_methodCount; count++) + { + Console.WriteLine(); + this.m_methodsList[count].Print(); + } + + Console.WriteLine("class name is " + this.MClass.Name.Value); + } + + public static byte[] ReadFully(Stream stream) + { + byte[] buffer = new byte[1024]; + using (MemoryStream ms = new MemoryStream()) + { + while (true) + { + int read = stream.Read(buffer, 0, buffer.Length); + if (read <= 0) + return ms.ToArray(); + ms.Write(buffer, 0, read); + } + } + } + + #region nested classes + public class PoolItem + { + public virtual void Print() + { + + } + } + + public class PoolUtf8 : PoolItem + { + public string Value = ""; + + public void readValue(byte[] data, ref int pointer, int length) + { + for (int i = 0; i < length; i++) + { + int a = (int)data[pointer++]; + if ((a & 0x80) == 0) + { + Value = Value + (char)a; + } + else if ((a & 0x20) == 0) + { + int b = (int)data[pointer++]; + Value = Value + (char)(((a & 0x1f) << 6) + (b & 0x3f)); + } + else + { + int b = (int)data[pointer++]; + int c = (int)data[pointer++]; + Value = Value + (char)(((a & 0xf) << 12) + ((b & 0x3f) << 6) + (c & 0x3f)); + } + } + } + + public override void Print() + { + Console.WriteLine("Utf8 type: " + Value); + } + } + + private class PoolInt : PoolItem + { + + } + + public class PoolClass : PoolItem + { + //public string name = ""; + public ushort namePointer = 0; + private ClassRecord parent; + public PoolUtf8 Name; + + public PoolClass(ClassRecord paren) + { + parent = paren; + } + + public void readValue(byte[] data, ref int pointer) + { + namePointer = (ushort)((data[pointer++] << 8) + data[pointer++]); + } + + public override void Print() + { + this.Name = ((PoolUtf8)this.parent.m_constantsPool[namePointer - 1]); + Console.Write("Class type: " + namePointer); + Console.WriteLine(" // " + ((PoolUtf8)this.parent.m_constantsPool[namePointer - 1]).Value); + + } + } + + public class PoolFieldRef : PoolItem + { + public ushort classPointer = 0; + public ushort nameTypePointer = 0; + public PoolNamedType mNameType; + public PoolClass mClass; + private ClassRecord parent; + + public PoolFieldRef(ClassRecord paren) + { + parent = paren; + } + + public void readValue(byte[] data, ref int pointer) + { + classPointer = (ushort)((data[pointer++] << 8) + data[pointer++]); + nameTypePointer = (ushort)((data[pointer++] << 8) + data[pointer++]); + } + + public override void Print() + { + this.mNameType = ((PoolNamedType)this.parent.m_constantsPool[nameTypePointer - 1]); + this.mClass = ((PoolClass)this.parent.m_constantsPool[classPointer - 1]); + Console.WriteLine("FieldRef type: " + classPointer + " , " + nameTypePointer); + } + } + + public class PoolMethodRef : PoolItem + { + public ushort classPointer = 0; + public ushort nameTypePointer = 0; + public PoolNamedType mNameType; + public PoolClass mClass; + private ClassRecord parent; + + public PoolMethodRef(ClassRecord paren) + { + parent = paren; + } + + public void readValue(byte[] data, ref int pointer) + { + classPointer = (ushort)((data[pointer++] << 8) + data[pointer++]); + nameTypePointer = (ushort)((data[pointer++] << 8) + data[pointer++]); + } + + public override void Print() + { + this.mNameType = ((PoolNamedType)this.parent.m_constantsPool[nameTypePointer - 1]); + this.mClass = ((PoolClass)this.parent.m_constantsPool[classPointer - 1]); + Console.WriteLine("MethodRef type: " + classPointer + " , " + nameTypePointer); + } + } + + public class PoolNamedType : PoolItem + { + public ushort namePointer = 0; + public ushort typePointer = 0; + private ClassRecord parent; + public PoolUtf8 Name; + public PoolUtf8 Type; + + public PoolNamedType(ClassRecord paren) + { + parent = paren; + } + + public void readValue(byte[] data, ref int pointer) + { + namePointer = (ushort)((data[pointer++] << 8) + data[pointer++]); + typePointer = (ushort)((data[pointer++] << 8) + data[pointer++]); + } + + public override void Print() + { + Name = ((PoolUtf8)this.parent.m_constantsPool[namePointer - 1]); + Type = ((PoolUtf8)this.parent.m_constantsPool[typePointer - 1]); + Console.Write("Named type: " + namePointer + " , " + typePointer); + Console.WriteLine(" // " + ((PoolUtf8)this.parent.m_constantsPool[namePointer - 1]).Value); + } + } + + //*********************** + public class MethodInfo + { + public ushort AccessFlags = 0; + public ushort NameIndex = 0; + public string Name = ""; + public ushort DescriptorIndex = 0; + public ushort AttributeCount = 0; + public List Attributes = new List(); + private ClassRecord parent; + public int CodePointer = 0; + + public MethodInfo(ClassRecord paren) + { + parent = paren; + } + + public void AddMethodCode(MethodMemory memory) + { + Array.Copy(this.Attributes[0].Code, 0, memory.MethodBuffer, memory.NextMethodPC, this.Attributes[0].Code.Length); + memory.Methodcount++; + this.CodePointer = memory.NextMethodPC; + memory.NextMethodPC += this.Attributes[0].Code.Length; + } + + public void ReadData(byte[] data, ref int pointer) + { + AccessFlags = (ushort)((data[pointer++] << 8) + data[pointer++]); + NameIndex = (ushort)((data[pointer++] << 8) + data[pointer++]); + DescriptorIndex = (ushort)((data[pointer++] << 8) + data[pointer++]); + AttributeCount = (ushort)((data[pointer++] << 8) + data[pointer++]); + for (int i = 0; i < AttributeCount; i++) + { + MethodAttribute attri = new MethodAttribute(this.parent); + attri.ReadData(data, ref pointer); + this.Attributes.Add(attri); + } + } + + public void Print() + { + Console.WriteLine("Method Info Struct: "); + Console.WriteLine("AccessFlags: " + AccessFlags); + Console.WriteLine("NameIndex: " + NameIndex + " // " + ((PoolUtf8)this.parent.m_constantsPool[NameIndex - 1]).Value); + Console.WriteLine("DescriptorIndex: " + DescriptorIndex + " // " + ((PoolUtf8)this.parent.m_constantsPool[DescriptorIndex - 1]).Value); + Console.WriteLine("Attribute Count:" + AttributeCount); + for (int i = 0; i < AttributeCount; i++) + { + this.Attributes[i].Print(); + } + } + + public class MethodAttribute + { + public ushort NameIndex = 0; + public string Name = ""; + public Int32 Length = 0; + //for now only support code attribute + public ushort MaxStack = 0; + public ushort MaxLocals = 0; + public Int32 CodeLength = 0; + public byte[] Code; + public ushort ExceptionTableLength = 0; + public ushort SubAttributeCount = 0; + public List SubAttributes = new List(); + private ClassRecord parent; + + public MethodAttribute(ClassRecord paren) + { + parent = paren; + } + + public void ReadData(byte[] data, ref int pointer) + { + NameIndex = (ushort)((data[pointer++] << 8) + data[pointer++]); + Length = (Int32)((data[pointer++] << 24) + (data[pointer++] << 16) + (data[pointer++] << 8) + data[pointer++]); + MaxStack = (ushort)((data[pointer++] << 8) + data[pointer++]); + MaxLocals = (ushort)((data[pointer++] << 8) + data[pointer++]); + CodeLength = (Int32)((data[pointer++] << 24) + (data[pointer++] << 16) + (data[pointer++] << 8) + data[pointer++]); + Code = new byte[CodeLength]; + for (int i = 0; i < CodeLength; i++) + { + Code[i] = data[pointer++]; + } + ExceptionTableLength = (ushort)((data[pointer++] << 8) + data[pointer++]); + SubAttributeCount = (ushort)((data[pointer++] << 8) + data[pointer++]); + for (int i = 0; i < SubAttributeCount; i++) + { + SubAttribute subAttri = new SubAttribute(this.parent); + subAttri.ReadData(data, ref pointer); + this.SubAttributes.Add(subAttri); + } + } + + public void Print() + { + Console.WriteLine("Method Attribute: "); + Console.WriteLine("Name Index: " + NameIndex + " // " + ((PoolUtf8)this.parent.m_constantsPool[NameIndex - 1]).Value); + Console.WriteLine("Length: " + Length); + Console.WriteLine("MaxStack: " + MaxStack); + Console.WriteLine("MaxLocals: " + MaxLocals); + Console.WriteLine("CodeLength: " + CodeLength); + for (int i = 0; i < Code.Length; i++) + { + Console.WriteLine("OpCode #" + i + " is: " + Code[i]); + } + Console.WriteLine("SubAttributes: " + SubAttributeCount); + for (int i = 0; i < SubAttributeCount; i++) + { + this.SubAttributes[i].Print(); + } + } + + public class SubAttribute + { + public ushort NameIndex = 0; + public string Name = ""; + public Int32 Length = 0; + public byte[] Data; + private ClassRecord parent; + + public SubAttribute(ClassRecord paren) + { + parent = paren; + } + + public void ReadData(byte[] data, ref int pointer) + { + NameIndex = (ushort)((data[pointer++] << 8) + data[pointer++]); + Length = (Int32)((data[pointer++] << 24) + (data[pointer++] << 16) + (data[pointer++] << 8) + data[pointer++]); + Data = new byte[Length]; + for (int i = 0; i < Length; i++) + { + Data[i] = data[pointer++]; + } + } + + public void Print() + { + Console.WriteLine("SubAttribute: NameIndex: " + NameIndex + " // " + ((PoolUtf8)this.parent.m_constantsPool[NameIndex - 1]).Value); + } + + } + } + + } + private class InterfaceInfo + { + public void ReadData(byte[] data, ref int i) + { + + } + } + + public class FieldInfo + { + public ushort AccessFlags = 0; + public ushort NameIndex = 0; + public string Name = ""; + public ushort DescriptorIndex = 0; + public ushort AttributeCount = 0; + public List Attributes = new List(); + private ClassRecord parent; + + public FieldInfo(ClassRecord paren) + { + parent = paren; + } + + public void ReadData(byte[] data, ref int pointer) + { + AccessFlags = (ushort)((data[pointer++] << 8) + data[pointer++]); + NameIndex = (ushort)((data[pointer++] << 8) + data[pointer++]); + DescriptorIndex = (ushort)((data[pointer++] << 8) + data[pointer++]); + AttributeCount = (ushort)((data[pointer++] << 8) + data[pointer++]); + for (int i = 0; i < AttributeCount; i++) + { + FieldAttribute attri = new FieldAttribute(this.parent); + attri.ReadData(data, ref pointer); + this.Attributes.Add(attri); + } + } + + public void Print() + { + Console.WriteLine("Field Info Struct: "); + Console.WriteLine("AccessFlags: " + AccessFlags); + Console.WriteLine("NameIndex: " + NameIndex + " // " + ((PoolUtf8)this.parent.m_constantsPool[NameIndex - 1]).Value); + Console.WriteLine("DescriptorIndex: " + DescriptorIndex + " // " + ((PoolUtf8)this.parent.m_constantsPool[DescriptorIndex - 1]).Value); + Console.WriteLine("Attribute Count:" + AttributeCount); + //if static, add to static field list + // if (this.AccessFlags == 9) //public and static + if ((this.AccessFlags & 0x08) != 0) + { + switch (((PoolUtf8)this.parent.m_constantsPool[DescriptorIndex - 1]).Value) + { + case "I": + Int newin = new Int(); + this.parent.StaticFields.Add(((PoolUtf8)this.parent.m_constantsPool[NameIndex - 1]).Value, newin); + break; + case "F": + Float newfl = new Float(); + this.parent.StaticFields.Add(((PoolUtf8)this.parent.m_constantsPool[NameIndex - 1]).Value, newfl); + break; + } + + } + for (int i = 0; i < AttributeCount; i++) + { + this.Attributes[i].Print(); + } + } + + public class FieldAttribute + { + public ushort NameIndex = 0; + public string Name = ""; + public Int32 Length = 0; + public byte[] Data; + private ClassRecord parent; + + public FieldAttribute(ClassRecord paren) + { + parent = paren; + } + + public void ReadData(byte[] data, ref int pointer) + { + NameIndex = (ushort)((data[pointer++] << 8) + data[pointer++]); + Length = (Int32)((data[pointer++] << 24) + (data[pointer++] << 16) + (data[pointer++] << 8) + data[pointer++]); + Data = new byte[Length]; + for (int i = 0; i < Length; i++) + { + Data[i] = data[pointer++]; + } + } + + public void Print() + { + Console.WriteLine("FieldAttribute: NameIndex: " + NameIndex + " // " + ((PoolUtf8)this.parent.m_constantsPool[NameIndex - 1]).Value); + } + } + } + + private class AttributeInfo + { + public void ReadData(byte[] data, ref int i) + { + + } + } + #endregion + + } +} \ No newline at end of file diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Heap.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Heap.cs new file mode 100644 index 0000000000..1a97b7d262 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Heap.cs @@ -0,0 +1,43 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace OpenSim.Region.Scripting.EmbeddedJVM +{ + public class Heap + { + public List ClassObjects = new List(); + + public Heap() + { + + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Interpreter.Logic.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Interpreter.Logic.cs new file mode 100644 index 0000000000..3e4063cddf --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Interpreter.Logic.cs @@ -0,0 +1,551 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; +using OpenSim.Region.Scripting.EmbeddedJVM.Types; +using OpenSim.Region.Scripting.EmbeddedJVM.Types.PrimitiveTypes; + +namespace OpenSim.Region.Scripting.EmbeddedJVM +{ + partial class Thread + { + private partial class Interpreter + { + private bool IsLogicOpCode(byte opcode) + { + bool result = false; + switch (opcode) + { + case (byte)(byte)OpCode.iconst_m1: + Int m_int = new Int(); + m_int.mValue = -1; + this.m_thread.m_currentFrame.OpStack.Push(m_int); + result = true; + break; + case (byte)(byte)OpCode.iconst_0: + m_int = new Int(); + m_int.mValue = 0; + this.m_thread.m_currentFrame.OpStack.Push(m_int); + result = true; + break; + case (byte)(byte)OpCode.iconst_1: + m_int = new Int(); + m_int.mValue = 1; + this.m_thread.m_currentFrame.OpStack.Push(m_int); + result = true; + break; + case (byte)(byte)OpCode.iconst_2: + m_int = new Int(); + m_int.mValue = 2; + this.m_thread.m_currentFrame.OpStack.Push(m_int); + result = true; + break; + case (byte)(byte)OpCode.iconst_3: + m_int = new Int(); + m_int.mValue = 3; + this.m_thread.m_currentFrame.OpStack.Push(m_int); + break; + case (byte)(byte)OpCode.iconst_4: + m_int = new Int(); + m_int.mValue = 4; + this.m_thread.m_currentFrame.OpStack.Push(m_int); + result = true; + break; + case (byte)OpCode.iconst_5: + m_int = new Int(); + m_int.mValue = 5; + this.m_thread.m_currentFrame.OpStack.Push(m_int); + result = true; + break; + case (byte)OpCode.fconst_0: + Float m_float = new Float(); + m_float.mValue = 0.0f; + this.m_thread.m_currentFrame.OpStack.Push(m_float); + result = true; + break; + case (byte)OpCode.fconst_1: + m_float = new Float(); + m_float.mValue = 1.0f; + this.m_thread.m_currentFrame.OpStack.Push(m_float); + result = true; + break; + case (byte)OpCode.fconst_2: + m_float = new Float(); + m_float.mValue = 2.0f; + this.m_thread.m_currentFrame.OpStack.Push(m_float); + result = true; + break; + case (byte)OpCode.bipush: //is this right? this should be pushing a byte onto stack not int? + int pushvalue = (int)GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC]; + Int pushInt = new Int(); + pushInt.mValue = pushvalue; + this.m_thread.m_currentFrame.OpStack.Push(pushInt); + this.m_thread.PC++; + result = true; + break; + case (byte)OpCode.sipush: + short pushvalue2 = (short)((GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC] << 8) + GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC + 1]); + Int pushInt2 = new Int(); + pushInt2.mValue = pushvalue2; + this.m_thread.m_currentFrame.OpStack.Push(pushInt2); + this.m_thread.PC += 2; + result = true; + break; + case (byte)OpCode.fload: + short findex1 = (short)((GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC])); + Float fload = new Float(); + if (this.m_thread.m_currentFrame.LocalVariables[findex1] != null) + { + if (this.m_thread.m_currentFrame.LocalVariables[findex1] is Float) + { + fload.mValue = ((Float)this.m_thread.m_currentFrame.LocalVariables[findex1]).mValue; + this.m_thread.m_currentFrame.OpStack.Push(fload); + } + } + this.m_thread.PC++; + result = true; + break; + case (byte)OpCode.iload_0: + if (this.m_thread.m_currentFrame.LocalVariables[0] != null) + { + if (this.m_thread.m_currentFrame.LocalVariables[0] is Int) + { + Int newInt = new Int(); + newInt.mValue = ((Int)this.m_thread.m_currentFrame.LocalVariables[0]).mValue; + this.m_thread.m_currentFrame.OpStack.Push(newInt); + } + } + result = true; + break; + case (byte)OpCode.iload_1: + if (this.m_thread.m_currentFrame.LocalVariables[1] != null) + { + if (this.m_thread.m_currentFrame.LocalVariables[1] is Int) + { + Int newInt = new Int(); + newInt.mValue = ((Int)this.m_thread.m_currentFrame.LocalVariables[1]).mValue; + this.m_thread.m_currentFrame.OpStack.Push(newInt); + } + } + result = true; + break; + case (byte)OpCode.fload_0: + if (this.m_thread.m_currentFrame.LocalVariables[0] != null) + { + if (this.m_thread.m_currentFrame.LocalVariables[0] is Float) + { + Float newfloat = new Float(); + newfloat.mValue = ((Float)this.m_thread.m_currentFrame.LocalVariables[0]).mValue; + this.m_thread.m_currentFrame.OpStack.Push(newfloat); + } + } + result = true; + break; + case (byte)OpCode.fload_1: + if (this.m_thread.m_currentFrame.LocalVariables[1] != null) + { + if (this.m_thread.m_currentFrame.LocalVariables[1] is Float) + { + Float newfloat = new Float(); + newfloat.mValue = ((Float)this.m_thread.m_currentFrame.LocalVariables[1]).mValue; + this.m_thread.m_currentFrame.OpStack.Push(newfloat); + } + } + result = true; + break; + case (byte)OpCode.fload_2: + if (this.m_thread.m_currentFrame.LocalVariables[2] != null) + { + if (this.m_thread.m_currentFrame.LocalVariables[2] is Float) + { + Float newfloat = new Float(); + newfloat.mValue = ((Float)this.m_thread.m_currentFrame.LocalVariables[2]).mValue; + this.m_thread.m_currentFrame.OpStack.Push(newfloat); + } + } + result = true; + break; + case (byte)OpCode.fload_3: + if (this.m_thread.m_currentFrame.LocalVariables[3] != null) + { + if (this.m_thread.m_currentFrame.LocalVariables[3] is Float) + { + Float newfloat = new Float(); + newfloat.mValue = ((Float)this.m_thread.m_currentFrame.LocalVariables[3]).mValue; + this.m_thread.m_currentFrame.OpStack.Push(newfloat); + } + } + result = true; + break; + case (byte)OpCode.istore: + short findex3 = (short)((GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC])); + BaseType istor = this.m_thread.m_currentFrame.OpStack.Pop(); + if (istor is Int) + { + this.m_thread.m_currentFrame.LocalVariables[findex3] = (Int)istor; + } + this.m_thread.PC++; + result = true; + break; + case (byte)OpCode.fstore: + short findex = (short)((GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC])); + BaseType fstor = this.m_thread.m_currentFrame.OpStack.Pop(); + if (fstor is Float) + { + this.m_thread.m_currentFrame.LocalVariables[findex] = (Float)fstor; + } + this.m_thread.PC++; + result = true; + break; + case (byte)OpCode.istore_0: + BaseType baset = this.m_thread.m_currentFrame.OpStack.Pop(); + if (baset is Int) + { + this.m_thread.m_currentFrame.LocalVariables[0] = (Int)baset; + } + result = true; + break; + case (byte)OpCode.istore_1: + baset = this.m_thread.m_currentFrame.OpStack.Pop(); + if (baset is Int) + { + this.m_thread.m_currentFrame.LocalVariables[1] = (Int)baset; + } + result = true; + break; + case (byte)OpCode.fstore_0: + baset = this.m_thread.m_currentFrame.OpStack.Pop(); + if (baset is Float) + { + this.m_thread.m_currentFrame.LocalVariables[0] = (Float)baset; + } + result = true; + break; + case (byte)OpCode.fstore_1: + baset = this.m_thread.m_currentFrame.OpStack.Pop(); + if (baset is Float) + { + this.m_thread.m_currentFrame.LocalVariables[1] = (Float)baset; + } + result = true; + break; + case (byte)OpCode.fstore_2: + baset = this.m_thread.m_currentFrame.OpStack.Pop(); + if (baset is Float) + { + this.m_thread.m_currentFrame.LocalVariables[2] = (Float)baset; + } + result = true; + break; + case (byte)OpCode.fstore_3: + baset = this.m_thread.m_currentFrame.OpStack.Pop(); + if (baset is Float) + { + this.m_thread.m_currentFrame.LocalVariables[3] = (Float)baset; + } + result = true; + break; + case (byte)OpCode.pop: + this.m_thread.m_currentFrame.OpStack.Pop(); + result = true; + break; + case (byte)OpCode.fadd: + BaseType bf2 = this.m_thread.m_currentFrame.OpStack.Pop(); + BaseType bf1 = this.m_thread.m_currentFrame.OpStack.Pop(); + if (bf1 is Float && bf2 is Float) + { + Float nflt = new Float(); + nflt.mValue = ((Float)bf1).mValue + ((Float)bf2).mValue; + this.m_thread.m_currentFrame.OpStack.Push(nflt); + } + result = true; + break; + case (byte)OpCode.fsub: + BaseType bsf2 = this.m_thread.m_currentFrame.OpStack.Pop(); + BaseType bsf1 = this.m_thread.m_currentFrame.OpStack.Pop(); + if (bsf1 is Float && bsf2 is Float) + { + Float resf = new Float(); + resf.mValue = ((Float)bsf1).mValue - ((Float)bsf2).mValue; + this.m_thread.m_currentFrame.OpStack.Push(resf); + } + result = true; + break; + case (byte)OpCode.imul: //check the order of the two values off the stack is correct + BaseType bs2 = this.m_thread.m_currentFrame.OpStack.Pop(); + BaseType bs1 = this.m_thread.m_currentFrame.OpStack.Pop(); + if (bs1 is Int && bs2 is Int) + { + Int nInt = new Int(); + nInt.mValue = ((Int)bs1).mValue * ((Int)bs2).mValue; + this.m_thread.m_currentFrame.OpStack.Push(nInt); + } + result = true; + break; + case (byte)OpCode.iinc: + if (this.m_thread.m_currentFrame.LocalVariables[GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC]] != null) + { + if (this.m_thread.m_currentFrame.LocalVariables[GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC]] is Int) + { + ((Int)this.m_thread.m_currentFrame.LocalVariables[GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC]]).mValue += (sbyte)GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC + 1]; + } + } + this.m_thread.PC += 2; + result = true; + break; + case (byte)OpCode.f2i: + BaseType conv1 = this.m_thread.m_currentFrame.OpStack.Pop(); + if (conv1 is Float) + { + Int newconv = new Int(); + newconv.mValue = (int)((Float)conv1).mValue; + this.m_thread.m_currentFrame.OpStack.Push(newconv); + } + result = true; + break; + case (byte)OpCode.fcmpl: + BaseType flcom2 = this.m_thread.m_currentFrame.OpStack.Pop(); + BaseType flcom1 = this.m_thread.m_currentFrame.OpStack.Pop(); + if (flcom1 is Float && flcom2 is Float) + { + Int compres = new Int(); + if (((Float)flcom1).mValue < ((Float)flcom2).mValue) + { + compres.mValue = -1; + } + else if (((Float)flcom1).mValue > ((Float)flcom2).mValue) + { + compres.mValue = 1; + } + else + { + compres.mValue = 0; + } + this.m_thread.m_currentFrame.OpStack.Push(compres); + } + result = true; + break; + case (byte)OpCode.fcmpg: + flcom2 = this.m_thread.m_currentFrame.OpStack.Pop(); + flcom1 = this.m_thread.m_currentFrame.OpStack.Pop(); + if (flcom1 is Float && flcom2 is Float) + { + Int compres = new Int(); + if (((Float)flcom1).mValue < ((Float)flcom2).mValue) + { + compres.mValue = -1; + } + else if (((Float)flcom1).mValue > ((Float)flcom2).mValue) + { + compres.mValue = 1; + } + else + { + compres.mValue = 0; + } + this.m_thread.m_currentFrame.OpStack.Push(compres); + } + result = true; + break; + case (byte)OpCode.ifge: + short compareoffset2 = (short)((GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC] << 8) + GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC + 1]); + BaseType compe1 = this.m_thread.m_currentFrame.OpStack.Pop(); + if (compe1 is Int) + { + if (((Int)compe1).mValue >= 0) + { + this.m_thread.PC += -1 + compareoffset2; + } + else + { + this.m_thread.PC += 2; + } + } + else + { + this.m_thread.PC += 2; + } + result = true; + break; + case (byte)OpCode.ifle: + short compareoffset1 = (short)((GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC] << 8) + GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC + 1]); + BaseType comp1 = this.m_thread.m_currentFrame.OpStack.Pop(); + if (comp1 is Int) + { + if (((Int)comp1).mValue <= 0) + { + this.m_thread.PC += -1 + compareoffset1; + } + else + { + this.m_thread.PC += 2; + } + } + else + { + this.m_thread.PC += 2; + } + result = true; + break; + case (byte)OpCode.if_icmpge: + short compareoffset = (short)((GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC] << 8) + GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC + 1]); + BaseType bc2 = this.m_thread.m_currentFrame.OpStack.Pop(); + BaseType bc1 = this.m_thread.m_currentFrame.OpStack.Pop(); + if (bc1 is Int && bc2 is Int) + { + //Console.WriteLine("comparing " + ((Int)bc1).mValue + " and " + ((Int)bc2).mValue); + if (((Int)bc1).mValue >= ((Int)bc2).mValue) + { + // Console.WriteLine("branch compare true , offset is " +compareoffset); + // Console.WriteLine("current PC is " + this._mThread.PC); + this.m_thread.PC += -1 + compareoffset; + //Console.WriteLine("new PC is " + this._mThread.PC); + } + else + { + //Console.WriteLine("branch compare false"); + this.m_thread.PC += 2; + } + } + else + { + this.m_thread.PC += 2; + } + result = true; + break; + case (byte)OpCode.if_icmple: + short compareloffset = (short)((GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC] << 8) + GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC + 1]); + BaseType bcl2 = this.m_thread.m_currentFrame.OpStack.Pop(); + BaseType bcl1 = this.m_thread.m_currentFrame.OpStack.Pop(); + if (bcl1 is Int && bcl2 is Int) + { + //Console.WriteLine("comparing " + ((Int)bcl1).mValue + " and " + ((Int)bcl2).mValue); + if (((Int)bcl1).mValue <= ((Int)bcl2).mValue) + { + // Console.WriteLine("branch compare true , offset is " + compareloffset); + // Console.WriteLine("current PC is " + this._mThread.PC); + this.m_thread.PC += -1 + compareloffset; + // Console.WriteLine("new PC is " + this._mThread.PC); + } + else + { + //Console.WriteLine("branch compare false"); + this.m_thread.PC += 2; + } + } + else + { + this.m_thread.PC += 2; + } + result = true; + break; + case (byte)OpCode._goto: + short offset = (short)((GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC] << 8) + GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC + 1]); + this.m_thread.PC += -1 + offset; + result = true; + break; + case (byte)OpCode.getstatic: + short fieldrefIndex = (short)((GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC] << 8) + GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC + 1]); + if (this.m_thread.currentClass.m_constantsPool[fieldrefIndex - 1] is ClassRecord.PoolFieldRef) + { + if (((ClassRecord.PoolFieldRef)this.m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).mClass.Name.Value == this.m_thread.currentClass.MClass.Name.Value) + { + //from this class + if (this.m_thread.currentClass.StaticFields.ContainsKey(((ClassRecord.PoolFieldRef)this.m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).mNameType.Name.Value)) + { + if (this.m_thread.currentClass.StaticFields[((ClassRecord.PoolFieldRef)this.m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).mNameType.Name.Value] is Float) + { + Float retFloat = new Float(); + retFloat.mValue = ((Float)this.m_thread.currentClass.StaticFields[((ClassRecord.PoolFieldRef)this.m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).mNameType.Name.Value]).mValue; + this.m_thread.m_currentFrame.OpStack.Push(retFloat); + } + else if (this.m_thread.currentClass.StaticFields[((ClassRecord.PoolFieldRef)this.m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).mNameType.Name.Value] is Int) + { + Int retInt = new Int(); + retInt.mValue = ((Int)this.m_thread.currentClass.StaticFields[((ClassRecord.PoolFieldRef)this.m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).mNameType.Name.Value]).mValue; + // Console.WriteLine("getting static field, " + retInt.mValue); + this.m_thread.m_currentFrame.OpStack.Push(retInt); + } + } + } + else + { + //get from a different class + } + } + this.m_thread.PC += 2; + result = true; + break; + case (byte)OpCode.putstatic: + fieldrefIndex = (short)((GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC] << 8) + GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC + 1]); + BaseType addstatic = this.m_thread.m_currentFrame.OpStack.Pop(); + if (this.m_thread.currentClass.m_constantsPool[fieldrefIndex - 1] is ClassRecord.PoolFieldRef) + { + if (((ClassRecord.PoolFieldRef)this.m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).mClass.Name.Value == this.m_thread.currentClass.MClass.Name.Value) + { + // this class + if (this.m_thread.currentClass.StaticFields.ContainsKey(((ClassRecord.PoolFieldRef)this.m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).mNameType.Name.Value)) + { + if (addstatic is Float) + { + if (this.m_thread.currentClass.StaticFields[((ClassRecord.PoolFieldRef)this.m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).mNameType.Name.Value] is Float) + { + Float newf = new Float(); + newf.mValue = ((Float)addstatic).mValue; + this.m_thread.currentClass.StaticFields[((ClassRecord.PoolFieldRef)this.m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).mNameType.Name.Value] = newf; + } + } + else if (addstatic is Int) + { + if (this.m_thread.currentClass.StaticFields[((ClassRecord.PoolFieldRef)this.m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).mNameType.Name.Value] is Int) + { + //Console.WriteLine("setting static field to " + ((Int)addstatic).mValue); + Int newi = new Int(); + newi.mValue = ((Int)addstatic).mValue; + this.m_thread.currentClass.StaticFields[((ClassRecord.PoolFieldRef)this.m_thread.currentClass.m_constantsPool[fieldrefIndex - 1]).mNameType.Name.Value] = newi; + } + } + } + } + else + { + // a different class + } + } + this.m_thread.PC += 2; + result = true; + break; + + } + + return result; + } + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Interpreter.Methods.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Interpreter.Methods.cs new file mode 100644 index 0000000000..a8ebbd9dc8 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Interpreter.Methods.cs @@ -0,0 +1,96 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; +using OpenSim.Region.Scripting.EmbeddedJVM.Types; +using OpenSim.Region.Scripting.EmbeddedJVM.Types.PrimitiveTypes; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework; +using OpenSim.Framework.Types; + +namespace OpenSim.Region.Scripting.EmbeddedJVM +{ + partial class Thread + { + private partial class Interpreter + { + private bool IsMethodOpCode(byte opcode) + { + bool result = false; + switch (opcode) + { + case 184: + short refIndex = (short) ((GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC] << 8) + GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC+1]); + if (this.m_thread.currentClass.m_constantsPool[refIndex - 1] is ClassRecord.PoolMethodRef) + { + string typ = ((ClassRecord.PoolMethodRef)this.m_thread.currentClass.m_constantsPool[refIndex - 1]).mNameType.Type.Value; + string typeparam = ""; + string typereturn = ""; + int firstbrak = 0; + int secondbrak = 0; + firstbrak = typ.LastIndexOf('('); + secondbrak = typ.LastIndexOf(')'); + typeparam = typ.Substring(firstbrak + 1, secondbrak - firstbrak - 1); + typereturn = typ.Substring(secondbrak + 1, typ.Length - secondbrak - 1); + if (((ClassRecord.PoolMethodRef)this.m_thread.currentClass.m_constantsPool[refIndex - 1]).mClass.Name.Value == this.m_thread.currentClass.MClass.Name.Value) + { + //calling a method in this class + if (typeparam.Length == 0) + { + this.m_thread.JumpToStaticVoidMethod(((ClassRecord.PoolMethodRef)this.m_thread.currentClass.m_constantsPool[refIndex - 1]).mNameType.Name.Value, (this.m_thread.PC + 2)); + } + else + { + this.m_thread.JumpToStaticParamMethod(((ClassRecord.PoolMethodRef)this.m_thread.currentClass.m_constantsPool[refIndex - 1]).mNameType.Name.Value, typeparam, (this.m_thread.PC + 2)); + } + } + else + { + //calling a method of a different class + + // OpenSimAPI Class + if (((ClassRecord.PoolMethodRef)this.m_thread.currentClass.m_constantsPool[refIndex - 1]).mClass.Name.Value == "OpenSimAPI") + { + this.m_thread.scriptInfo.api.CallMethod(((ClassRecord.PoolMethodRef)this.m_thread.currentClass.m_constantsPool[refIndex - 1]).mNameType.Name.Value, null); + } + } + } + else + { + this.m_thread.PC += 2; + } + result = true; + break; + } + + return result; + } + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Interpreter.Return.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Interpreter.Return.cs new file mode 100644 index 0000000000..6444776f49 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Interpreter.Return.cs @@ -0,0 +1,40 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace OpenSim.Region.Scripting.EmbeddedJVM +{ + partial class Thread + { + private partial class Interpreter + { + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Interpreter.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Interpreter.cs new file mode 100644 index 0000000000..ba7448a341 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Interpreter.cs @@ -0,0 +1,135 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; +using OpenSim.Region.Scripting.EmbeddedJVM.Types; +using OpenSim.Region.Scripting.EmbeddedJVM.Types.PrimitiveTypes; + +namespace OpenSim.Region.Scripting.EmbeddedJVM +{ + partial class Thread + { + private partial class Interpreter + { + private Thread m_thread; + + public Interpreter(Thread parentThread) + { + m_thread = parentThread; + } + + public bool Excute() + { + bool run = true; + byte currentOpCode = GlobalMemory.MethodArea.MethodBuffer[this.m_thread.PC++]; + // Console.WriteLine("opCode is: " + currentOpCode); + bool handled = false; + + handled = this.IsLogicOpCode(currentOpCode); + if (!handled) + { + handled = this.IsMethodOpCode(currentOpCode); + } + if (!handled) + { + if (currentOpCode == 172) + { + if (this.m_thread.stack.StackFrames.Count > 1) + { + Console.WriteLine("returning int from function"); + int retPC1 = this.m_thread.m_currentFrame.ReturnPC; + BaseType bas1 = this.m_thread.m_currentFrame.OpStack.Pop(); + this.m_thread.stack.StackFrames.Pop(); + this.m_thread.m_currentFrame = this.m_thread.stack.StackFrames.Peek(); + this.m_thread.PC = retPC1; + if (bas1 is Int) + { + this.m_thread.m_currentFrame.OpStack.Push((Int)bas1); + } + } + else + { + // Console.WriteLine("No parent function so ending program"); + this.m_thread.stack.StackFrames.Pop(); + run = false; + } + handled = true; + } + if (currentOpCode == 174) + { + if (this.m_thread.stack.StackFrames.Count > 1) + { + Console.WriteLine("returning float from function"); + int retPC1 = this.m_thread.m_currentFrame.ReturnPC; + BaseType bas1 = this.m_thread.m_currentFrame.OpStack.Pop(); + this.m_thread.stack.StackFrames.Pop(); + this.m_thread.m_currentFrame = this.m_thread.stack.StackFrames.Peek(); + this.m_thread.PC = retPC1; + if (bas1 is Float) + { + this.m_thread.m_currentFrame.OpStack.Push((Float)bas1); + } + } + else + { + // Console.WriteLine("No parent function so ending program"); + this.m_thread.stack.StackFrames.Pop(); + run = false; + } + handled = true; + } + if (currentOpCode == 177) + { + if (this.m_thread.stack.StackFrames.Count > 1) + { + Console.WriteLine("returning from function"); + int retPC = this.m_thread.m_currentFrame.ReturnPC; + this.m_thread.stack.StackFrames.Pop(); + this.m_thread.m_currentFrame = this.m_thread.stack.StackFrames.Peek(); + this.m_thread.PC = retPC; + } + else + { + // Console.WriteLine("No parent function so ending program"); + this.m_thread.stack.StackFrames.Pop(); + run = false; + } + handled = true; + } + } + if (!handled) + { + Console.WriteLine("opcode " + currentOpCode + " not been handled "); + } + return run; + + } + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/MainMemory.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/MainMemory.cs new file mode 100644 index 0000000000..addb6ffbeb --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/MainMemory.cs @@ -0,0 +1,45 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace OpenSim.Region.Scripting.EmbeddedJVM +{ + public class MainMemory + { + public Heap HeapArea; + public MethodMemory MethodArea; + + public MainMemory() + { + MethodArea = new MethodMemory(); + HeapArea = new Heap(); + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/MethodMemory.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/MethodMemory.cs new file mode 100644 index 0000000000..7d69e914b0 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/MethodMemory.cs @@ -0,0 +1,46 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace OpenSim.Region.Scripting.EmbeddedJVM +{ + public class MethodMemory + { + public byte[] MethodBuffer; + public List Classes = new List(); + public int NextMethodPC = 0; + public int Methodcount = 0; + + public MethodMemory() + { + MethodBuffer = new byte[20000]; + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Object.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Object.cs new file mode 100644 index 0000000000..6a0a1a4e5a --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Object.cs @@ -0,0 +1,37 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace OpenSim.Region.Scripting.EmbeddedJVM +{ + public class Object + { + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/OpCodes.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/OpCodes.cs new file mode 100644 index 0000000000..33dee7f6f2 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/OpCodes.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Region.Scripting.EmbeddedJVM +{ + public enum OpCode : byte + { + iconst_m1 = 2, + iconst_0 = 3, + iconst_1 = 4, + iconst_2 = 5, + iconst_3 = 6, + iconst_4 = 7, + iconst_5 = 8, + fconst_0 = 11, + fconst_1 = 12, + fconst_2 = 13, + bipush = 16, + sipush = 17, + fload = 23, + iload_0 = 26, + iload_1 = 27, + fload_0 = 34, + fload_1 = 35, + fload_2 = 36, + fload_3 = 37, + istore = 54, + fstore = 56, + istore_0 = 59, + istore_1 = 60, + istore_2 = 61, + istore_3 = 62, + fstore_0 = 67, + fstore_1 = 68, + fstore_2 = 69, + fstore_3 = 70, + pop = 87, + fadd = 98, + fsub = 102, + imul = 104, + iinc = 132, + f2i = 139, + fcmpl = 149, + fcmpg = 150, + ifge = 156, + ifgt = 157, + ifle = 158, + if_icmpge = 162, + if_icmpgt = 163, + if_icmple = 164, + _goto = 167, + getstatic = 178, + putstatic = 179 + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Stack.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Stack.cs new file mode 100644 index 0000000000..74f0a7ffe8 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Stack.cs @@ -0,0 +1,42 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace OpenSim.Region.Scripting.EmbeddedJVM +{ + public class Stack + { + public Stack StackFrames = new Stack(); + + public Stack() + { + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/StackFrame.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/StackFrame.cs new file mode 100644 index 0000000000..1072395e32 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/StackFrame.cs @@ -0,0 +1,49 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; +using OpenSim.Region.Scripting.EmbeddedJVM.Types; + +namespace OpenSim.Region.Scripting.EmbeddedJVM +{ + public class StackFrame + { + public BaseType[] LocalVariables; + public Stack OpStack = new Stack(); + + public int ReturnPC = 0; + public ClassRecord CallingClass = null; + + public StackFrame() + { + LocalVariables = new BaseType[20]; + } + + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Thread.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Thread.cs new file mode 100644 index 0000000000..6059e40805 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JVM/Thread.cs @@ -0,0 +1,119 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; +using OpenSim.Region.Scripting.EmbeddedJVM.Types; +using OpenSim.Region.Scripting.EmbeddedJVM.Types.PrimitiveTypes; +using OpenSim.Framework; +using OpenSim.Framework.Interfaces; +using OpenSim.Region.Environment.Scenes; +using OpenSim.Region.Scripting; + +namespace OpenSim.Region.Scripting.EmbeddedJVM +{ + public partial class Thread + { + // Is this smart? + public static MainMemory GlobalMemory; + public static Scene World; + private int PC = 0; + private Stack stack; + private Interpreter m_Interpreter; + public ClassRecord currentClass; + public ClassInstance currentInstance; + private StackFrame m_currentFrame; + public int excutionCounter = 0; + public bool running = false; + + public ScriptInfo scriptInfo; + + public Thread() + { + this.m_Interpreter = new Interpreter(this); + this.stack = new Stack(); + } + + public void SetPC(int methodpointer) + { + //Console.WriteLine("Thread PC has been set to " + methodpointer); + PC = methodpointer; + } + + public void StartMethod(ClassRecord rec, string methName) + { + m_currentFrame = new StackFrame(); + this.stack.StackFrames.Push(m_currentFrame); + this.currentClass = rec; + currentClass.StartMethod(this, methName); + } + + public void StartMethod( string methName) + { + m_currentFrame = new StackFrame(); + this.stack.StackFrames.Push(m_currentFrame); + currentClass.StartMethod(this, methName); + } + + public void JumpToStaticVoidMethod(string methName, int returnPC) + { + m_currentFrame = new StackFrame(); + m_currentFrame.ReturnPC = returnPC; + this.stack.StackFrames.Push(m_currentFrame); + currentClass.StartMethod(this, methName); + } + + public void JumpToStaticParamMethod(string methName, string param, int returnPC) + { + if (param == "I") + { + BaseType bs1 = m_currentFrame.OpStack.Pop(); + m_currentFrame = new StackFrame(); + m_currentFrame.ReturnPC = returnPC; + this.stack.StackFrames.Push(m_currentFrame); + m_currentFrame.LocalVariables[0] = ((Int)bs1); + currentClass.StartMethod(this, methName); + } + if (param == "F") + { + + } + } + + public void JumpToClassStaticVoidMethod(string className, string methName, int returnPC) + { + + } + + public bool Excute() + { + excutionCounter++; + return this.m_Interpreter.Excute(); + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JavaEngine.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JavaEngine.cs new file mode 100644 index 0000000000..a884e2b310 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/JavaEngine.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Text; + +using OpenSim.Region.Scripting; +using OpenSim.Region.Scripting.EmbeddedJVM; + +namespace OpenSim.Region.Scripting +{ + public class JavaEngine : IScriptCompiler + { + public string FileExt() + { + return ".java"; + } + + public Dictionary compile(string filename) + { + JVMScript script = new JVMScript(); + Dictionary returns = new Dictionary(); + + script.LoadScript(filename); + + returns.Add(filename, script); + + return returns; + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/OpenSimJVM.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/OpenSimJVM.cs new file mode 100644 index 0000000000..6b3e8582f3 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/OpenSimJVM.cs @@ -0,0 +1,170 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; +using System.IO; +using System.Threading; +using OpenSim.Framework; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Utilities; +using OpenSim.Region.Scripting; +using OpenSim.Region.Environment.Scenes; + +namespace OpenSim.Region.Scripting.EmbeddedJVM +{ + public class JVMScript : IScript + { + private List _threads = new List(); + private BlockingQueue CompileScripts = new BlockingQueue(); + private MainMemory _mainMemory; + + ScriptInfo scriptInfo; + + public void Initialise(ScriptInfo info) + { + scriptInfo = info; + + _mainMemory = new MainMemory(); + Thread.GlobalMemory = this._mainMemory; + Thread.World = info.world; + CompileScript(); + + scriptInfo.events.OnFrame += new EventManager.OnFrameDelegate(events_OnFrame); + scriptInfo.events.OnNewPresence += new EventManager.OnNewPresenceDelegate(events_OnNewPresence); + } + + void events_OnNewPresence(ScenePresence presence) + { + for (int i = 0; i < this._threads.Count; i++) + { + if (!this._threads[i].running) + { + this._threads[i].StartMethod("OnNewPresence"); + bool run = true; + while (run) + { + run = this._threads[i].Excute(); + } + } + } + } + + void events_OnFrame() + { + for (int i = 0; i < this._threads.Count; i++) + { + if (!this._threads[i].running) + { + this._threads[i].StartMethod("OnFrame"); + bool run = true; + while (run) + { + run = this._threads[i].Excute(); + } + } + } + } + + public string Name + { + get { return "JVM Scripting Engine"; } + } + + public void LoadScript(string script) + { + Console.WriteLine("OpenSimJVM - loading new script: " + script); + CompileInfo comp = new CompileInfo(); + comp.script = script; + comp.scriptName = script; + this.CompileScripts.Enqueue(comp); + } + + public void CompileScript() + { + CompileInfo comp = this.CompileScripts.Dequeue(); + string script = comp.script; + string scriptName = comp.scriptName; + try + { + //need to compile the script into a java class file + + //first save it to a java source file + TextWriter tw = new StreamWriter(scriptName + ".java"); + tw.WriteLine(script); + tw.Close(); + + //now compile + System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo("javac.exe", "*.java"); + // psi.RedirectStandardOutput = true; + psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; + psi.UseShellExecute = false; + + System.Diagnostics.Process javacomp; + javacomp = System.Diagnostics.Process.Start(psi); + javacomp.WaitForExit(); + + + //now load in class file + ClassRecord class1 = new ClassRecord(); + class1.LoadClassFromFile(scriptName + ".class"); + class1.PrintToConsole(); + //Console.WriteLine(); + this._mainMemory.MethodArea.Classes.Add(class1); + class1.AddMethodsToMemory(this._mainMemory.MethodArea); + + Thread newThread = new Thread(); + this._threads.Add(newThread); + newThread.currentClass = class1; + newThread.scriptInfo = scriptInfo; + + //now delete the created files + System.IO.File.Delete(scriptName + ".java"); + System.IO.File.Delete(scriptName + ".class"); + //this.OnFrame(); + } + catch (Exception e) + { + Console.WriteLine("exception"); + Console.WriteLine(e.StackTrace); + Console.WriteLine(e.Message); + } + } + + private class CompileInfo + { + public string script; + public string scriptName; + + public CompileInfo() + { + + } + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/Types/ArrayReference.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/Types/ArrayReference.cs new file mode 100644 index 0000000000..40e2e227e7 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/Types/ArrayReference.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Region.Scripting.EmbeddedJVM.Types +{ + public class ArrayReference :BaseType + { + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/Types/BaseType.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/Types/BaseType.cs new file mode 100644 index 0000000000..4ee172083a --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/Types/BaseType.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Region.Scripting.EmbeddedJVM.Types +{ + public class BaseType : Object + { + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/Types/ObjectReference.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/Types/ObjectReference.cs new file mode 100644 index 0000000000..75d8e41774 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/Types/ObjectReference.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Region.Scripting.EmbeddedJVM.Types +{ + public class ObjectReference : BaseType + { + public ushort Reference; + + public ObjectReference() + { + + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/Types/PrimitiveTypes/Byte.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/Types/PrimitiveTypes/Byte.cs new file mode 100644 index 0000000000..f5446dcde7 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/Types/PrimitiveTypes/Byte.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Region.Scripting.EmbeddedJVM.Types.PrimitiveTypes +{ + public class Byte : BaseType + { + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/Types/PrimitiveTypes/Char.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/Types/PrimitiveTypes/Char.cs new file mode 100644 index 0000000000..89824b415d --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/Types/PrimitiveTypes/Char.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Region.Scripting.EmbeddedJVM.Types.PrimitiveTypes +{ + public class Char : BaseType + { + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/Types/PrimitiveTypes/Float.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/Types/PrimitiveTypes/Float.cs new file mode 100644 index 0000000000..2638c20b5f --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/Types/PrimitiveTypes/Float.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Region.Scripting.EmbeddedJVM.Types.PrimitiveTypes +{ + public class Float : BaseType + { + public float mValue = 0; + + public Float() + { + + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/Types/PrimitiveTypes/Int.cs b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/Types/PrimitiveTypes/Int.cs new file mode 100644 index 0000000000..0155e72b71 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Engines/JVMEngine/Types/PrimitiveTypes/Int.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Region.Scripting.EmbeddedJVM.Types.PrimitiveTypes +{ + public class Int : BaseType + { + public int mValue = 0; + + public Int() + { + + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/IScriptHost.cs b/OpenSim/Region/Environment/Scenes/Scripting/IScriptHost.cs new file mode 100644 index 0000000000..5d5f6985d0 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/IScriptHost.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; +using libsecondlife; + +namespace OpenSim.Region.Environment.Scenes.Scripting +{ + public interface IScriptHost + { + string Name { get; } + LLUUID UUID { get; } + LLVector3 AbsolutePosition { get; } + void SetText(string text, Axiom.Math.Vector3 color, double alpha); + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/NullScriptHost.cs b/OpenSim/Region/Environment/Scenes/Scripting/NullScriptHost.cs new file mode 100644 index 0000000000..62c84a63ab --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/NullScriptHost.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Text; +using libsecondlife; + +namespace OpenSim.Region.Environment.Scenes.Scripting +{ + public class NullScriptHost : IScriptHost + { + + LLVector3 m_pos = new LLVector3( 128, 128, 30 ); + public string Name + { + get { return "Object"; } + } + + public LLUUID UUID + { + get { return LLUUID.Zero; } + } + + public LLVector3 AbsolutePosition + { + get { return m_pos; } + } + + public void SetText(string text, Axiom.Math.Vector3 color, double alpha) + { + Console.WriteLine("Tried to SetText [{0}] on NullScriptHost", text); + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/Script.cs b/OpenSim/Region/Environment/Scenes/Scripting/Script.cs new file mode 100644 index 0000000000..a6b613bfd8 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/Script.cs @@ -0,0 +1,64 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 OpenSim.Region.Environment.Scenes; + +namespace OpenSim.Region.Scripting +{ + public interface IScript + { + void Initialise(ScriptInfo scriptInfo); + string Name { get; } + } + + public class TestScript : IScript + { + ScriptInfo script; + + public string Name + { + get { return "TestScript 0.1"; } + } + + public void Initialise(ScriptInfo scriptInfo) + { + script = scriptInfo; + script.events.OnFrame += events_OnFrame; + script.events.OnNewPresence += events_OnNewPresence; + } + + void events_OnNewPresence(ScenePresence presence) + { + script.logger.Verbose("Hello " + presence.Firstname.ToString() + "!"); + } + + void events_OnFrame() + { + //script.logger.Verbose("Hello World!"); + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/ScriptAPI.cs b/OpenSim/Region/Environment/Scenes/Scripting/ScriptAPI.cs new file mode 100644 index 0000000000..03c9c0874c --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/ScriptAPI.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Key = libsecondlife.LLUUID; +using Rotation = libsecondlife.LLQuaternion; +using Vector = libsecondlife.LLVector3; +using LSLList = System.Collections.Generic.List; + + +using OpenSim.Region.Environment.Scenes; + +namespace OpenSim.Region.Scripting +{ + // This class is to be used for engines which may not be able to access the Scene directly. + // Scene access is preffered, but obviously not possible on some non-.NET languages. + public class ScriptAPI + { + Scene scene; + ScriptInterpretedAPI interpretedAPI; + + public ScriptAPI(Scene world, Key taskID) + { + scene = world; + interpretedAPI = new ScriptInterpretedAPI(world, taskID); + } + + public Object CallMethod(String method, Object[] args) + { + return null; + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/ScriptEngineInterface.cs b/OpenSim/Region/Environment/Scenes/Scripting/ScriptEngineInterface.cs new file mode 100644 index 0000000000..33021eeb35 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/ScriptEngineInterface.cs @@ -0,0 +1,43 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +/* Original code: Tedd Hansen */ +using System; +using System.Collections.Generic; +using System.Text; +using OpenSim.Region.Environment.Scenes.Scripting; + +//TODO: WHERE TO PLACE THIS? +namespace OpenSim.Region.Environment.Scenes.Scripting +{ + public interface ScriptEngineInterface + { + void InitializeEngine(OpenSim.Region.Environment.Scenes.Scene Sceneworld, OpenSim.Framework.Console.LogBase logger); + void Shutdown(); + void StartScript(string ScriptID, IScriptHost ObjectID); + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/ScriptEngineLoader.cs b/OpenSim/Region/Environment/Scenes/Scripting/ScriptEngineLoader.cs new file mode 100644 index 0000000000..2c87359cc5 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/ScriptEngineLoader.cs @@ -0,0 +1,124 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +/* Original code: Tedd Hansen */ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Reflection; + +namespace OpenSim.Region.Environment.Scenes.Scripting +{ + public class ScriptEngineLoader + { + private OpenSim.Framework.Console.LogBase m_log; + public ScriptEngineLoader(OpenSim.Framework.Console.LogBase logger) + { + m_log = logger; + } + + public ScriptEngineInterface LoadScriptEngine(string EngineName) + { + ScriptEngineInterface ret = null; + try + { + ret = LoadAndInitAssembly(Path.Combine("ScriptEngines", "OpenSim.Region.ScriptEngine." + EngineName + ".dll"), + "OpenSim.Region.ScriptEngine." + EngineName + ".ScriptEngine"); + } + catch (Exception e) + { + m_log.Error("ScriptEngine", "Error loading assembly \"" + EngineName + "\": " + e.ToString()); + } + return ret; + } + + /// + /// Does actual loading and initialization of script Assembly + /// + /// AppDomain to load script into + /// FileName of script assembly (.dll) + /// + private ScriptEngineInterface LoadAndInitAssembly(string FileName, string NameSpace) + { + //Common.SendToDebug("Loading ScriptEngine Assembly " + FileName); + // Load .Net Assembly (.dll) + // Initialize and return it + + // TODO: Add error handling + + Assembly a; + //try + //{ + + + // Load to default appdomain (temporary) + a = Assembly.LoadFrom(FileName); + // Load to specified appdomain + // TODO: Insert security + //a = FreeAppDomain.Load(FileName); + //} + //catch (Exception e) + //{ + // m_log.Error("ScriptEngine", "Error loading assembly \"" + FileName + "\": " + e.ToString()); + //} + + + //Console.WriteLine("Loading: " + FileName); + //foreach (Type _t in a.GetTypes()) + //{ + // Console.WriteLine("Type: " + _t.ToString()); + //} + + Type t; + //try + //{ + t = a.GetType(NameSpace, true); + //} + //catch (Exception e) + //{ + // m_log.Error("ScriptEngine", "Error initializing type \"" + NameSpace + "\" from \"" + FileName + "\": " + e.ToString()); + //} + + ScriptEngineInterface ret; + //try + //{ + ret = (ScriptEngineInterface)Activator.CreateInstance(t); + //} + //catch (Exception e) + //{ + // m_log.Error("ScriptEngine", "Error initializing type \"" + NameSpace + "\" from \"" + FileName + "\": " + e.ToString()); + //} + + return ret; + + + } + + + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/ScriptInfo.cs b/OpenSim/Region/Environment/Scenes/Scripting/ScriptInfo.cs new file mode 100644 index 0000000000..6d6202388a --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/ScriptInfo.cs @@ -0,0 +1,63 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 OpenSim.Framework.Console; +using OpenSim.Region.Environment.Scenes; + +namespace OpenSim.Region.Scripting +{ + /// + /// Class which provides access to the world + /// + public class ScriptInfo + { + // Reference to world.eventsManager provided for convenience + public EventManager events; + + // The main world + public Scene world; + + // The console + public LogBase logger; + + // API Access + public ScriptAPI api; + + public ScriptInfo(Scene scene) + { + world = scene; + events = world.EventManager; + logger = MainLog.Instance; + api = new ScriptAPI(world, libsecondlife.LLUUID.Zero); + } + + public void CreateTaskAPI(libsecondlife.LLUUID task) + { + api = new ScriptAPI(world, task); + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/ScriptInterpretedAPI.cs b/OpenSim/Region/Environment/Scenes/Scripting/ScriptInterpretedAPI.cs new file mode 100644 index 0000000000..6937e0385e --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/ScriptInterpretedAPI.cs @@ -0,0 +1,267 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Key = libsecondlife.LLUUID; +using Rotation = libsecondlife.LLQuaternion; +using Vector = libsecondlife.LLVector3; +using LSLList = System.Collections.Generic.List; + +using OpenSim.Region.Environment.Scenes; +using OpenSim.Region.Environment.LandManagement; +using libsecondlife; + +namespace OpenSim.Region.Scripting +{ + /// + /// A class inteded to act as an API for LSL-styled interpreted languages + /// + /// Avoid at all costs. This should ONLY be used for LSL. + class ScriptInterpretedAPI + { + protected LLUUID m_object; + protected Scene m_scene; + + /// + /// The scene in which this script is acting + /// + public Scene Scene + { + get { return m_scene; } + } + + /// + /// The id of the object our script is supposed to be acting in + /// + public Key ObjectID + { + get { return m_object; } + } + + /// + /// The object our script is supposed to be in + /// + public SceneObjectGroup Task + { + get { return Scene.Objects[ObjectID]; } + } + + /// + /// Creates a new ScriptInterpretedAPI for a specified object + /// + /// The scene the object is located in + /// The specific member being 'occupied' by the script + public ScriptInterpretedAPI(Scene world, libsecondlife.LLUUID member) + { + m_scene = world; + m_object = member; + } + + /// + /// Returns the absolute number of a integer value. + /// + /// Input + /// Absolute number of input + public int osAbs(int val) + { + return Math.Abs(val); + } + + public float osAcos(float val) + { + return (float)Math.Acos(val); + } + + [Obsolete("Unimplemented")] + public void osAddToLandPassList(Key avatar, float hours) + { + Vector myPosition = Task.AbsolutePosition; + Land myParcel = Scene.LandManager.getLandObject(myPosition.X, myPosition.Y); + + OpenSim.Framework.Console.MainLog.Instance.Warn("script", "Unimplemented function called by script: osAddToLandPassList(Key avatar, float hours)"); + return; + } + + [Obsolete("Unimplemented")] + public void osAdjustSoundVolume(float volume) + { + OpenSim.Framework.Console.MainLog.Instance.Warn("script", "Unimplemented function called by script: osAdjustSoundVolume(float volume)"); + return; + } + + [Obsolete("Unimplemented")] + public void osAllowInventoryDrop(int add) + { + return; + } + + [Obsolete("Unimplemented")] + public float osAngleBetween(Rotation a, Rotation b) + { + Axiom.Math.Quaternion axA = new Axiom.Math.Quaternion(a.W, a.X, a.Y, a.Z); + Axiom.Math.Quaternion axB = new Axiom.Math.Quaternion(b.W, b.X, b.Y, b.Z); + + return 0; + } + + [Obsolete("Unimplemented")] + public void osApplyImpulse(Vector force, int local) + { + return; + } + + [Obsolete("Unimplemented")] + public void osApplyRotationalImpulse(Vector force, int local) + { + return; + } + + public float osAsin(float val) + { + return (float)Math.Asin(val); + } + + public float osAtan2(float x, float y) + { + return (float)Math.Atan2(x, y); + } + + [Obsolete("Unimplemented")] + public void osAttachToAvatar(Key avatar, int attachmentPoint) + { + return; + } + + [Obsolete("Unimplemented")] + public Key osAvatarOnSitTarget() + { + //TODO: Follow this as Children is chanced to be of type entity to support ScenePresences + /* + foreach (KeyValuePair Child in Task.Children) + { + if (Child.Value is ScenePresence) + { + return Child.Value.uuid; + } + } + */ + + return Key.Zero; + } + + public Rotation osAxes2Rot(Vector fwd, Vector left, Vector up) + { + Axiom.Math.Quaternion axQ = new Axiom.Math.Quaternion(); + Axiom.Math.Vector3 axFwd = new Axiom.Math.Vector3(fwd.X, fwd.Y, fwd.Z); + Axiom.Math.Vector3 axLeft = new Axiom.Math.Vector3(left.X, left.Y, left.Z); + Axiom.Math.Vector3 axUp = new Axiom.Math.Vector3(up.X, up.Y, up.Z); + + axQ.FromAxes(axFwd, axLeft, axUp); + + return new Rotation(axQ.x, axQ.y, axQ.z, axQ.w); + } + + public Rotation osAxisAngle2Rot(Vector axis, float angle) + { + Axiom.Math.Quaternion axQ = Axiom.Math.Quaternion.FromAngleAxis(angle, new Axiom.Math.Vector3(axis.X, axis.Y, axis.Z)); + + return new Rotation(axQ.x, axQ.y, axQ.z, axQ.w); + } + + public string osBase64ToString(string str) + { + Encoding enc = System.Text.Encoding.UTF8; + return enc.GetString(Convert.FromBase64String(str)); + } + + [Obsolete("Unimplemented")] + public void osBreakAllLinks() + { + return; + } + + [Obsolete("Unimplemented")] + public void osBreakLink() + { + return; + } + + public LSLList osCSV2List(string src) + { + LSLList retVal = new LSLList(); + retVal.AddRange(src.Split(',')); + + return retVal; + } + + public int osCeil(float val) + { + return (int)Math.Ceiling(val); + } + + [Obsolete("Unimplemented")] + public void osCloseRemoteDataChannel(Key channel) + { + return; + } + + [Obsolete("Unimplemented")] + public float osCloud(Vector offset) + { + return 0.0f; + } + + [Obsolete("Unimplemented")] + public void osCollisionFilter(string name, Key id, int accept) + { + return; + } + + [Obsolete("Unimplemented")] + public void osCollisionSprite(string impact_sprite) + { + return; + } + + public float osCos(float theta) + { + return (float)Math.Cos(theta); + } + + public void osCreateLink(Key target, int parent) + { + if(Scene.Entities[target] is SceneObjectGroup) + Task.LinkToGroup((SceneObjectGroup)Scene.Entities[target]); + + return; + } + + [Obsolete("Partially Unimplemented")] + public LSLList osDeleteSubList(LSLList src, int start, int end) + { + if (start < 0 || end < 0) + { + throw new Exception("Unsupported at this time."); + } + + src.RemoveRange(start, start - end + 1); + return src; + } + + [Obsolete("Partially Unimplemented")] + public string osDeleteSubString(string src, int start, int end) + { + if (start < 0 || end < 0) + { + throw new Exception("Unsupported at this time."); + } + + return src.Remove(start, start - end + 1); + } + + [Obsolete("Unimplemented")] + public void osDetachFromAvatar(Key avatar) + { + return; + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/ScriptInterpretedEvents.cs b/OpenSim/Region/Environment/Scenes/Scripting/ScriptInterpretedEvents.cs new file mode 100644 index 0000000000..ca2ec8dec7 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/ScriptInterpretedEvents.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Text; +using OpenSim.Region.Environment.Scenes; +using libsecondlife; +using Key = libsecondlife.LLUUID; + +namespace OpenSim.Region.Scripting +{ + + public class ScriptInterpretedEvents + { + public delegate void OnTouchStartDelegate(Key user); + public event OnTouchStartDelegate OnTouchStart; + + + public void TriggerTouchStart(Key user) + { + if (OnTouchStart != null) + OnTouchStart(user); + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scripting/ScriptManager.cs b/OpenSim/Region/Environment/Scenes/Scripting/ScriptManager.cs new file mode 100644 index 0000000000..406ea36814 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Scripting/ScriptManager.cs @@ -0,0 +1,107 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Collections.Generic; +using OpenSim.Framework.Console; +using OpenSim.Region.Environment.Scenes; + +namespace OpenSim.Region.Scripting +{ + public class ScriptManager + { + List scripts = new List(); + Scene scene; + Dictionary compilers = new Dictionary(); + + private void LoadFromCompiler(Dictionary compiledscripts) + { + foreach (KeyValuePair script in compiledscripts) + { + ScriptInfo scriptInfo = new ScriptInfo(scene); // Since each script could potentially corrupt their access with a stray assignment, making a new one for each script. + MainLog.Instance.Verbose("Loading " + script.Key); + script.Value.Initialise(scriptInfo); + scripts.Add(script.Value); + } + MainLog.Instance.Verbose("Finished loading " + compiledscripts.Count.ToString() + " script(s)"); + } + + public ScriptManager(Scene world) + { + scene = world; + + // Default Engines + CSharpScriptEngine csharpCompiler = new CSharpScriptEngine(); + compilers.Add(csharpCompiler.FileExt(),csharpCompiler); + + JScriptEngine jscriptCompiler = new JScriptEngine(); + compilers.Add(jscriptCompiler.FileExt(), jscriptCompiler); + + JavaEngine javaCompiler = new JavaEngine(); + compilers.Add(javaCompiler.FileExt(), javaCompiler); + } + + public void Compile(string filename) + { + foreach (KeyValuePair compiler in compilers) + { + if (filename.EndsWith(compiler.Key)) + { + LoadFromCompiler(compiler.Value.compile(filename)); + break; + } + } + } + + public void RunScriptCmd(string[] args) + { + switch (args[0]) + { + case "load": + Compile(args[1]); + break; + + default: + MainLog.Instance.Error("Unknown script command"); + break; + } + } + + public void AddPreCompiledScript(IScript script) + { + MainLog.Instance.Verbose("Loading script " + script.Name); + ScriptInfo scriptInfo = new ScriptInfo(scene); // Since each script could potentially corrupt their access with a stray assignment, making a new one for each script. + script.Initialise(scriptInfo); + scripts.Add(script); + } + } + + interface IScriptCompiler + { + Dictionary compile(string filename); + string FileExt(); + } +} diff --git a/OpenSim/Region/Environment/StorageManager.cs b/OpenSim/Region/Environment/StorageManager.cs new file mode 100644 index 0000000000..0d5a1a2a87 --- /dev/null +++ b/OpenSim/Region/Environment/StorageManager.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Text; + +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Servers; +using OpenSim.Region.Capabilities; +using OpenSim.Region.Environment.Scenes; +using OpenSim.Region.Interfaces; + +using System.Reflection; + +namespace OpenSim.Region.Environment +{ + public class StorageManager + { + private IRegionDataStore m_dataStore; + + public IRegionDataStore DataStore + { + get + { + return m_dataStore; + } + } + + public StorageManager(IRegionDataStore storage) + { + m_dataStore = storage; + } + + public StorageManager(string dllName, string dataStoreFile, string dataStoreDB) + { + OpenSim.Framework.Console.MainLog.Instance.Verbose("DATASTORE", "Attempting to load " + dllName); + Assembly pluginAssembly = Assembly.LoadFrom(dllName); + + foreach (Type pluginType in pluginAssembly.GetTypes()) + { + if (pluginType.IsPublic) + { + Type typeInterface = pluginType.GetInterface("IRegionDataStore", true); + + if (typeInterface != null) + { + IRegionDataStore plug = (IRegionDataStore)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString())); + plug.Initialise(dataStoreFile, dataStoreDB); + + m_dataStore = plug; + + OpenSim.Framework.Console.MainLog.Instance.Verbose("DATASTORE", "Added IRegionDataStore Interface"); + } + + typeInterface = null; + } + } + + pluginAssembly = null; + + //TODO: Add checking and warning to make sure it initialised. + } + } +} diff --git a/OpenSim/Region/Examples/SimpleApp/ComplexObject.cs b/OpenSim/Region/Examples/SimpleApp/ComplexObject.cs new file mode 100644 index 0000000000..01af4f0a2b --- /dev/null +++ b/OpenSim/Region/Examples/SimpleApp/ComplexObject.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Text; +using OpenSim.Region.Environment.Scenes; +using Axiom.Math; +using libsecondlife; +using OpenSim.Framework.Types; +using OpenSim.Framework.Interfaces; + +namespace SimpleApp +{ + public class ComplexObject : SceneObjectGroup + { + private LLQuaternion m_rotationDirection; + + private class RotatingWheel : SceneObjectPart + { + private LLQuaternion m_rotationDirection; + + public RotatingWheel(ulong regionHandle, SceneObjectGroup parent, LLUUID ownerID, uint localID, LLVector3 groupPosition, LLVector3 offsetPosition, LLQuaternion rotationDirection) + : base(regionHandle, parent, ownerID, localID, new CylinderShape( 0.5f, 0.2f ), groupPosition, offsetPosition ) + { + m_rotationDirection = rotationDirection; + } + + public override void UpdateMovement() + { + UpdateRotation(RotationOffset * m_rotationDirection); + } + } + + public override void UpdateMovement() + { + UpdateGroupRotation(GroupRotation * m_rotationDirection); + + base.UpdateMovement(); + } + + + + public ComplexObject(Scene scene, ulong regionHandle, LLUUID ownerID, uint localID, LLVector3 pos ) + : base(scene, regionHandle, ownerID, localID, pos, BoxShape.Default ) + { + m_rotationDirection = new LLQuaternion(0.05f, 0.1f, 0.15f); + + AddPart(new RotatingWheel(regionHandle, this, ownerID, scene.PrimIDAllocate(), pos, new LLVector3(0, 0, 0.75f), new LLQuaternion(0.05f,0,0))); + AddPart(new RotatingWheel(regionHandle, this, ownerID, scene.PrimIDAllocate(), pos, new LLVector3(0, 0, -0.75f), new LLQuaternion(-0.05f,0,0))); + + AddPart(new RotatingWheel(regionHandle, this, ownerID, scene.PrimIDAllocate(), pos, new LLVector3(0, 0.75f,0), new LLQuaternion(0.5f, 0, 0.05f))); + AddPart(new RotatingWheel(regionHandle, this, ownerID, scene.PrimIDAllocate(), pos, new LLVector3(0, -0.75f,0), new LLQuaternion(-0.5f, 0, -0.05f))); + + AddPart(new RotatingWheel(regionHandle, this, ownerID, scene.PrimIDAllocate(), pos, new LLVector3(0.75f, 0, 0), new LLQuaternion(0, 0.5f, 0.05f))); + AddPart(new RotatingWheel(regionHandle, this, ownerID, scene.PrimIDAllocate(), pos, new LLVector3(-0.75f, 0, 0), new LLQuaternion(0, -0.5f, -0.05f))); + + UpdateParentIDs(); + } + + public override void OnGrabPart(SceneObjectPart part, LLVector3 offsetPos, IClientAPI remoteClient) + { + m_parts.Remove(part.UUID); + remoteClient.SendKillObject(m_regionHandle, part.LocalID); + remoteClient.AddMoney(1); + remoteClient.SendChatMessage("Poof!", 1, this.AbsolutePosition, "Party Party", LLUUID.Zero); + } + + public override void OnGrabGroup( LLVector3 offsetPos, IClientAPI remoteClient) + { + if( m_parts.Count == 1 ) + { + m_parts.Remove(m_rootPart.UUID); + m_scene.RemoveEntity(this); + remoteClient.SendKillObject(m_regionHandle, m_rootPart.LocalID); + remoteClient.AddMoney(50); + remoteClient.SendChatMessage("KABLAM!!!", 1, AbsolutePosition, "Groupie Groupie", LLUUID.Zero); + } + } + } +} diff --git a/OpenSim/Region/Examples/SimpleApp/CpuCounterObject.cs b/OpenSim/Region/Examples/SimpleApp/CpuCounterObject.cs new file mode 100644 index 0000000000..ce9cd09ade --- /dev/null +++ b/OpenSim/Region/Examples/SimpleApp/CpuCounterObject.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Text; +using OpenSim.Region.Environment.Scenes; +using libsecondlife; +using OpenSim.Framework.Types; +using System.Timers; +using System.Diagnostics; + +namespace SimpleApp +{ + public class CpuCounterObject : SceneObjectGroup + { + private PerformanceCounter m_counter; + + public CpuCounterObject(Scene world, ulong regionHandle, LLUUID ownerID, uint localID, LLVector3 pos ) + : base(world, regionHandle, ownerID, localID, pos, BoxShape.Default ) + { + String objectName = "Processor"; + String counterName = "% Processor Time"; + String instanceName = "_Total"; + + m_counter = new PerformanceCounter(objectName, counterName, instanceName); + } + + public override void UpdateMovement( ) + { + float cpu = m_counter.NextValue() / 40f; + LLVector3 size = new LLVector3(cpu, cpu, cpu); + //rootPrimitive.ResizeGoup( size ); + + base.UpdateMovement(); + } + } +} diff --git a/OpenSim/Region/Examples/SimpleApp/FileSystemObject.cs b/OpenSim/Region/Examples/SimpleApp/FileSystemObject.cs new file mode 100644 index 0000000000..4c0ece8c6a --- /dev/null +++ b/OpenSim/Region/Examples/SimpleApp/FileSystemObject.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Text; +using OpenSim.Region.Environment.Scenes; +using libsecondlife; +using OpenSim.Framework.Types; +using System.Timers; +using System.Diagnostics; +using System.IO; +using Primitive = OpenSim.Region.Environment.Scenes.Primitive; + +namespace SimpleApp +{ + public class FileSystemObject : SceneObjectGroup + { + public FileSystemObject(Scene world, FileInfo fileInfo, LLVector3 pos) + : base(world, world.RegionInfo.RegionHandle, LLUUID.Zero, world.NextLocalId, pos, BoxShape.Default) + { + + + float size = (float)Math.Pow((double)fileInfo.Length, (double)1 / 3) / 5; + // rootPrimitive.ResizeGoup(new LLVector3(size, size, size)); + Text = fileInfo.Name; + ScheduleGroupForFullUpdate(); + } + + public override void Update() + { + base.Update(); + } + } +} diff --git a/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs new file mode 100644 index 0000000000..a6a36f921b --- /dev/null +++ b/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs @@ -0,0 +1,222 @@ +using System.Collections.Generic; +using System.Net; +using System.Timers; +using System; +using System.Text; + +using libsecondlife; +using libsecondlife.Packets; + +using OpenSim.Framework; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Framework.Data; +using OpenSim.Framework.Utilities; +using OpenSim.Region.Environment.Scenes; + +namespace SimpleApp +{ + public class MyNpcCharacter : IClientAPI + { + private uint movementFlag = 0; + private short flyState = 0; + private LLQuaternion bodyDirection = LLQuaternion.Identity; + private short count = 0; + +#pragma warning disable 67 + + public event ImprovedInstantMessage OnInstantMessage; + public event ChatFromViewer OnChatFromViewer; + public event RezObject OnRezObject; + public event ModifyTerrain OnModifyTerrain; + public event SetAppearance OnSetAppearance; + public event StartAnim OnStartAnim; + public event LinkObjects OnLinkObjects; + public event RequestMapBlocks OnRequestMapBlocks; + public event TeleportLocationRequest OnTeleportLocationRequest; + public event DisconnectUser OnDisconnectUser; + public event RequestAvatarProperties OnRequestAvatarProperties; + + public event GenericCall4 OnDeRezObject; + public event GenericCall OnRegionHandShakeReply; + public event GenericCall OnRequestWearables; + public event GenericCall2 OnCompleteMovementToRegion; + public event UpdateAgent OnAgentUpdate; + public event GenericCall OnRequestAvatarsData; + public event AddNewPrim OnAddPrim; + public event ObjectDuplicate OnObjectDuplicate; + public event UpdateVector OnGrabObject; + public event ObjectSelect OnDeGrabObject; + public event MoveObject OnGrabUpdate; + + + public event UpdateShape OnUpdatePrimShape; + public event ObjectExtraParams OnUpdateExtraParams; + public event ObjectSelect OnObjectSelect; + public event GenericCall7 OnObjectDescription; + public event GenericCall7 OnObjectName; + public event UpdatePrimFlags OnUpdatePrimFlags; + public event UpdatePrimTexture OnUpdatePrimTexture; + public event UpdateVector OnUpdatePrimGroupPosition; + public event UpdateVector OnUpdatePrimSinglePosition; + public event UpdatePrimRotation OnUpdatePrimGroupRotation; + public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation; + public event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation; + public event UpdateVector OnUpdatePrimScale; + public event StatusChange OnChildAgentStatus; + public event GenericCall2 OnStopMovement; + public event GenericCall6 OnRemoveAvatar; + + public event CreateNewInventoryItem OnCreateNewInventoryItem; + public event CreateInventoryFolder OnCreateNewInventoryFolder; + public event FetchInventoryDescendents OnFetchInventoryDescendents; + public event FetchInventory OnFetchInventory; + public event RequestTaskInventory OnRequestTaskInventory; + public event UDPAssetUploadRequest OnAssetUploadRequest; + public event XferReceive OnXferReceive; + public event RequestXfer OnRequestXfer; + + public event UUIDNameRequest OnNameFromUUIDRequest; + + public event ParcelPropertiesRequest OnParcelPropertiesRequest; + public event ParcelDivideRequest OnParcelDivideRequest; + public event ParcelJoinRequest OnParcelJoinRequest; + public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest; + + public event ParcelSelectObjects OnParcelSelectObjects; + public event ParcelObjectOwnerRequest OnParcelObjectOwnerRequest; + public event ObjectDeselect OnObjectDeselect; + public event EstateOwnerMessageRequest OnEstateOwnerMessage; + +#pragma warning restore 67 + + private LLUUID myID = LLUUID.Random(); + public MyNpcCharacter( EventManager eventManager ) + { + eventManager.OnFrame += Update; + } + + public virtual LLVector3 StartPos + { + get { return new LLVector3(128, 100, 2); } + set { } + } + + public virtual LLUUID AgentId + { + get { return myID; } + } + + public LLUUID SessionId + { + get { return LLUUID.Zero; } + } + + public virtual string FirstName + { + get { return "Annoying"; } + } + + public virtual string LastName + { + get { return "NPC"; } + } + + public virtual void OutPacket(Packet newPack) { } + public virtual void SendWearables(AvatarWearable[] wearables) { } + public virtual void SendAppearance(LLUUID agentID, byte[] visualParams, byte[] textureEntry) { } + public virtual void SendStartPingCheck(byte seq) { } + public virtual void SendKillObject(ulong regionHandle, uint localID) { } + public virtual void SendAnimation(LLUUID animID, int seq, LLUUID sourceAgentId) { } + public virtual void SendChatMessage(string message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID) { } + public virtual void SendChatMessage(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID) { } + public virtual void SendInstantMessage(string message, LLUUID target, string fromName) { } + public virtual void SendLayerData(float[] map) { } + public virtual void SendLayerData(int px, int py, float[] map) { } + public virtual void MoveAgentIntoRegion(RegionInfo regInfo, LLVector3 pos, LLVector3 look) { } + public virtual void InformClientOfNeighbour(ulong neighbourHandle, IPEndPoint neighbourExternalEndPoint) { } + public virtual AgentCircuitData RequestClientInfo() { return new AgentCircuitData(); } + public virtual void CrossRegion(ulong newRegionHandle, LLVector3 pos, LLVector3 lookAt, IPEndPoint newRegionExternalEndPoint, string capsURL) { } + public virtual void SendMapBlock(List mapBlocks) { } + public virtual void SendLocalTeleport(LLVector3 position, LLVector3 lookAt, uint flags) { } + public virtual void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint, uint locationID, uint flags, string capsURL) { } + public virtual void SendTeleportCancel() { } + public virtual void SendTeleportLocationStart() { } + public virtual void SendMoneyBalance(LLUUID transaction, bool success, byte[] description, int balance) { } + + public virtual void SendAvatarData(ulong regionHandle, string firstName, string lastName, LLUUID avatarID, uint avatarLocalID, LLVector3 Pos, byte[] textureEntry) { } + public virtual void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLVector3 velocity) { } + + public virtual void AttachObject(uint localID, LLQuaternion rotation, byte attachPoint) { } + + public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, LLVector3 pos, uint flags, LLUUID objectID, LLUUID ownerID, string text, uint parentID, byte[] particleSystem, LLQuaternion rotation) { } + public virtual void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLQuaternion rotation) { } + + public virtual void SendInventoryFolderDetails(LLUUID ownerID, LLUUID folderID, List items) { } + public virtual void SendInventoryItemDetails(LLUUID ownerID, InventoryItemBase item) { } + public virtual void SendInventoryItemUpdate(InventoryItemBase Item) { } + public virtual void SendRemoveInventoryItem(LLUUID itemID) { } + public virtual void SendTaskInventory(LLUUID taskID, short serial, byte[] fileName) { } + public virtual void SendXferPacket(ulong xferID, uint packet, byte[] data) { } + + public virtual void SendNameReply(LLUUID profileId, string firstname, string lastname) { } + + public virtual void SendPreLoadSound(LLUUID objectID, LLUUID ownerID, LLUUID soundID) { } + public virtual void SendPlayAttachedSound(LLUUID soundID, LLUUID objectID, LLUUID ownerID, float gain, byte flags) { } + + public void SendAlertMessage(string message) { } + public void SendAgentAlertMessage(string message, bool modal) { } + public void SendLoadURL(string objectname, LLUUID objectID, LLUUID ownerID, bool groupOwned, string message, string url) { } + + public virtual void SendRegionHandshake(RegionInfo regionInfo) + { + this.OnRegionHandShakeReply(this); + this.OnCompleteMovementToRegion(); + } + + private void Update( ) + { + Encoding enc = Encoding.ASCII; + + if (this.OnAgentUpdate != null) + { + this.OnAgentUpdate(this, movementFlag, bodyDirection); + } + if (this.flyState == 0) + { + movementFlag = (uint)MainAvatar.ControlFlags.AGENT_CONTROL_FLY | (uint)MainAvatar.ControlFlags.AGENT_CONTROL_UP_NEG; + flyState = 1; + } + else if (this.flyState == 1) + { + movementFlag = (uint)MainAvatar.ControlFlags.AGENT_CONTROL_FLY | (uint)MainAvatar.ControlFlags.AGENT_CONTROL_UP_POS; + flyState = 2; + } + else + { + movementFlag = (uint)MainAvatar.ControlFlags.AGENT_CONTROL_FLY; + flyState = 0; + } + + if (count >= 40) + { + if (OnChatFromViewer != null) + { + this.OnChatFromViewer(enc.GetBytes("Kind of quiet around here, isn't it! \0"), 2, new LLVector3(128, 128, 26), this.FirstName + " " + this.LastName, this.AgentId); + } + count = -1; + + } + + count++; + } + + public bool AddMoney(int debit) + { + return false; + } + + public void SendViewerTime(int phase) { } + public void SendAvatarProperties(LLUUID avatarID, string aboutText, string bornOn, string charterMember, string flAbout, uint flags, LLUUID flImageID, LLUUID imageID, string profileURL, LLUUID partnerID) { } + } +} diff --git a/OpenSim/Region/Examples/SimpleApp/MyWorld.cs b/OpenSim/Region/Examples/SimpleApp/MyWorld.cs new file mode 100644 index 0000000000..2c62316276 --- /dev/null +++ b/OpenSim/Region/Examples/SimpleApp/MyWorld.cs @@ -0,0 +1,85 @@ +using System.Collections.Generic; +using libsecondlife; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Types; + +using OpenSim.Region.Environment.Scenes; +using OpenSim.Region.Terrain; +using OpenSim.Region.Environment; +using OpenSim.Framework.Communications.Caches; + +using Avatar=OpenSim.Region.Environment.Scenes.ScenePresence; + +namespace SimpleApp +{ + public class MyWorld : Scene + { + private List m_avatars; + + public MyWorld( RegionInfo regionInfo, AgentCircuitManager authen, CommunicationsManager commsMan, AssetCache assetCach, StorageManager storeMan, BaseHttpServer httpServer) + : base( regionInfo, authen, commsMan, assetCach, storeMan, httpServer) + { + m_avatars = new List(); + } + + public override void LoadWorldMap() + { + float[] map = new float[65536]; + + for (int i = 0; i < 65536; i++) + { + int x = i % 256; + int y = i / 256; + + map[i] = 25f; + } + + this.Terrain.GetHeights1D(map); + this.CreateTerrainTexture(); + } + + public override void ProcessObjectGrab(uint localID, LLVector3 offsetPos, IClientAPI remoteClient) + { + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + SceneObjectGroup obj = ent as SceneObjectGroup; + + if( obj.HasChildPrim( localID ) ) + { + obj.ObjectGrabHandler(localID, offsetPos, remoteClient); + return; + } + } + } + + base.ProcessObjectGrab(localID, offsetPos, remoteClient); + } + + #region IWorld Members + + override public void AddNewClient(IClientAPI client, bool child) + { + SubscribeToClientEvents(client); + + ScenePresence avatar = CreateAndAddScenePresence(client); + avatar.AbsolutePosition = new LLVector3(128, 128, 26); + + LLVector3 pos = new LLVector3(128, 128, 128); + + client.OnCompleteMovementToRegion += delegate() + { + client.SendChatMessage("Welcome to My World.", 1, pos, "System", LLUUID.Zero ); + }; + + + client.SendRegionHandshake(m_regInfo); + } + + #endregion + } +} diff --git a/OpenSim/Region/Examples/SimpleApp/Program.cs b/OpenSim/Region/Examples/SimpleApp/Program.cs new file mode 100644 index 0000000000..44ca93bdfe --- /dev/null +++ b/OpenSim/Region/Examples/SimpleApp/Program.cs @@ -0,0 +1,142 @@ +using System; +using System.Net; +using libsecondlife; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Types; +using OpenSim.Physics.Manager; + +using OpenSim.Region.Capabilities; +using OpenSim.Region.ClientStack; +using OpenSim.Region.Communications.Local; +using OpenSim.Framework.Communications.Caches; +using OpenSim.Region.GridInterfaces.Local; +using System.Timers; +using OpenSim.Region.Environment.Scenes; +using OpenSim.Framework.Data; +using OpenSim.Region.Environment; +using System.IO; + +namespace SimpleApp +{ + class Program : RegionApplicationBase, conscmd_callback + { + protected override LogBase CreateLog() + { + return new LogBase(null, "SimpleApp", this, false); + } + + protected override void Initialize() + { + m_httpServerPort = 9000; + + StartLog(); + + m_networkServersInfo = new NetworkServersInfo( 1000, 1000 ); + + LocalAssetServer assetServer = new LocalAssetServer(); + assetServer.SetServerInfo("http://localhost:8003/", ""); + + m_assetCache = new AssetCache(assetServer); + } + + public void Run() + { + base.StartUp(); + + CommunicationsLocal.LocalSettings settings = new CommunicationsLocal.LocalSettings("", false, "", ""); + m_commsManager = new CommunicationsLocal(m_networkServersInfo, m_httpServer, m_assetCache, settings); + + m_log.Notice(m_log.LineInfo); + + ScenePresence.PhysicsEngineFlying = true; + + IPEndPoint internalEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9000); + + RegionInfo regionInfo = new RegionInfo(1000, 1000, internalEndPoint, "localhost"); + regionInfo.DataStore = "simpleapp_datastore.yap"; + + UDPServer udpServer; + + Scene scene = SetupScene(regionInfo, out udpServer); + scene.StartTimer(); + + udpServer.ServerListener(); + + LLVector3 pos = new LLVector3(110, 129, 27); + + SceneObjectGroup sceneObject = new CpuCounterObject(scene, regionInfo.RegionHandle, LLUUID.Zero, scene.PrimIDAllocate(), pos + new LLVector3( 1f, 1f, 1f )); + scene.AddEntity(sceneObject); + + for (int i = 0; i < 27; i++) + { + LLVector3 posOffset = new LLVector3( (i%3)*4, (i%9)/3 * 4, (i/9) * 4 ); + ComplexObject complexObject = new ComplexObject(scene, regionInfo.RegionHandle, LLUUID.Zero, scene.PrimIDAllocate(), pos + posOffset ); + scene.AddEntity(complexObject); + } + + MyNpcCharacter m_character = new MyNpcCharacter(scene.EventManager); + scene.AddNewClient(m_character, false); + + DirectoryInfo dirInfo = new DirectoryInfo( "." ); + + float x = 0; + float z = 0; + + foreach( FileInfo fileInfo in dirInfo.GetFiles()) + { + LLVector3 filePos = new LLVector3(100 + x, 129, 27 + z); + x = x + 2; + if( x > 50 ) + { + x = 0; + z = z + 2; + } + + FileSystemObject fileObject = new FileSystemObject( scene, fileInfo, filePos ); + scene.AddEntity(fileObject); + } + + m_log.Notice("Press enter to quit."); + m_log.ReadLine(); + } + + protected override Scene CreateScene(RegionInfo regionInfo, StorageManager storageManager, AgentCircuitManager circuitManager) + { + return new MyWorld(regionInfo, circuitManager, m_commsManager, m_assetCache, storageManager, m_httpServer); + } + + protected override StorageManager CreateStorageManager(RegionInfo regionInfo) + { + return new StorageManager("OpenSim.DataStore.NullStorage.dll", "simpleapp.yap", "simpleapp"); + } + + protected override PhysicsScene GetPhysicsScene( ) + { + return GetPhysicsScene("basicphysics"); + } + + #region conscmd_callback Members + + public void RunCmd(string cmd, string[] cmdparams) + { + throw new Exception("The method or operation is not implemented."); + } + + public void Show(string ShowWhat) + { + throw new Exception("The method or operation is not implemented."); + } + + #endregion + + static void Main(string[] args) + { + Program app = new Program(); + + app.Run(); + } + } +} diff --git a/OpenSim/Region/Examples/SimpleApp/Properties/AssemblyInfo.cs b/OpenSim/Region/Examples/SimpleApp/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..3b0de8a3e2 --- /dev/null +++ b/OpenSim/Region/Examples/SimpleApp/Properties/AssemblyInfo.cs @@ -0,0 +1,31 @@ +using System.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("SimpleApp")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Playahead AB")] +[assembly: AssemblyProduct("SimpleApp")] +[assembly: AssemblyCopyright("Copyright © Playahead AB 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("a5cfa45f-5acf-4b2e-9c50-1dd1fd7608ee")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/GridInterfaces/Local/AssemblyInfo.cs b/OpenSim/Region/GridInterfaces/Local/AssemblyInfo.cs new file mode 100644 index 0000000000..b5fc1ef917 --- /dev/null +++ b/OpenSim/Region/GridInterfaces/Local/AssemblyInfo.cs @@ -0,0 +1,56 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Reflection; +using System.Runtime.InteropServices; +// Information about this assembly is defined by the following +// attributes. +// +// change them to the information which is associated with the assembly +// you compile. + +[assembly: AssemblyTitle("LocalGridServers")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("LocalGridServers")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. +[assembly: ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all values by your own or you can build default build and revision +// numbers with the '*' character (the default): + +[assembly: AssemblyVersion("1.0.*")] diff --git a/OpenSim/Region/GridInterfaces/Local/LocalAssetServer.cs b/OpenSim/Region/GridInterfaces/Local/LocalAssetServer.cs new file mode 100644 index 0000000000..26641919e5 --- /dev/null +++ b/OpenSim/Region/GridInterfaces/Local/LocalAssetServer.cs @@ -0,0 +1,401 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.IO; +using System.Threading; +using Db4objects.Db4o; +using Db4objects.Db4o.Query; +using libsecondlife; +using Nini.Config; +using OpenSim.Framework.Console; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Framework.Utilities; + +namespace OpenSim.Region.GridInterfaces.Local +{ + public class LocalAssetPlugin : IAssetPlugin + { + public LocalAssetPlugin() + { + + } + + public IAssetServer GetAssetServer() + { + return (new LocalAssetServer()); + } + } + + public class LocalAssetServer : IAssetServer + { + private IAssetReceiver _receiver; + private BlockingQueue _assetRequests; + private IObjectContainer db; + private Thread _localAssetServerThread; + + public LocalAssetServer() + { + bool yapfile; + this._assetRequests = new BlockingQueue(); + yapfile = File.Exists(Path.Combine(Util.dataDir(),"regionassets.yap")); + + MainLog.Instance.Verbose("Local Asset Server class created"); + db = Db4oFactory.OpenFile(Path.Combine(Util.dataDir(),"regionassets.yap")); + MainLog.Instance.Verbose("Db4 Asset database creation"); + + if (!yapfile) + { + this.SetUpAssetDatabase(); + } + + this._localAssetServerThread = new Thread(new ThreadStart(RunRequests)); + this._localAssetServerThread.IsBackground = true; + this._localAssetServerThread.Start(); + + } + + public void SetReceiver(IAssetReceiver receiver) + { + this._receiver = receiver; + } + + public void RequestAsset(LLUUID assetID, bool isTexture) + { + ARequest req = new ARequest(); + req.AssetID = assetID; + req.IsTexture = isTexture; + this._assetRequests.Enqueue(req); + } + + public void UpdateAsset(AssetBase asset) + { + + } + + public void UploadNewAsset(AssetBase asset) + { + AssetStorage store = new AssetStorage(); + store.Data = asset.Data; + store.Name = asset.Name; + store.UUID = asset.FullID; + db.Set(store); + db.Commit(); + } + + public void SetServerInfo(string ServerUrl, string ServerKey) + { + + } + public void Close() + { + if (db != null) + { + MainLog.Instance.Verbose("Closing local asset server database"); + db.Close(); + } + } + + private void RunRequests() + { + while (true) + { + byte[] idata = null; + bool found = false; + AssetStorage foundAsset = null; + ARequest req = this._assetRequests.Dequeue(); + IObjectSet result = db.Query(new AssetUUIDQuery(req.AssetID)); + if (result.Count > 0) + { + foundAsset = (AssetStorage)result.Next(); + found = true; + } + + AssetBase asset = new AssetBase(); + if (found) + { + asset.FullID = foundAsset.UUID; + asset.Type = foundAsset.Type; + asset.InvType = foundAsset.Type; + asset.Name = foundAsset.Name; + idata = foundAsset.Data; + } + else + { + asset.FullID = LLUUID.Zero; + } + asset.Data = idata; + _receiver.AssetReceived(asset, req.IsTexture); + } + + } + + private void SetUpAssetDatabase() + { + MainLog.Instance.Verbose("Setting up asset database"); + + AssetBase Image = new AssetBase(); + Image.FullID = new LLUUID("00000000-0000-0000-9999-000000000001"); + Image.Name = "Bricks"; + this.LoadAsset(Image, true, "bricks.jp2"); + AssetStorage store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + Image = new AssetBase(); + Image.FullID = new LLUUID("00000000-0000-0000-9999-000000000002"); + Image.Name = "Plywood"; + this.LoadAsset(Image, true, "plywood.jp2"); + store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + Image = new AssetBase(); + Image.FullID = new LLUUID("00000000-0000-0000-9999-000000000003"); + Image.Name = "Rocks"; + this.LoadAsset(Image, true, "rocks.jp2"); + store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + Image = new AssetBase(); + Image.FullID = new LLUUID("00000000-0000-0000-9999-000000000004"); + Image.Name = "Granite"; + this.LoadAsset(Image, true, "granite.jp2"); + store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + Image = new AssetBase(); + Image.FullID = new LLUUID("00000000-0000-0000-9999-000000000005"); + Image.Name = "Hardwood"; + this.LoadAsset(Image, true, "hardwood.jp2"); + store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + Image = new AssetBase(); + Image.FullID = new LLUUID("00000000-0000-0000-5005-000000000005"); + Image.Name = "Prim Base Texture"; + this.LoadAsset(Image, true, "plywood.jp2"); + store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + Image = new AssetBase(); + Image.FullID = new LLUUID("00000000-0000-0000-9999-000000000006"); + Image.Name = "Map Base Texture"; + this.LoadAsset(Image, true, "map_base.jp2"); + store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + Image = new AssetBase(); + Image.FullID = new LLUUID("00000000-0000-0000-9999-000000000007"); + Image.Name = "Map Texture"; + this.LoadAsset(Image, true, "map1.jp2"); + store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + Image = new AssetBase(); + Image.FullID = new LLUUID("00000000-0000-1111-9999-000000000010"); + Image.Name = "Female Body Texture"; + this.LoadAsset(Image, true, "femalebody.jp2"); + store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + Image = new AssetBase(); + Image.FullID = new LLUUID("00000000-0000-1111-9999-000000000011"); + Image.Name = "Female Bottom Texture"; + this.LoadAsset(Image, true, "femalebottom.jp2"); + store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + Image = new AssetBase(); + Image.FullID = new LLUUID("00000000-0000-1111-9999-000000000012"); + Image.Name = "Female Face Texture"; + this.LoadAsset(Image, true, "femaleface.jp2"); + store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + Image = new AssetBase(); + Image.FullID = new LLUUID("77c41e39-38f9-f75a-024e-585989bbabbb"); + Image.Name = "Skin"; + Image.Type = 13; + Image.InvType = 13; + this.LoadAsset(Image, false, "base_skin.dat"); + store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + + Image = new AssetBase(); + Image.FullID = new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73"); + Image.Name = "Shape"; + Image.Type = 13; + Image.InvType = 13; + this.LoadAsset(Image, false, "base_shape.dat"); + store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + Image = new AssetBase(); + Image.FullID = new LLUUID("00000000-38f9-1111-024e-222222111110"); + Image.Name = "Shirt"; + Image.Type = 5; + Image.InvType = 18; + this.LoadAsset(Image, false, "newshirt.dat"); + store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + Image = new AssetBase(); + Image.FullID = new LLUUID("00000000-38f9-1111-024e-222222111120"); + Image.Name = "Shirt"; + Image.Type = 5; + Image.InvType = 18; + this.LoadAsset(Image, false, "newpants.dat"); + store = new AssetStorage(); + store.Data = Image.Data; + store.Name = Image.Name; + store.UUID = Image.FullID; + db.Set(store); + db.Commit(); + + string filePath = Path.Combine(Util.configDir(), "OpenSimAssetSet.xml"); + if(File.Exists(filePath)) + { + XmlConfigSource source = new XmlConfigSource(filePath); + ReadAssetDetails(source); + } + } + + protected void ReadAssetDetails(IConfigSource source) + { + AssetBase newAsset = null; + for (int i = 0; i < source.Configs.Count; i++) + { + newAsset = new AssetBase(); + newAsset.FullID = new LLUUID(source.Configs[i].GetString("assetID", LLUUID.Random().ToStringHyphenated())); + newAsset.Name = source.Configs[i].GetString("name", ""); + newAsset.Type =(sbyte) source.Configs[i].GetInt("assetType", 0); + newAsset.InvType =(sbyte) source.Configs[i].GetInt("inventoryType", 0); + string fileName = source.Configs[i].GetString("fileName", ""); + if (fileName != "") + { + this.LoadAsset(newAsset, false, fileName); + AssetStorage store = new AssetStorage(); + store.Data = newAsset.Data; + store.Name = newAsset.Name; + store.UUID = newAsset.FullID; + db.Set(store); + db.Commit(); + } + } + } + + private void LoadAsset(AssetBase info, bool image, string filename) + { + //should request Asset from storage manager + //but for now read from file + + string dataPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "assets"); //+ folder; + string fileName = Path.Combine(dataPath, filename); + FileInfo fInfo = new FileInfo(fileName); + long numBytes = fInfo.Length; + FileStream fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read); + byte[] idata = new byte[numBytes]; + BinaryReader br = new BinaryReader(fStream); + idata = br.ReadBytes((int)numBytes); + br.Close(); + fStream.Close(); + info.Data = idata; + //info.loaded=true; + } + } + public class AssetUUIDQuery : Predicate + { + private LLUUID _findID; + + public AssetUUIDQuery(LLUUID find) + { + _findID = find; + } + public bool Match(AssetStorage asset) + { + return (asset.UUID == _findID); + } + } + +} diff --git a/OpenSim/Region/GridInterfaces/Remote/AssemblyInfo.cs b/OpenSim/Region/GridInterfaces/Remote/AssemblyInfo.cs new file mode 100644 index 0000000000..1e15c5ea9f --- /dev/null +++ b/OpenSim/Region/GridInterfaces/Remote/AssemblyInfo.cs @@ -0,0 +1,56 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Reflection; +using System.Runtime.InteropServices; +// Information about this assembly is defined by the following +// attributes. +// +// change them to the information which is associated with the assembly +// you compile. + +[assembly: AssemblyTitle("RemoteGridServers")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RemoteGridServers")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. +[assembly: ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all values by your own or you can build default build and revision +// numbers with the '*' character (the default): + +[assembly: AssemblyVersion("1.0.*")] diff --git a/OpenSim/Region/GridInterfaces/Remote/RemoteAssetServer.cs b/OpenSim/Region/GridInterfaces/Remote/RemoteAssetServer.cs new file mode 100644 index 0000000000..8643736277 --- /dev/null +++ b/OpenSim/Region/GridInterfaces/Remote/RemoteAssetServer.cs @@ -0,0 +1,133 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.IO; +using System.Net; +using System.Text; +using System.Threading; +using libsecondlife; +using OpenSim.Framework.Console; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Framework.Utilities; + +namespace OpenSim.Region.GridInterfaces.Remote +{ + public class RemoteAssetServer : IAssetServer + { + private IAssetReceiver _receiver; + private BlockingQueue _assetRequests; + private Thread _remoteAssetServerThread; + private string AssetServerUrl; + private string AssetSendKey; + + public RemoteAssetServer() + { + this._assetRequests = new BlockingQueue(); + this._remoteAssetServerThread = new Thread(new ThreadStart(RunRequests)); + this._remoteAssetServerThread.IsBackground = true; + this._remoteAssetServerThread.Start(); + MainLog.Instance.Verbose("Remote Asset Server class created"); + } + + public void SetReceiver(IAssetReceiver receiver) + { + this._receiver = receiver; + } + + public void RequestAsset(LLUUID assetID, bool isTexture) + { + ARequest req = new ARequest(); + req.AssetID = assetID; + req.IsTexture = isTexture; + this._assetRequests.Enqueue(req); + } + + public void UpdateAsset(AssetBase asset) + { + + } + + public void UploadNewAsset(AssetBase asset) + { + Encoding Windows1252Encoding = Encoding.GetEncoding(1252); + string ret = Windows1252Encoding.GetString(asset.Data); + byte[] buffer = Windows1252Encoding.GetBytes(ret); + WebClient client = new WebClient(); + client.UploadData(this.AssetServerUrl + "assets/" + asset.FullID, buffer); + + } + + public void SetServerInfo(string ServerUrl, string ServerKey) + { + this.AssetServerUrl = ServerUrl; + this.AssetSendKey = ServerKey; + } + + private void RunRequests() + { + while (true) + { + //we need to add support for the asset server not knowing about a requested asset + // 404... THE MAGIC FILE NOT FOUND ERROR, very useful for telling you things such as a file (or asset ;) ) not being found!!!!!!!!!!! it's 2:22AM + ARequest req = this._assetRequests.Dequeue(); + LLUUID assetID = req.AssetID; + // OpenSim.Framework.Console.MainLog.Instance.Verbose(" RemoteAssetServer- Got a AssetServer request, processing it - " + this.AssetServerUrl + "assets/" + assetID); + WebRequest AssetLoad = WebRequest.Create(this.AssetServerUrl + "assets/" + assetID); + WebResponse AssetResponse = AssetLoad.GetResponse(); + byte[] idata = new byte[(int)AssetResponse.ContentLength]; + BinaryReader br = new BinaryReader(AssetResponse.GetResponseStream()); + idata = br.ReadBytes((int)AssetResponse.ContentLength); + br.Close(); + + AssetBase asset = new AssetBase(); + asset.FullID = assetID; + asset.Data = idata; + _receiver.AssetReceived(asset, req.IsTexture); + } + } + + public void Close() + { + + } + } + + public class RemoteAssetPlugin : IAssetPlugin + { + public RemoteAssetPlugin() + { + + } + + public IAssetServer GetAssetServer() + { + return (new RemoteAssetServer()); + } + } + +} diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs new file mode 100644 index 0000000000..ce567a9a29 --- /dev/null +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs @@ -0,0 +1,56 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Reflection; +using System.Runtime.InteropServices; +// Information about this assembly is defined by the following +// attributes. +// +// change them to the information which is associated with the assembly +// you compile. + +[assembly: AssemblyTitle("PhysXplugin")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("PhysXplugin")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. +[assembly: ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all values by your own or you can build default build and revision +// numbers with the '*' character (the default): + +[assembly: AssemblyVersion("1.0.*")] diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs new file mode 100644 index 0000000000..2e58e102fe --- /dev/null +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs @@ -0,0 +1,277 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Collections.Generic; +using Axiom.Math; +using OpenSim.Physics.Manager; + +namespace OpenSim.Region.Physics.BasicPhysicsPlugin +{ + /// + /// Will be the PhysX plugin but for now will be a very basic physics engine + /// + public class BasicPhysicsPlugin : IPhysicsPlugin + { + public BasicPhysicsPlugin() + { + + } + + public bool Init() + { + return true; + } + + public PhysicsScene GetScene() + { + return new BasicScene(); + } + + public string GetName() + { + return ("basicphysics"); + } + + public void Dispose() + { + + } + } + + public class BasicScene : PhysicsScene + { + private List _actors = new List(); + private float[] _heightMap; + + public BasicScene() + { + + } + + public override PhysicsActor AddAvatar(PhysicsVector position) + { + BasicActor act = new BasicActor(); + act.Position = position; + _actors.Add(act); + return act; + } + + public override void RemoveAvatar(PhysicsActor actor) + { + BasicActor act = (BasicActor)actor; + if (_actors.Contains(act)) + { + _actors.Remove(act); + } + + } + + public override PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size, Quaternion rotation) + { + return null; + } + + public override void Simulate(float timeStep) + { + foreach (BasicActor actor in _actors) + { + actor.Position.X = actor.Position.X + (actor.Velocity.X * timeStep); + actor.Position.Y = actor.Position.Y + (actor.Velocity.Y * timeStep); + if (actor.Position.Y < 0) + { + actor.Position.Y = 0.1F; + } + else if (actor.Position.Y >= 256) + { + actor.Position.Y = 255.9F; + } + + if (actor.Position.X < 0) + { + actor.Position.X = 0.1F; + } + else if (actor.Position.X > 256) + { + actor.Position.X = 255.9F; + } + + float height = _heightMap[(int)actor.Position.Y * 256 + (int)actor.Position.X] + 1.2f; + if (actor.Flying) + { + if (actor.Position.Z + (actor.Velocity.Z * timeStep) < _heightMap[(int)actor.Position.Y * 256 + (int)actor.Position.X] + 2) + { + actor.Position.Z = height; + actor.Velocity.Z = 0; + } + else + { + actor.Position.Z = actor.Position.Z + (actor.Velocity.Z * timeStep); + } + } + else + { + actor.Position.Z = height; + actor.Velocity.Z = 0; + } + + + } + } + + public override void GetResults() + { + + } + + public override bool IsThreaded + { + get + { + return (false); // for now we won't be multithreaded + } + } + + public override void SetTerrain(float[] heightMap) + { + this._heightMap = heightMap; + } + + public override void DeleteTerrain() + { + + } + } + + public class BasicActor : PhysicsActor + { + private PhysicsVector _position; + private PhysicsVector _velocity; + private PhysicsVector _acceleration; + private bool flying; + public BasicActor() + { + _velocity = new PhysicsVector(); + _position = new PhysicsVector(); + _acceleration = new PhysicsVector(); + } + + public override bool Flying + { + get + { + return flying; + } + set + { + flying = value; + } + } + + public override PhysicsVector Position + { + get + { + return _position; + } + set + { + _position = value; + } + } + + public override PhysicsVector Size + { + get + { + return new PhysicsVector(0, 0, 0); + } + set + { + } + } + + public override PhysicsVector Velocity + { + get + { + return _velocity; + } + set + { + _velocity = value; + } + } + + public override Quaternion Orientation + { + get + { + return Quaternion.Identity; + } + set + { + + } + } + + public override PhysicsVector Acceleration + { + get + { + return _acceleration; + } + + } + + public override bool Kinematic + { + get + { + return true; + } + set + { + + } + } + public void SetAcceleration(PhysicsVector accel) + { + this._acceleration = accel; + } + + public override void AddForce(PhysicsVector force) + { + + } + + public override void SetMomentum(PhysicsVector momentum) + { + + } + } + +} diff --git a/OpenSim/Region/Physics/BulletXPlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/BulletXPlugin/AssemblyInfo.cs new file mode 100644 index 0000000000..bda35f7aa5 --- /dev/null +++ b/OpenSim/Region/Physics/BulletXPlugin/AssemblyInfo.cs @@ -0,0 +1,56 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Reflection; +using System.Runtime.InteropServices; +// Information about this assembly is defined by the following +// attributes. +// +// change them to the information which is associated with the assembly +// you compile. + +[assembly: AssemblyTitle("BulletXPlugin")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("BulletXPlugin")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. +[assembly: ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all values by your own or you can build default build and revision +// numbers with the '*' character (the default): + +[assembly: AssemblyVersion("1.0.0.0")] diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs new file mode 100644 index 0000000000..1ca5efebec --- /dev/null +++ b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs @@ -0,0 +1,534 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +#region References +using System; +using System.Collections.Generic; +using OpenSim.Physics.Manager; +using Axiom.Math; +//Specific References for BulletXPlugin +using MonoXnaCompactMaths; +using XnaDevRu.BulletX; +using XnaDevRu.BulletX.Dynamics; +#endregion + +namespace OpenSim.Region.Physics.BulletXPlugin +{ + /// + /// This Class converts objects and types for BulletX + /// + public class BulletXConversions + { + public static MonoXnaCompactMaths.Vector3 PhysicsVectorToXnaVector3(PhysicsVector physicsVector) + { + return new MonoXnaCompactMaths.Vector3(physicsVector.X, physicsVector.Y, physicsVector.Z); + } + public static void PhysicsVectorToXnaVector3(PhysicsVector physicsVector, out MonoXnaCompactMaths.Vector3 XnaVector3) + { + XnaVector3.X = physicsVector.X; + XnaVector3.Y = physicsVector.Y; + XnaVector3.Z = physicsVector.Z; + } + public static PhysicsVector XnaVector3ToPhysicsVector(MonoXnaCompactMaths.Vector3 xnaVector3) + { + return new PhysicsVector(xnaVector3.X, xnaVector3.Y, xnaVector3.Z); + } + /*public static void XnaVector3ToPhysicsVector(MonoXnaCompactMaths.Vector3 xnaVector3, out PhysicsVector physicsVector) + { + xnaVector3.X = physicsVector.X; + xnaVector3.Y = physicsVector.Y; + xnaVector3.Z = physicsVector.Z; + }*/ + #region Axiom and Xna + ///// + ///// BTW maybe some conversions will be a simply converion that it doesn't require this class, but i don't know + ///// + ///// + ///// + //public static MonoXnaCompactMaths.Vector3 Vector3AxiomToXna(Axiom.Math.Vector3 AxiomVector3) + //{ + // return new MonoXnaCompactMaths.Vector3(AxiomVector3.x, AxiomVector3.y, AxiomVector3.z); + //} + #endregion + } + /// + /// PhysicsPlugin Class for BulletX + /// + public class BulletXPlugin : IPhysicsPlugin + { + private BulletXScene _mScene; + + public BulletXPlugin() + { + } + public bool Init() + { + return true; + } + public PhysicsScene GetScene() + { + if (_mScene == null) + { + _mScene = new BulletXScene(); + } + return (_mScene); + } + public string GetName() + { + return ("BulletXEngine"); + } + public void Dispose() + { + } + } + /// + /// PhysicsScene Class for BulletX + /// + public class BulletXScene : PhysicsScene + { + public DiscreteDynamicsWorld ddWorld; + private CollisionDispatcher cDispatcher; + private OverlappingPairCache opCache; + private SequentialImpulseConstraintSolver sicSolver; + + private const int minXY = 0; + private const int minZ = 0; + private const int maxXY = 256; + private const int maxZ = 4096; + private const int maxHandles = 32766; //Why? I don't know + private static float gravity = 9.8f; + private static float heightLevel0 = 77.0f; + private static float heightLevel1 = 200.0f; + private static float lowGravityFactor = 0.2f; + + private float[] _heightmap; + private List _characters = new List(); + + public static float Gravity { get { return gravity; } } + public static float HeightLevel0 { get { return heightLevel0; } } + public static float HeightLevel1 { get { return heightLevel1; } } + public static float LowGravityFactor { get { return lowGravityFactor; } } + + public BulletXScene() + { + cDispatcher = new CollisionDispatcher(); + MonoXnaCompactMaths.Vector3 worldMinDim = new MonoXnaCompactMaths.Vector3((float)minXY, (float)minXY, (float)minZ); + MonoXnaCompactMaths.Vector3 worldMaxDim = new MonoXnaCompactMaths.Vector3((float)maxXY, (float)maxXY, (float)maxZ); + opCache = new AxisSweep3(worldMinDim, worldMaxDim, maxHandles); + sicSolver = new SequentialImpulseConstraintSolver(); + + ddWorld = new DiscreteDynamicsWorld(cDispatcher, opCache, sicSolver); + ddWorld.Gravity = new MonoXnaCompactMaths.Vector3(0, 0, -gravity); + + this._heightmap = new float[65536]; + } + + public override PhysicsActor AddAvatar(PhysicsVector position) + { + PhysicsVector pos = new PhysicsVector(); + pos.X = position.X; + pos.Y = position.Y; + pos.Z = position.Z + 20; + BulletXCharacter newAv = new BulletXCharacter(this, pos); + this._characters.Add(newAv); + return newAv; + } + + public override void RemoveAvatar(PhysicsActor actor) + { + + } + + public override PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size) + { + PhysicsVector pos = new PhysicsVector(); + pos.X = position.X; + pos.Y = position.Y; + pos.Z = position.Z; + PhysicsVector siz = new PhysicsVector(); + siz.X = size.X; + siz.Y = size.Y; + siz.Z = size.Z; + return new BulletXPrim(); + } + + public override void Simulate(float timeStep) + { + foreach (BulletXCharacter actor in _characters) + { + actor.Move(timeStep); + + } + ddWorld.StepSimulation(timeStep, 0, timeStep); + foreach (BulletXCharacter actor in _characters) + { + actor.ValidateHeight(this._heightmap[ + (int)Math.Round(actor.RigidBodyHorizontalPosition.x) * 256 + + (int)Math.Round(actor.RigidBodyHorizontalPosition.y)]); + } + foreach (BulletXCharacter actor in _characters) + { + actor.UpdatePosition(); + } + + } + + public override void GetResults() + { + + } + + public override bool IsThreaded + { + get + { + return (false); // for now we won't be multithreaded + } + } + + public override void SetTerrain(float[] heightMap) + { + //As the same as ODE, heightmap (x,y) must be swapped for BulletX + for (int i = 0; i < 65536; i++) + { + // this._heightmap[i] = (double)heightMap[i]; + // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...) + int x = i & 0xff; + int y = i >> 8; + this._heightmap[i] = heightMap[x * 256 + y]; + } + } + + public override void DeleteTerrain() + { + + } + } + /// + /// PhysicsActor Character Class for BulletX + /// + public class BulletXCharacter : PhysicsActor + { + private PhysicsVector _position; + private PhysicsVector _velocity; + private PhysicsVector _acceleration; + private bool flying; + private RigidBody rigidBody; + public Axiom.Math.Vector2 RigidBodyHorizontalPosition + { + get + { + return new Axiom.Math.Vector2(this.rigidBody.CenterOfMassPosition.X, this.rigidBody.CenterOfMassPosition.Y); + } + } + public BulletXCharacter(BulletXScene parent_scene, PhysicsVector pos) + { + _velocity = new PhysicsVector(); + _position = pos; + _acceleration = new PhysicsVector(); + float _mass = 50.0f; //This depends of avatar's dimensions + Matrix _startTransform = Matrix.Identity; + _startTransform.Translation = BulletXConversions.PhysicsVectorToXnaVector3(pos); + Matrix _centerOfMassOffset = Matrix.Identity; + CollisionShape _collisionShape = new BoxShape(new MonoXnaCompactMaths.Vector3(0.5f, 0.5f, 1.60f)); + DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset); + MonoXnaCompactMaths.Vector3 _localInertia = new MonoXnaCompactMaths.Vector3(); + _collisionShape.CalculateLocalInertia(_mass, out _localInertia); //Always when mass > 0 + + //The next values might change + float _linearDamping = 0.0f; + float _angularDamping = 0.0f; + float _friction = 0.5f; + float _restitution = 0.0f; + + rigidBody = new RigidBody(_mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping, _friction, _restitution); + rigidBody.ActivationState = ActivationState.DisableDeactivation; + + parent_scene.ddWorld.AddRigidBody(rigidBody); + } + + public override bool Flying + { + get + { + return flying; + } + set + { + flying = value; + } + } + + public override PhysicsVector Position + { + get + { + return _position; + } + set + { + _position = value; + } + } + + public override PhysicsVector Velocity + { + get + { + return _velocity; + } + set + { + _velocity = value; + } + } + + public override bool Kinematic + { + get + { + return false; + } + set + { + + } + } + + public override Axiom.Math.Quaternion Orientation + { + get + { + return Axiom.Math.Quaternion.Identity; + } + set + { + + } + } + + public override PhysicsVector Acceleration + { + get + { + return _acceleration; + } + + } + public void SetAcceleration(PhysicsVector accel) + { + this._acceleration = accel; + } + + public override void AddForce(PhysicsVector force) + { + + } + + public override void SetMomentum(PhysicsVector momentum) + { + + } + + public void Move(float timeStep) + { + MonoXnaCompactMaths.Vector3 vec = new MonoXnaCompactMaths.Vector3(); + //if (this._velocity.X == 0.0f) + // vec.X = this.rigidBody.LinearVelocity.X; //current velocity + //else + vec.X = this._velocity.X; //overrides current velocity + + //if (this._velocity.Y == 0.0f) + // vec.Y = this.rigidBody.LinearVelocity.Y; //current velocity + //else + vec.Y = this._velocity.Y; //overrides current velocity + + float nextZVelocity; + //if (this._velocity.Z == 0.0f) + // nextZVelocity = this.rigidBody.LinearVelocity.Z; //current velocity + //else + nextZVelocity = this._velocity.Z; //overrides current velocity + + if (flying) + { + //Antigravity with movement + if (this._position.Z <= BulletXScene.HeightLevel0) + { + vec.Z = nextZVelocity + BulletXScene.Gravity * timeStep; + } + //Lowgravity with movement + else if((this._position.Z > BulletXScene.HeightLevel0) + && (this._position.Z <= BulletXScene.HeightLevel1)) + { + vec.Z = nextZVelocity + BulletXScene.Gravity * timeStep * (1.0f - BulletXScene.LowGravityFactor); + } + //Lowgravity with... + else if (this._position.Z > BulletXScene.HeightLevel1) + { + if(nextZVelocity > 0) //no movement + vec.Z = BulletXScene.Gravity * timeStep * (1.0f - BulletXScene.LowGravityFactor); + else + vec.Z = nextZVelocity + BulletXScene.Gravity * timeStep * (1.0f - BulletXScene.LowGravityFactor); + + } + } + else + { + vec.Z = nextZVelocity; + } + rigidBody.LinearVelocity = vec; + } + + public void UpdatePosition() + { + this._position = BulletXConversions.XnaVector3ToPhysicsVector(rigidBody.CenterOfMassPosition); + } + + //This validation is very basic + internal void ValidateHeight(float heighmapPositionValue) + { + if (rigidBody.CenterOfMassPosition.Z < heighmapPositionValue) + { + Matrix m = rigidBody.WorldTransform; + MonoXnaCompactMaths.Vector3 v3 = m.Translation; + v3.Z = heighmapPositionValue; + m.Translation = v3; + rigidBody.WorldTransform = m; + } + } + } + /// + /// PhysicsActor Prim Class for BulletX + /// + public class BulletXPrim : PhysicsActor + { + private PhysicsVector _position; + private PhysicsVector _velocity; + private PhysicsVector _acceleration; + + public BulletXPrim() + { + _velocity = new PhysicsVector(); + _position = new PhysicsVector(); + _acceleration = new PhysicsVector(); + } + public override bool Flying + { + get + { + return false; //no flying prims for you + } + set + { + + } + } + public override PhysicsVector Position + { + get + { + PhysicsVector pos = new PhysicsVector(); + // PhysicsVector vec = this._prim.Position; + //pos.X = vec.X; + //pos.Y = vec.Y; + //pos.Z = vec.Z; + return pos; + + } + set + { + /*PhysicsVector vec = value; + PhysicsVector pos = new PhysicsVector(); + pos.X = vec.X; + pos.Y = vec.Y; + pos.Z = vec.Z; + this._prim.Position = pos;*/ + } + } + + public override PhysicsVector Velocity + { + get + { + return _velocity; + } + set + { + _velocity = value; + } + } + + public override bool Kinematic + { + get + { + return false; + //return this._prim.Kinematic; + } + set + { + //this._prim.Kinematic = value; + } + } + + public override Axiom.Math.Quaternion Orientation + { + get + { + Axiom.Math.Quaternion res = new Axiom.Math.Quaternion(); + return res; + } + set + { + + } + } + + public override PhysicsVector Acceleration + { + get + { + return _acceleration; + } + + } + public void SetAcceleration(PhysicsVector accel) + { + this._acceleration = accel; + } + + public override void AddForce(PhysicsVector force) + { + + } + + public override void SetMomentum(PhysicsVector momentum) + { + + } + } +} diff --git a/OpenSim/Region/Physics/BulletXPlugin/OpenSim.Region.Physics.BulletXPlugin.csproj b/OpenSim/Region/Physics/BulletXPlugin/OpenSim.Region.Physics.BulletXPlugin.csproj new file mode 100644 index 0000000000..fdb1d384a1 --- /dev/null +++ b/OpenSim/Region/Physics/BulletXPlugin/OpenSim.Region.Physics.BulletXPlugin.csproj @@ -0,0 +1,66 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {2D3DE8E4-9202-46A4-857B-3579B70E8356} + Library + Properties + OpenSim.Region.Physics.BulletXPlugin + OpenSim.Region.Physics.BulletXPlugin + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + ..\..\..\..\bin\Physics\ + TRACE + prompt + 4 + + + + + + + + + + ..\..\..\..\bin\Axiom.MathLib.dll + False + + + False + ..\..\..\..\bin\Modified.XnaDevRu.BulletX.dll + + + False + ..\..\..\..\bin\MonoXnaCompactMaths.dll + + + False + ..\..\..\..\bin\OpenSim.Region.Physics.Manager.dll + + + + + + \ No newline at end of file diff --git a/OpenSim/Region/Physics/Manager/AssemblyInfo.cs b/OpenSim/Region/Physics/Manager/AssemblyInfo.cs new file mode 100644 index 0000000000..9415db9655 --- /dev/null +++ b/OpenSim/Region/Physics/Manager/AssemblyInfo.cs @@ -0,0 +1,56 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Reflection; +using System.Runtime.InteropServices; +// Information about this assembly is defined by the following +// attributes. +// +// change them to the information which is associated with the assembly +// you compile. + +[assembly: AssemblyTitle("PhysicsManager")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("PhysicsManager")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. +[assembly: ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all values by your own or you can build default build and revision +// numbers with the '*' character (the default): + +[assembly: AssemblyVersion("1.0.*")] diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs new file mode 100644 index 0000000000..bea54de6c6 --- /dev/null +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -0,0 +1,187 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 Axiom.Math; + +namespace OpenSim.Physics.Manager +{ + public delegate void PositionUpdate(PhysicsVector position); + public delegate void VelocityUpdate(PhysicsVector velocity); + public delegate void OrientationUpdate(Quaternion orientation); + + public abstract class PhysicsActor + { +#pragma warning disable 67 + public event PositionUpdate OnPositionUpdate; + public event VelocityUpdate OnVelocityUpdate; + public event OrientationUpdate OnOrientationUpdate; +#pragma warning restore 67 + + public static PhysicsActor Null + { + get + { + return new NullPhysicsActor(); + } + } + + public abstract PhysicsVector Size + { + get; + set; + } + + public abstract PhysicsVector Position + { + get; + set; + } + + public abstract PhysicsVector Velocity + { + get; + set; + } + + public abstract PhysicsVector Acceleration + { + get; + } + + public abstract Quaternion Orientation + { + get; + set; + } + + public abstract bool Flying + { + get; + set; + } + + public abstract bool Kinematic + { + get; + set; + } + + public abstract void AddForce(PhysicsVector force); + + public abstract void SetMomentum(PhysicsVector momentum); + } + + public class NullPhysicsActor : PhysicsActor + { + public override PhysicsVector Position + { + get + { + return PhysicsVector.Zero; + } + set + { + return; + } + } + + public override PhysicsVector Size + { + get + { + return PhysicsVector.Zero; + } + set + { + return; + } + } + + public override PhysicsVector Velocity + { + get + { + return PhysicsVector.Zero; + } + set + { + return; + } + } + + public override Quaternion Orientation + { + get + { + return Quaternion.Identity; + } + set + { + + } + } + + public override PhysicsVector Acceleration + { + get { return PhysicsVector.Zero; } + } + + public override bool Flying + { + get + { + return false; + } + set + { + return; + } + } + + public override bool Kinematic + { + get + { + return true; + } + set + { + return; + } + } + + public override void AddForce(PhysicsVector force) + { + return; + } + + public override void SetMomentum(PhysicsVector momentum) + { + return; + } + } +} diff --git a/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs new file mode 100644 index 0000000000..3f9e396a24 --- /dev/null +++ b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs @@ -0,0 +1,115 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.IO; +using System.Reflection; +using OpenSim.Framework.Console; + +namespace OpenSim.Physics.Manager +{ + /// + /// Description of MyClass. + /// + public class PhysicsPluginManager + { + private Dictionary _plugins=new Dictionary(); + + public PhysicsPluginManager() + { + + } + + public PhysicsScene GetPhysicsScene(string engineName) + { + if (String.IsNullOrEmpty(engineName)) + { + return PhysicsScene.Null; + } + + if(_plugins.ContainsKey(engineName)) + { + MainLog.Instance.Verbose("PHYSICS","creating "+engineName); + return _plugins[engineName].GetScene(); + } + else + { + MainLog.Instance.Warn("PHYSICS", "couldn't find physicsEngine: {0}", engineName); + throw new ArgumentException(String.Format("couldn't find physicsEngine: {0}",engineName)); + } + } + + public void LoadPlugins() + { + string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory ,"Physics"); + string[] pluginFiles = Directory.GetFiles(path, "*.dll"); + + + for(int i= 0; i"; + } + } +} diff --git a/OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs new file mode 100644 index 0000000000..ee10430c16 --- /dev/null +++ b/OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs @@ -0,0 +1,56 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Reflection; +using System.Runtime.InteropServices; +// Information about this assembly is defined by the following +// attributes. +// +// change them to the information which is associated with the assembly +// you compile. + +[assembly: AssemblyTitle("RealPhysXplugin")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RealPhysXplugin")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. +[assembly: ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all values by your own or you can build default build and revision +// numbers with the '*' character (the default): + +[assembly: AssemblyVersion("1.0.*")] diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs new file mode 100644 index 0000000000..d6b1fc3ed8 --- /dev/null +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs @@ -0,0 +1,492 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 Axiom.Math; +using Ode.NET; +using OpenSim.Physics.Manager; + +namespace OpenSim.Region.Physics.OdePlugin +{ + /// + /// ODE plugin + /// + public class OdePlugin : IPhysicsPlugin + { + private OdeScene _mScene; + + public OdePlugin() + { + + } + + public bool Init() + { + return true; + } + + public PhysicsScene GetScene() + { + if (_mScene == null) + { + _mScene = new OdeScene(); + } + return (_mScene); + } + + public string GetName() + { + return ("OpenDynamicsEngine"); + } + + public void Dispose() + { + + } + } + + public class OdeScene : PhysicsScene + { + static public IntPtr world; + static public IntPtr space; + static private IntPtr contactgroup; + static private IntPtr LandGeom; + //static private IntPtr Land; + private double[] _heightmap; + static private d.NearCallback nearCallback = near; + private List _characters = new List(); + private List _prims = new List(); + private static d.ContactGeom[] contacts = new d.ContactGeom[30]; + private static d.Contact contact; + + public OdeScene() + { + contact.surface.mode |= d.ContactFlags.Approx1 | d.ContactFlags.SoftCFM | d.ContactFlags.SoftERP; + contact.surface.mu = 10.0f; + contact.surface.bounce = 0.9f; + contact.surface.soft_erp = 0.005f; + contact.surface.soft_cfm = 0.00003f; + + world = d.WorldCreate(); + space = d.HashSpaceCreate(IntPtr.Zero); + contactgroup = d.JointGroupCreate(0); + d.WorldSetGravity(world, 0.0f, 0.0f, -10.0f); + d.WorldSetAutoDisableFlag(world, false); + d.WorldSetContactSurfaceLayer(world, 0.001f); + this._heightmap = new double[65536]; + } + + // This function blatantly ripped off from BoxStack.cs + static private void near(IntPtr space, IntPtr g1, IntPtr g2) + { + IntPtr b1 = d.GeomGetBody(g1); + IntPtr b2 = d.GeomGetBody(g2); + if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) + return; + + int count = d.Collide(g1, g2, 500, contacts, d.ContactGeom.SizeOf); + for (int i = 0; i < count; ++i) + { + contact.geom = contacts[i]; + IntPtr joint = d.JointCreateContact(world, contactgroup, ref contact); + d.JointAttach(joint, b1, b2); + } + + } + + public override PhysicsActor AddAvatar(PhysicsVector position) + { + PhysicsVector pos = new PhysicsVector(); + pos.X = position.X; + pos.Y = position.Y; + pos.Z = position.Z + 20; + OdeCharacter newAv = new OdeCharacter(this, pos); + this._characters.Add(newAv); + return newAv; + } + + public override void RemoveAvatar(PhysicsActor actor) + { + + } + + public override PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size, Quaternion rotation) + { + PhysicsVector pos = new PhysicsVector(); + pos.X = position.X; + pos.Y = position.Y; + pos.Z = position.Z; + PhysicsVector siz = new PhysicsVector(); + siz.X = size.X; + siz.Y = size.Y; + siz.Z = size.Z; + Quaternion rot = new Quaternion(); + rot.w = rotation.w; + rot.x = rotation.x; + rot.y = rotation.y; + rot.z = rotation.z; + OdePrim newPrim = new OdePrim(this, pos, siz, rot); + this._prims.Add(newPrim); + return newPrim; + } + + public override void Simulate(float timeStep) + { + foreach (OdeCharacter actor in _characters) + { + actor.Move(timeStep); + } + d.SpaceCollide(space, IntPtr.Zero, nearCallback); + for (int i = 0; i < 50; i++) + { + d.WorldQuickStep(world, timeStep * 0.02f); + } + + d.JointGroupEmpty(contactgroup); + foreach (OdeCharacter actor in _characters) + { + actor.UpdatePosition(); + } + } + + public override void GetResults() + { + + } + + public override bool IsThreaded + { + get + { + return (false); // for now we won't be multithreaded + } + } + + public override void SetTerrain(float[] heightMap) + { + for (int i = 0; i < 65536; i++) + { + // this._heightmap[i] = (double)heightMap[i]; + // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...) + int x = i & 0xff; + int y = i >> 8; + this._heightmap[i] = (double)heightMap[x * 256 + y]; + } + IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); + d.GeomHeightfieldDataBuildDouble(HeightmapData, _heightmap, 0, 256, 256, 256, 256, 1.0f, 0.0f, 2.0f, 0); + d.GeomHeightfieldDataSetBounds(HeightmapData, 256, 256); + LandGeom = d.CreateHeightfield(space, HeightmapData, 1); + d.Matrix3 R = new d.Matrix3(); + + Quaternion q1 =Quaternion.FromAngleAxis(1.5707f, new Vector3(1,0,0)); + Quaternion q2 =Quaternion.FromAngleAxis(1.5707f, new Vector3(0,1,0)); + //Axiom.Math.Quaternion q3 = Axiom.Math.Quaternion.FromAngleAxis(3.14f, new Axiom.Math.Vector3(0, 0, 1)); + + q1 = q1 * q2; + //q1 = q1 * q3; + Vector3 v3 = new Vector3(); + float angle = 0; + q1.ToAngleAxis(ref angle, ref v3); + + d.RFromAxisAndAngle(out R, v3.x, v3.y, v3.z, angle); + d.GeomSetRotation(LandGeom, ref R); + d.GeomSetPosition(LandGeom, 128, 128, 0); + } + + public override void DeleteTerrain() + { + + } + } + + public class OdeCharacter : PhysicsActor + { + private PhysicsVector _position; + private PhysicsVector _velocity; + private PhysicsVector _acceleration; + private bool flying = false; + //private float gravityAccel; + private IntPtr BoundingCapsule; + IntPtr capsule_geom; + d.Mass capsule_mass; + + public OdeCharacter(OdeScene parent_scene, PhysicsVector pos) + { + _velocity = new PhysicsVector(); + _position = pos; + _acceleration = new PhysicsVector(); + d.MassSetCapsule(out capsule_mass, 50.0f, 3, 0.5f, 2f); + capsule_geom = d.CreateSphere(OdeScene.space, 1.0f); /// not a typo! Spheres roll, capsules tumble + this.BoundingCapsule = d.BodyCreate(OdeScene.world); + d.BodySetMass(BoundingCapsule, ref capsule_mass); + d.BodySetPosition(BoundingCapsule, pos.X, pos.Y, pos.Z); + d.GeomSetBody(capsule_geom, BoundingCapsule); + } + + public override bool Flying + { + get + { + return flying; + } + set + { + flying = value; + } + } + + public override PhysicsVector Position + { + get + { + return _position; + } + set + { + _position = value; + } + } + + public override PhysicsVector Size + { + get + { + return new PhysicsVector(0,0,0); + } + set + { + } + } + + + public override PhysicsVector Velocity + { + get + { + return _velocity; + } + set + { + _velocity = value; + } + } + + public override bool Kinematic + { + get + { + return false; + } + set + { + + } + } + + public override Quaternion Orientation + { + get + { + return Quaternion.Identity; + } + set + { + + } + } + + public override PhysicsVector Acceleration + { + get + { + return _acceleration; + } + + } + public void SetAcceleration(PhysicsVector accel) + { + this._acceleration = accel; + } + + public override void AddForce(PhysicsVector force) + { + + } + + public override void SetMomentum(PhysicsVector momentum) + { + + } + + public void Move(float timeStep) + { + PhysicsVector vec = new PhysicsVector(); + d.Vector3 vel = d.BodyGetLinearVel(BoundingCapsule); + vec.X = (vel.X - this._velocity.X) * -75000.0f; + vec.Y = (vel.Y - this._velocity.Y) * -75000.0f; + if (flying) + { + vec.Z = (vel.Z - this._velocity.Z) * -75000.0f; + } + d.BodyAddForce(this.BoundingCapsule, vec.X, vec.Y, vec.Z); + } + + public void UpdatePosition() + { + d.Vector3 vec = d.BodyGetPosition(BoundingCapsule); + this._position.X = vec.X; + this._position.Y = vec.Y; + this._position.Z = vec.Z; + } + } + + public class OdePrim : PhysicsActor + { + private PhysicsVector _position; + private PhysicsVector _velocity; + private PhysicsVector _size; + private PhysicsVector _acceleration; + private Quaternion _orientation; + IntPtr prim_geom; + + public OdePrim(OdeScene parent_scene, PhysicsVector pos, PhysicsVector size, Quaternion rotation) + { + _velocity = new PhysicsVector(); + _position = pos; + _size = size; + _acceleration = new PhysicsVector(); + _orientation = rotation; + prim_geom = d.CreateBox(OdeScene.space, _size.X, _size.Y, _size.Z); + d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + d.Quaternion myrot = new d.Quaternion(); + myrot.W = rotation.w; + myrot.X = rotation.x; + myrot.Y = rotation.y; + myrot.Z = rotation.z; + d.GeomSetQuaternion(prim_geom, ref myrot); + } + + public override bool Flying + { + get + { + return false; //no flying prims for you + } + set + { + } + } + + public override PhysicsVector Position + { + get + { + return _position; + } + set + { + _position = value; + d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + } + } + + public override PhysicsVector Size + { + get + { + return _size; + } + set + { + _size = value; + } + } + + public override PhysicsVector Velocity + { + get + { + return _velocity; + } + set + { + _velocity = value; + } + } + + public override bool Kinematic + { + get + { + return false; + } + set + { + } + } + + public override Quaternion Orientation + { + get + { + return _orientation; + } + set + { + _orientation = value; + d.Quaternion myrot = new d.Quaternion(); + myrot.W = _orientation.w; + myrot.X = _orientation.x; + myrot.Y = _orientation.y; + myrot.Z = _orientation.z; + d.GeomSetQuaternion(prim_geom, ref myrot); + } + } + + public override PhysicsVector Acceleration + { + get + { + return _acceleration; + } + } + + public void SetAcceleration(PhysicsVector accel) + { + this._acceleration = accel; + } + + public override void AddForce(PhysicsVector force) + { + } + + public override void SetMomentum(PhysicsVector momentum) + { + } + } +} diff --git a/OpenSim/Region/Physics/PhysXPlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/PhysXPlugin/AssemblyInfo.cs new file mode 100644 index 0000000000..ee10430c16 --- /dev/null +++ b/OpenSim/Region/Physics/PhysXPlugin/AssemblyInfo.cs @@ -0,0 +1,56 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Reflection; +using System.Runtime.InteropServices; +// Information about this assembly is defined by the following +// attributes. +// +// change them to the information which is associated with the assembly +// you compile. + +[assembly: AssemblyTitle("RealPhysXplugin")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("RealPhysXplugin")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. +[assembly: ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all values by your own or you can build default build and revision +// numbers with the '*' character (the default): + +[assembly: AssemblyVersion("1.0.*")] diff --git a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs new file mode 100644 index 0000000000..39fe5e6079 --- /dev/null +++ b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs @@ -0,0 +1,446 @@ +/*/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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 OpenSim.Physics.Manager; +using PhysXWrapper; +using Quaternion=Axiom.Math.Quaternion; + +namespace OpenSim.Region.Physics.PhysXPlugin +{ + /// + /// Will be the PhysX plugin but for now will be a very basic physics engine + /// + public class PhysXPlugin : IPhysicsPlugin + { + private PhysXScene _mScene; + + public PhysXPlugin() + { + + } + + public bool Init() + { + return true; + } + + public PhysicsScene GetScene() + { + if(_mScene == null) + { + _mScene = new PhysXScene(); + } + return(_mScene); + } + + public string GetName() + { + return("RealPhysX"); + } + + public void Dispose() + { + + } + } + + public class PhysXScene :PhysicsScene + { + private List _characters = new List(); + private List _prims = new List(); + private float[] _heightMap = null; + private NxPhysicsSDK mySdk; + private NxScene scene; + + public PhysXScene() + { + mySdk = NxPhysicsSDK.CreateSDK(); + Console.WriteLine("Sdk created - now creating scene"); + scene = mySdk.CreateScene(); + + } + + public override PhysicsActor AddAvatar(PhysicsVector position) + { + Vec3 pos = new Vec3(); + pos.X = position.X; + pos.Y = position.Y; + pos.Z = position.Z; + PhysXCharacter act = new PhysXCharacter( scene.AddCharacter(pos)); + act.Position = position; + _characters.Add(act); + return act; + } + + public override void RemoveAvatar(PhysicsActor actor) + { + + } + + public override PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size, Quaternion rotation) + { + Vec3 pos = new Vec3(); + pos.X = position.X; + pos.Y = position.Y; + pos.Z = position.Z; + Vec3 siz = new Vec3(); + siz.X = size.X; + siz.Y = size.Y; + siz.Z = size.Z; + PhysXPrim act = new PhysXPrim( scene.AddNewBox(pos, siz)); + _prims.Add(act); + return act; + } + public override void Simulate(float timeStep) + { + try + { + foreach (PhysXCharacter actor in _characters) + { + actor.Move(timeStep); + } + scene.Simulate(timeStep); + scene.FetchResults(); + scene.UpdateControllers(); + + foreach (PhysXCharacter actor in _characters) + { + actor.UpdatePosition(); + } + } + catch (Exception e) + { + Console.WriteLine(e.Message); + } + + } + + public override void GetResults() + { + + } + + public override bool IsThreaded + { + get + { + return(false); // for now we won't be multithreaded + } + } + + public override void SetTerrain(float[] heightMap) + { + if (this._heightMap != null) + { + Console.WriteLine("PhysX - deleting old terrain"); + this.scene.DeleteTerrain(); + } + this._heightMap = heightMap; + this.scene.AddTerrain(heightMap); + } + + public override void DeleteTerrain() + { + this.scene.DeleteTerrain(); + } + } + + public class PhysXCharacter : PhysicsActor + { + private PhysicsVector _position; + private PhysicsVector _velocity; + private PhysicsVector _acceleration; + private NxCharacter _character; + private bool flying; + private float gravityAccel; + + public PhysXCharacter(NxCharacter character) + { + _velocity = new PhysicsVector(); + _position = new PhysicsVector(); + _acceleration = new PhysicsVector(); + _character = character; + } + + public override bool Flying + { + get + { + return flying; + } + set + { + flying = value; + } + } + + public override PhysicsVector Position + { + get + { + return _position; + } + set + { + _position = value; + Vec3 ps = new Vec3(); + ps.X = value.X; + ps.Y = value.Y; + ps.Z = value.Z; + this._character.Position = ps; + } + } + + public override PhysicsVector Size + { + get + { + return new PhysicsVector(0,0,0); + } + set + { + } + } + public override PhysicsVector Velocity + { + get + { + return _velocity; + } + set + { + _velocity = value; + } + } + + public override bool Kinematic + { + get + { + return false; + } + set + { + + } + } + + public override Quaternion Orientation + { + get + { + return Quaternion.Identity; + } + set + { + + } + } + + public override PhysicsVector Acceleration + { + get + { + return _acceleration; + } + + } + public void SetAcceleration (PhysicsVector accel) + { + this._acceleration = accel; + } + + public override void AddForce(PhysicsVector force) + { + + } + + public override void SetMomentum(PhysicsVector momentum) + { + + } + + public void Move(float timeStep) + { + Vec3 vec = new Vec3(); + vec.X = this._velocity.X * timeStep; + vec.Y = this._velocity.Y * timeStep; + if(flying) + { + vec.Z = ( this._velocity.Z) * timeStep; + } + else + { + gravityAccel+= -9.8f; + vec.Z = (gravityAccel + this._velocity.Z) * timeStep; + } + int res = this._character.Move(vec); + if(res == 1) + { + gravityAccel = 0; + } + } + + public void UpdatePosition() + { + Vec3 vec = this._character.Position; + this._position.X = vec.X; + this._position.Y = vec.Y; + this._position.Z = vec.Z; + } + } + + public class PhysXPrim : PhysicsActor + { + private PhysicsVector _position; + private PhysicsVector _velocity; + private PhysicsVector _acceleration; + private NxActor _prim; + + public PhysXPrim(NxActor prim) + { + _velocity = new PhysicsVector(); + _position = new PhysicsVector(); + _acceleration = new PhysicsVector(); + _prim = prim; + } + public override bool Flying + { + get + { + return false; //no flying prims for you + } + set + { + + } + } + public override PhysicsVector Position + { + get + { + PhysicsVector pos = new PhysicsVector(); + Vec3 vec = this._prim.Position; + pos.X = vec.X; + pos.Y = vec.Y; + pos.Z = vec.Z; + return pos; + + } + set + { + PhysicsVector vec = value; + Vec3 pos = new Vec3(); + pos.X = vec.X; + pos.Y = vec.Y; + pos.Z = vec.Z; + this._prim.Position = pos; + } + } + + public override PhysicsVector Size + { + get + { + return new PhysicsVector(0, 0, 0); + } + set + { + } + } + + public override PhysicsVector Velocity + { + get + { + return _velocity; + } + set + { + _velocity = value; + } + } + + public override bool Kinematic + { + get + { + return this._prim.Kinematic; + } + set + { + this._prim.Kinematic = value; + } + } + + public override Quaternion Orientation + { + get + { + Quaternion res = new Quaternion(); + PhysXWrapper.Quaternion quat = this._prim.GetOrientation(); + res.w = quat.W; + res.x = quat.X; + res.y = quat.Y; + res.z = quat.Z; + return res; + } + set + { + + } + } + + public override PhysicsVector Acceleration + { + get + { + return _acceleration; + } + + } + public void SetAcceleration (PhysicsVector accel) + { + this._acceleration = accel; + } + + public override void AddForce(PhysicsVector force) + { + + } + + public override void SetMomentum(PhysicsVector momentum) + { + + } + + + } + +} diff --git a/OpenSim/Region/ScriptEngine/Common/Executor.cs b/OpenSim/Region/ScriptEngine/Common/Executor.cs new file mode 100644 index 0000000000..148ae0fff7 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Common/Executor.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Reflection; + +namespace OpenSim.Region.ScriptEngine.Common +{ + public class Executor : MarshalByRefObject + { + /* TODO: + * + * Needs to be common for all AppDomains - share memory too? + * Needs to have an instance in each AppDomain, and some way of referring it. + * Need to know what AppDomain a script is in so we know where to find our instance. + * + */ + + private IScript m_Script; + private Dictionary Events = new Dictionary(); + private bool m_Running = true; + + + public Executor(IScript Script) + { + m_Script = Script; + + } + + public void StopScript() + { + m_Running = false; + } + public AppDomain GetAppDomain() + { + return AppDomain.CurrentDomain; + } + + public void ExecuteEvent(string FunctionName, object[] args) + { + // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. + // Instead use RuntimeTypeHandle, RuntimeFieldHandle and RunTimeHandle (IntPtr) instead! + + //foreach (MemberInfo mi in this.GetType().GetMembers()) + //{ + //if (mi.ToString().ToLower().Contains("default")) + //{ + // Console.WriteLine("Member found: " + mi.ToString()); + //} + //} + + if (m_Running == false) + { + // Script is inactive, do not execute! + return; + } + + string EventName = m_Script.State() + "_event_" + FunctionName; + + //type.InvokeMember(EventName, BindingFlags.InvokeMethod, null, m_Script, args); + + Console.WriteLine("ScriptEngine Executor.ExecuteEvent: \"" + EventName + "\""); + + if (Events.ContainsKey(EventName) == false) + { + // Not found, create + Type type = m_Script.GetType(); + try + { + MethodInfo mi = type.GetMethod(EventName); + Events.Add(EventName, mi); + } + catch (Exception e) + { + // Event name not found, cache it as not found + Events.Add(EventName, null); + } + } + + // Get event + MethodInfo ev = null; + Events.TryGetValue(EventName, out ev); + + if (ev == null) // No event by that name! + return; + + // Found + try + { + // Invoke it + ev.Invoke(m_Script, args); + + } + catch (Exception e) + { + // TODO: Send to correct place + Console.WriteLine("ScriptEngine Exception attempting to executing script function: " + e.ToString()); + } + } + + } + +} diff --git a/OpenSim/Region/ScriptEngine/Common/IScript.cs b/OpenSim/Region/ScriptEngine/Common/IScript.cs new file mode 100644 index 0000000000..99c08861b9 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Common/IScript.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Region.ScriptEngine.Common +{ + public interface IScript + { + string State(); + Executor Exec { get; } + } +} diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs new file mode 100644 index 0000000000..f80898b547 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs @@ -0,0 +1,632 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +/* Original code: Tedd Hansen */ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Region.ScriptEngine.Common +{ + public interface LSL_BuiltIn_Commands_Interface + { + + string State(); + + double llSin(double f); + double llCos(double f); + double llTan(double f); + double llAtan2(double x, double y); + double llSqrt(double f); + double llPow(double fbase, double fexponent); + int llAbs(int i); + double llFabs(double f); + double llFrand(double mag); + int llFloor(double f); + int llCeil(double f); + int llRound(double f); + double llVecMag(LSL_Types.Vector3 v); + LSL_Types.Vector3 llVecNorm(LSL_Types.Vector3 v); + double llVecDist(LSL_Types.Vector3 a, LSL_Types.Vector3 b); + LSL_Types.Vector3 llRot2Euler(LSL_Types.Quaternion r); + LSL_Types.Quaternion llEuler2Rot(LSL_Types.Vector3 v); + LSL_Types.Quaternion llAxes2Rot(LSL_Types.Vector3 fwd, LSL_Types.Vector3 left, LSL_Types.Vector3 up); + LSL_Types.Vector3 llRot2Fwd(LSL_Types.Quaternion r); + LSL_Types.Vector3 llRot2Left(LSL_Types.Quaternion r); + LSL_Types.Vector3 llRot2Up(LSL_Types.Quaternion r); + LSL_Types.Quaternion llRotBetween(LSL_Types.Vector3 start, LSL_Types.Vector3 end); + void llWhisper(int channelID, string text); + //void llSay(int channelID, string text); + void llSay(int channelID, string text); + void llShout(int channelID, string text); + int llListen(int channelID, string name, string ID, string msg); + void llListenControl(int number, int active); + void llListenRemove(int number); + void llSensor(string name, string id, int type, double range, double arc); + void llSensorRepeat(string name, string id, int type, double range, double arc, double rate); + void llSensorRemove(); + string llDetectedName(int number); + string llDetectedKey(int number); + string llDetectedOwner(int number); + int llDetectedType(int number); + LSL_Types.Vector3 llDetectedPos(int number); + LSL_Types.Vector3 llDetectedVel(int number); + LSL_Types.Vector3 llDetectedGrab(int number); + LSL_Types.Quaternion llDetectedRot(int number); + int llDetectedGroup(int number); + int llDetectedLinkNumber(int number); + void llDie(); + double llGround(LSL_Types.Vector3 offset); + double llCloud(LSL_Types.Vector3 offset); + LSL_Types.Vector3 llWind(LSL_Types.Vector3 offset); + void llSetStatus(int status, int value); + int llGetStatus(int status); + void llSetScale(LSL_Types.Vector3 scale); + LSL_Types.Vector3 llGetScale(); + void llSetColor(LSL_Types.Vector3 color, int face); + double llGetAlpha(int face); + void llSetAlpha(double alpha, int face); + LSL_Types.Vector3 llGetColor(int face); + void llSetTexture(string texture, int face); + void llScaleTexture(double u, double v, int face); + void llOffsetTexture(double u, double v, int face); + void llRotateTexture(double rotation, int face); + string llGetTexture(int face); + void llSetPos(LSL_Types.Vector3 pos); + + //wiki: vector llGetPos() + LSL_Types.Vector3 llGetPos(); + //wiki: vector llGetLocalPos() + LSL_Types.Vector3 llGetLocalPos(); + //wiki: llSetRot(rotation rot) + void llSetRot(LSL_Types.Quaternion rot); + //wiki: rotation llGetRot() + LSL_Types.Quaternion llGetRot(); + //wiki: rotation llGetLocalRot() + LSL_Types.Quaternion llGetLocalRot(); + //wiki: llSetForce(vector force, integer local) + void llSetForce(LSL_Types.Vector3 force, int local); + //wiki: vector llGetForce() + LSL_Types.Vector3 llGetForce(); + //wiki: integer llTarget(vector position, double range) + int llTarget(LSL_Types.Vector3 position, double range); + //wiki: llTargetRemove(integer number) + void llTargetRemove(int number); + //wiki: integer llRotTarget(rotation rot, double error) + int llRotTarget(LSL_Types.Quaternion rot, double error); + //wiki: integer llRotTargetRemove(integer number) + void llRotTargetRemove(int number); + //wiki: llMoveToTarget(vector target, double tau) + void llMoveToTarget(LSL_Types.Vector3 target, double tau); + //wiki: llStopMoveToTarget() + void llStopMoveToTarget(); + //wiki: llApplyImpulse(vector force, integer local) + void llApplyImpulse(LSL_Types.Vector3 force, int local); + //wiki: llapplyRotationalImpulse(vector force, integer local) + void llApplyRotationalImpulse(LSL_Types.Vector3 force, int local); + //wiki: llSetTorque(vector torque, integer local) + void llSetTorque(LSL_Types.Vector3 torque, int local); + //wiki: vector llGetTorque() + LSL_Types.Vector3 llGetTorque(); + //wiki: llSeForceAndTorque(vector force, vector torque, integer local) + void llSetForceAndTorque(LSL_Types.Vector3 force, LSL_Types.Vector3 torque, int local); + //wiki: vector llGetVel() + LSL_Types.Vector3 llGetVel(); + //wiki: vector llGetAccel() + LSL_Types.Vector3 llGetAccel(); + //wiki: vector llGetOmega() + LSL_Types.Vector3 llGetOmega(); + //wiki: double llGetTimeOfDay() + double llGetTimeOfDay(); + //wiki: double llGetWallclock() + double llGetWallclock(); + //wiki: double llGetTime() + double llGetTime(); + //wiki: llResetTime() + void llResetTime(); + //wiki: double llGetAndResetTime() + double llGetAndResetTime(); + //wiki (deprecated) llSound(string sound, double volume, integer queue, integer loop) + void llSound(); + //wiki: llPlaySound(string sound, double volume) + void llPlaySound(string sound, double volume); + //wiki: llLoopSound(string sound, double volume) + void llLoopSound(string sound, double volume); + //wiki: llLoopSoundMaster(string sound, double volume) + void llLoopSoundMaster(string sound, double volume); + //wiki: llLoopSoundSlave(string sound, double volume) + void llLoopSoundSlave(string sound, double volume); + //wiki llPlaySoundSlave(string sound, double volume) + void llPlaySoundSlave(string sound, double volume); + //wiki: llTriggerSound(string sound, double volume) + void llTriggerSound(string sound, double volume); + //wiki: llStopSound() + void llStopSound(); + //wiki: llPreloadSound(string sound) + void llPreloadSound(string sound); + //wiki: string llGetSubString(string src, integer start, integer end) + string llGetSubString(string src, int start, int end); + //wiki: string llDeleteSubString(string src, integer start, integer end) + string llDeleteSubString(string src, int start, int end); + //wiki string llInsertString(string dst, integer position, string src) + string llInsertString(string dst, int position, string src); + //wiki: string llToUpper(string source) + string llToUpper(string source); + //wiki: string llToLower(string source) + string llToLower(string source); + //wiki: integer llGiveMoney(key destination, integer amount) + int llGiveMoney(string destination, int amount); + //wiki: (deprecated) + void llMakeExplosion(); + //wiki: (deprecated) + void llMakeFountain(); + //wiki: (deprecated) + void llMakeSmoke(); + //wiki: (deprecated) + void llMakeFire(); + //wiki: llRezObject(string inventory, vector pos, vector rel, rotation rot, integer param) + void llRezObject(string inventory, LSL_Types.Vector3 pos, LSL_Types.Quaternion rot, int param); + //wiki: llLookAt(vector target, double strength, double damping) + void llLookAt(LSL_Types.Vector3 target, double strength, double damping); + //wiki: llStopLookAt() + void llStopLookAt(); + //wiki: llSetTimerEvent(double sec) + void llSetTimerEvent(double sec); + //wiki: llSleep(double sec) + void llSleep(double sec); + //wiki: double llGetMass() + double llGetMass(); + //wiki: llCollisionFilter(string name, key id, integer accept) + void llCollisionFilter(string name, string id, int accept); + //wiki: llTakeControls(integer controls, integer accept, integer pass_on) + void llTakeControls(int controls, int accept, int pass_on); + //wiki: llReleaseControls() + void llReleaseControls(); + //wiki: llAttachToAvatar(integer attachment) + void llAttachToAvatar(int attachment); + //wiki: llDetachFromAvatar() + void llDetachFromAvatar(); + //wiki: (deprecated) llTakeCamera() + void llTakeCamera(); + //wiki: (deprecated) llReleaseCamera() + void llReleaseCamera(); + //wiki: key llGetOwner() + string llGetOwner(); + //wiki: llInstantMessage(key user, string message) + void llInstantMessage(string user, string message); + //wiki: llEmail(string address, string subject, string message) + void llEmail(string address, string subject, string message); + //wiki: llGetNextEmail(string address, string subject) + void llGetNextEmail(string address, string subject); + //wiki: key llGetKey() + string llGetKey(); + //wiki: llSetBuoyancy(double buoyancy) + void llSetBuoyancy(double buoyancy); + //wiki: llSetHoverHeight(double height, integer water, double tau) + void llSetHoverHeight(double height, int water, double tau); + //wiki: llStopHover + void llStopHover(); + //wiki: llMinEventDelay(double delay) + void llMinEventDelay(double delay); + //wiki: (deprecated) llSoundPreload() + void llSoundPreload(); + //wiki: llRotLookAt(rotation target, double strength, double damping) + void llRotLookAt(LSL_Types.Quaternion target, double strength, double damping); + //wiki: integer llStringLength(string str) + int llStringLength(string str); + //wiki: llStartAnimation(string anim) + void llStartAnimation(string anim); + //wiki: llStopAnimation(string anim) + void llStopAnimation(string anim); + //wiki: (deprecated) llPointAt + void llPointAt(); + //wiki: (deprecated) llStopPointAt + void llStopPointAt(); + //wiki: llTargetOmega(vector axis, double spinrate, double gain) + void llTargetOmega(LSL_Types.Vector3 axis, double spinrate, double gain); + //wiki: integer llGetStartParameter() + int llGetStartParameter(); + //wiki: llGodLikeRezObject(key inventory, vector pos) + void llGodLikeRezObject(string inventory, LSL_Types.Vector3 pos); + //wiki: llRequestPermissions(key agent, integer perm) + void llRequestPermissions(string agent, int perm); + //wiki: key llGetPermissionsKey() + string llGetPermissionsKey(); + //wiki: integer llGetPermissions() + int llGetPermissions(); + //wiki integer llGetLinkNumber() + int llGetLinkNumber(); + //wiki: llSetLinkColor(integer linknumber, vector color, integer face) + void llSetLinkColor(int linknumber, LSL_Types.Vector3 color, int face); + //wiki: llCreateLink(key target, integer parent) + void llCreateLink(string target, int parent); + //wiki: llBreakLink(integer linknum) + void llBreakLink(int linknum); + //wiki: llBreakAllLinks() + void llBreakAllLinks(); + //wiki: key llGetLinkKey(integer linknum) + string llGetLinkKey(int linknum); + //wiki: llGetLinkName(integer linknum) + void llGetLinkName(int linknum); + //wiki: integer llGetInventoryNumber(integer type) + int llGetInventoryNumber(int type); + //wiki: string llGetInventoryName(integer type, integer number) + string llGetInventoryName(int type, int number); + //wiki: llSetScriptState(string name, integer run) + void llSetScriptState(string name, int run); + //wiki: double llGetEnergy() + double llGetEnergy(); + //wiki: llGiveInventory(key destination, string inventory) + void llGiveInventory(string destination, string inventory); + //wiki: llRemoveInventory(string item) + void llRemoveInventory(string item); + //wiki: llSetText(string text, vector color, double alpha) + void llSetText(string text, LSL_Types.Vector3 color, double alpha); + //wiki: double llWater(vector offset) + double llWater(LSL_Types.Vector3 offset); + //wiki: llPassTouches(integer pass) + void llPassTouches(int pass); + //wiki: key llRequestAgentData(key id, integer data) + string llRequestAgentData(string id, int data); + //wiki: key llRequestInventoryData(string name) + string llRequestInventoryData(string name); + //wiki: llSetDamage(double damage) + void llSetDamage(double damage); + //wiki: llTeleportAgentHome(key agent) + void llTeleportAgentHome(string agent); + //wiki: llModifyLand(integer action, integer brush) + void llModifyLand(int action, int brush); + //wiki: llCollisionSound(string impact_sound, double impact_volume) + void llCollisionSound(string impact_sound, double impact_volume); + //wiki: llCollisionSprite(string impact_sprite) + void llCollisionSprite(string impact_sprite); + //wiki: string llGetAnimation(key id) + string llGetAnimation(string id); + //wiki: llResetScript() + void llResetScript(); + //wiki: llMessageLinked(integer linknum, integer num, string str, key id) + void llMessageLinked(int linknum, int num, string str, string id); + //wiki: llPushObject(key target, vector impulse, vector ang_impulse, integer local) + void llPushObject(string target, LSL_Types.Vector3 impulse, LSL_Types.Vector3 ang_impulse, int local); + //wiki: llPassCollisions(integer pass) + void llPassCollisions(int pass); + //wiki: string llGetScriptName() + string llGetScriptName(); + //wiki: integer llGetNumberOfSides() + int llGetNumberOfSides(); + //wiki: rotation llAxisAngle2Rot(vector axis, double angle) + LSL_Types.Quaternion llAxisAngle2Rot(LSL_Types.Vector3 axis, double angle); + //wiki: vector llRot2Axis(rotation rot) + LSL_Types.Vector3 llRot2Axis(LSL_Types.Quaternion rot); + void llRot2Angle(); + //wiki: double llAcos(double val) + double llAcos(double val); + //wiki: double llAsin(double val) + double llAsin(double val); + //wiki: double llAngleBetween(rotation a, rotation b) + double llAngleBetween(LSL_Types.Quaternion a, LSL_Types.Quaternion b); + //wiki: string llGetInventoryKey(string name) + string llGetInventoryKey(string name); + //wiki: llAllowInventoryDrop(integer add) + void llAllowInventoryDrop(int add); + //wiki: vector llGetSunDirection() + LSL_Types.Vector3 llGetSunDirection(); + //wiki: vector llGetTextureOffset(integer face) + LSL_Types.Vector3 llGetTextureOffset(int face); + //wiki: vector llGetTextureScale(integer side) + LSL_Types.Vector3 llGetTextureScale(int side); + //wiki: double llGetTextureRot(integer side) + double llGetTextureRot(int side); + //wiki: integer llSubStringIndex(string source, string pattern) + int llSubStringIndex(string source, string pattern); + //wiki: key llGetOwnerKey(key id) + string llGetOwnerKey(string id); + //wiki: vector llGetCenterOfMass() + LSL_Types.Vector3 llGetCenterOfMass(); + //wiki: list llListSort(list src, integer stride, integer ascending) + List llListSort(List src, int stride, int ascending); + //integer llGetListLength(list src) + int llGetListLength(List src); + //wiki: integer llList2Integer(list src, integer index) + int llList2Integer(List src, int index); + //wiki: double llList2double(list src, integer index) + double llList2double(List src, int index); + //wiki: string llList2String(list src, integer index) + string llList2String(List src, int index); + //wiki: key llList2Key(list src, integer index) + string llList2Key(List src, int index); + //wiki: vector llList2Vector(list src, integer index) + LSL_Types.Vector3 llList2Vector(List src, int index); + //wiki rotation llList2Rot(list src, integer index) + LSL_Types.Quaternion llList2Rot(List src, int index); + //wiki: list llList2List(list src, integer start, integer end) + List llList2List(List src, int start, int end); + //wiki: llDeleteSubList(list src, integer start, integer end) + List llDeleteSubList(List src, int start, int end); + //wiki: integer llGetListEntryType( list src, integer index ) + int llGetListEntryType(List src, int index); + //wiki: string llList2CSV( list src ) + string llList2CSV(List src); + //wiki: list llCSV2List( string src ) + List llCSV2List(string src); + //wiki: list llListRandomize( list src, integer stride ) + List llListRandomize(List src, int stride); + //wiki: list llList2ListStrided( list src, integer start, integer end, integer stride ) + List llList2ListStrided(List src, int start, int end, int stride); + //wiki: vector llGetRegionCorner( ) + LSL_Types.Vector3 llGetRegionCorner(); + //wiki: list llListInsertList( list dest, list src, integer start ) + List llListInsertList(List dest, List src, int start); + //wiki: integer llListFindList( list src, list test ) + int llListFindList(List src, List test); + //wiki: string llGetObjectName() + string llGetObjectName(); + //wiki: llSetObjectName(string name) + void llSetObjectName(string name); + //wiki: string llGetDate() + string llGetDate(); + //wiki: integer llEdgeOfWorld(vector pos, vector dir) + int llEdgeOfWorld(LSL_Types.Vector3 pos, LSL_Types.Vector3 dir); + //wiki: integer llGetAgentInfo(key id) + int llGetAgentInfo(string id); + //wiki: llAdjustSoundVolume(double volume) + void llAdjustSoundVolume(double volume); + //wiki: llSetSoundQueueing(integer queue) + void llSetSoundQueueing(int queue); + //wiki: llSetSoundRadius(double radius) + void llSetSoundRadius(double radius); + //wiki: string llKey2Name(key id) + string llKey2Name(string id); + //wiki: llSetTextureAnim(integer mode, integer face, integer sizex, integer sizey, double start, double length, double rate) + void llSetTextureAnim(int mode, int face, int sizex, int sizey, double start, double length, double rate); + //wiki: llTriggerSoundLimited(string sound, double volume, vector top_north_east, vector bottom_south_west) + void llTriggerSoundLimited(string sound, double volume, LSL_Types.Vector3 top_north_east, LSL_Types.Vector3 bottom_south_west); + //wiki: llEjectFromLand(key pest) + void llEjectFromLand(string pest); + void llParseString2List(); + //wiki: integer llOverMyLand(key id) + int llOverMyLand(string id); + //wiki: key llGetLandOwnerAt(vector pos) + string llGetLandOwnerAt(LSL_Types.Vector3 pos); + //wiki: key llGetNotecardLine(string name, integer line) + string llGetNotecardLine(string name, int line); + //wiki: vector llGetAgentSize(key id) + LSL_Types.Vector3 llGetAgentSize(string id); + //wiki: integer llSameGroup(key agent) + int llSameGroup(string agent); + //wiki: llUnSit(key id) + void llUnSit(string id); + //wiki: vector llGroundSlope(vector offset) + LSL_Types.Vector3 llGroundSlope(LSL_Types.Vector3 offset); + //wiki: vector llGroundNormal(vector offset) + LSL_Types.Vector3 llGroundNormal(LSL_Types.Vector3 offset); + //wiki: vector llGroundContour(vector offset) + LSL_Types.Vector3 llGroundContour(LSL_Types.Vector3 offset); + //wiki: integer llGetAttached() + int llGetAttached(); + //wiki: integer llGetFreeMemory() + int llGetFreeMemory(); + //wiki: string llGetRegionName() + string llGetRegionName(); + //wiki: double llGetRegionTimeDilation() + double llGetRegionTimeDilation(); + //wiki: double llGetRegionFPS() + double llGetRegionFPS(); + //wiki: llParticleSystem(List rules + void llParticleSystem(List rules); + //wiki: llGroundRepel(double height, integer water, double tau) + void llGroundRepel(double height, int water, double tau); + void llGiveInventoryList(); + //wiki: llSetVehicleType(integer type) + void llSetVehicleType(int type); + //wiki: llSetVehicledoubleParam(integer param, double value) + void llSetVehicledoubleParam(int param, double value); + //wiki: llSetVehicleVectorParam(integer param, vector vec) + void llSetVehicleVectorParam(int param, LSL_Types.Vector3 vec); + //wiki: llSetVehicleRotationParam(integer param, rotation rot) + void llSetVehicleRotationParam(int param, LSL_Types.Quaternion rot); + //wiki: llSetVehicleFlags(integer flags) + void llSetVehicleFlags(int flags); + //wiki: llRemoveVehicleFlags(integer flags) + void llRemoveVehicleFlags(int flags); + //wiki: llSitTarget(vector offset, rotation rot) + void llSitTarget(LSL_Types.Vector3 offset, LSL_Types.Quaternion rot); + //wiki key llAvatarOnSitTarget() + string llAvatarOnSitTarget(); + //wiki: llAddToLandPassList(key avatar, double hours) + void llAddToLandPassList(string avatar, double hours); + //wiki: llSetTouchText(string text) + void llSetTouchText(string text); + //wiki: llSetSitText(string text) + void llSetSitText(string text); + //wiki: llSetCameraEyeOffset(vector offset) + void llSetCameraEyeOffset(LSL_Types.Vector3 offset); + //wiki: llSeteCameraAtOffset(vector offset) + void llSetCameraAtOffset(LSL_Types.Vector3 offset); + void llDumpList2String(); + //wiki: integer llScriptDanger(vector pos) + void llScriptDanger(LSL_Types.Vector3 pos); + //wiki: llDialog( key avatar, string message, list buttons, integer chat_channel ) + void llDialog(string avatar, string message, List buttons, int chat_channel); + //wiki: llVolumeDetect(integer detect) + void llVolumeDetect(int detect); + //wiki: llResetOtherScript(string name) + void llResetOtherScript(string name); + //wiki: integer llGetScriptState(string name) + int llGetScriptState(string name); + //wiki: (deprecated) + void llRemoteLoadScript(); + //wiki: llSetRemoteScriptAccessPin(integer pin) + void llSetRemoteScriptAccessPin(int pin); + //wiki: llRemoteLoadScriptPin(key target, string name, integer pin, integer running, integer start_param) + void llRemoteLoadScriptPin(string target, string name, int pin, int running, int start_param); + //wiki: llOpenRemoteDataChannel() + void llOpenRemoteDataChannel(); + //wiki: key llSendRemoteData(key channel, string dest, integer idata, string sdata) + string llSendRemoteData(string channel, string dest, int idata, string sdata); + //wiki: llRemoteDataReply(key channel, key message_id, string sdata, integer idata) + void llRemoteDataReply(string channel, string message_id, string sdata, int idata); + //wiki: llCloseRemoteDataChannel(key channel) + void llCloseRemoteDataChannel(string channel); + //wiki: string llMD5String(string src, integer nonce) + string llMD5String(string src, int nonce); + //wiki: llSetPrimitiveParams( list rules ) + void llSetPrimitiveParams(List rules); + //wiki: string llStringToBase64(string str) + string llStringToBase64(string str); + //wiki: string llBase64ToString(string str) + string llBase64ToString(string str); + //wiki: (deprecated) + void llXorBase64Strings(); + //wiki: llRemoteDataSetRegion() + void llRemoteDataSetRegion(); + //wiki: double llLog10(double val) + double llLog10(double val); + //wiki: double llLog(double val) + double llLog(double val); + //wiki: list llGetAnimationList( key id ) + List llGetAnimationList(string id); + //wiki: llSetParcelMusicURL(string url) + void llSetParcelMusicURL(string url); + //wiki: vector llGetRootPosition() + LSL_Types.Vector3 llGetRootPosition(); + //wiki: rotation llGetRootRotation() + LSL_Types.Quaternion llGetRootRotation(); + //wiki: string llGetObjectDesc() + string llGetObjectDesc(); + //wiki: llSetObjectDesc(string desc) + void llSetObjectDesc(string desc); + //wiki: key llGetCreator() + string llGetCreator(); + //wiki: string llGetTimestamp() + string llGetTimestamp(); + //wiki: llSetLinkAlpha(integer linknumber, double alpha, integer face) + void llSetLinkAlpha(int linknumber, double alpha, int face); + //wiki: integer llGetNumberOfPrims() + int llGetNumberOfPrims(); + //wiki: key llGetNumberOfNotecardLines(string name) + string llGetNumberOfNotecardLines(string name); + //wiki: list llGetBoundingBox( key object ) + List llGetBoundingBox(string obj); + //wiki: vector llGetGeometricCenter() + LSL_Types.Vector3 llGetGeometricCenter(); + void llGetPrimitiveParams(); + //wiki: string llIntegerToBase64(integer number) + string llIntegerToBase64(int number); + //wiki integer llBase64ToInteger(string str) + int llBase64ToInteger(string str); + //wiki: double llGetGMTclock() + double llGetGMTclock(); + //wiki: string llGetSimulatorHostname() + string llGetSimulatorHostname(); + //llSetLocalRot(rotation rot) + void llSetLocalRot(LSL_Types.Quaternion rot); + //wiki: list llParseStringKeepNulls( string src, list separators, list spacers ) + List llParseStringKeepNulls(string src, List seperators, List spacers); + //wiki: llRezAtRoot(string inventory, vector position, vector velocity, rotation rot, integer param) + void llRezAtRoot(string inventory, LSL_Types.Vector3 position, LSL_Types.Vector3 velocity, LSL_Types.Quaternion rot, int param); + //wiki: integer llGetObjectPermMask(integer mask) + int llGetObjectPermMask(int mask); + //wiki: llSetObjectPermMask(integer mask, integer value) + void llSetObjectPermMask(int mask, int value); + //wiki integer llGetInventoryPermMask(string item, integer mask) + void llGetInventoryPermMask(string item, int mask); + //wiki: llSetInventoryPermMask(string item, integer mask, integer value) + void llSetInventoryPermMask(string item, int mask, int value); + //wiki: key llGetInventoryCreator(string item) + string llGetInventoryCreator(string item); + //wiki: llOwnerSay(string msg) + void llOwnerSay(string msg); + //wiki: key llRequestSimulatorData(string simulator, integer data) + void llRequestSimulatorData(string simulator, int data); + //wiki: llForceMouselook(integer mouselook) + void llForceMouselook(int mouselook); + //wiki: double llGetObjectMass(key id) + double llGetObjectMass(string id); + void llListReplaceList(); + //wiki: llLoadURL(key avatar_id, string message, string url) + void llLoadURL(string avatar_id, string message, string url); + //wiki: llParcelMediaCommandList( list commandList ) + void llParcelMediaCommandList(List commandList); + void llParcelMediaQuery(); + //wiki integer llModPow(integer a, integer b, integer c) + int llModPow(int a, int b, int c); + //wiki: integer llGetInventoryType(string name) + int llGetInventoryType(string name); + //wiki: llSetPayPrice( integer price, list quick_pay_buttons ) + void llSetPayPrice(int price, List quick_pay_buttons); + //wiki: vector llGetCameraPos() + LSL_Types.Vector3 llGetCameraPos(); + //wiki rotation llGetCameraRot() + LSL_Types.Quaternion llGetCameraRot(); + //wiki: (deprecated) + void llSetPrimURL(); + //wiki: (deprecated) + void llRefreshPrimURL(); + //wiki: string llEscapeURL(string url) + string llEscapeURL(string url); + //wiki: string llUnescapeURL(string url) + string llUnescapeURL(string url); + //wiki: llMapDestination(string simname, vector pos, vector look_at) + void llMapDestination(string simname, LSL_Types.Vector3 pos, LSL_Types.Vector3 look_at); + //wiki: llAddToLandBanList(key avatar, double hours) + void llAddToLandBanList(string avatar, double hours); + //wiki: llRemoveFromLandPassList(key avatar) + void llRemoveFromLandPassList(string avatar); + //wiki: llRemoveFromLandBanList(key avatar) + void llRemoveFromLandBanList(string avatar); + //wiki: llSetCameraParams( list rules ) + void llSetCameraParams(List rules); + //wiki: llClearCameraParams() + void llClearCameraParams(); + //wiki: double llListStatistics( integer operation, list src ) + double llListStatistics(int operation, List src); + //wiki: integer llGetUnixTime() + int llGetUnixTime(); + //wiki: integer llGetParcelFlags(vector pos) + int llGetParcelFlags(LSL_Types.Vector3 pos); + //wiki: integer llGetRegionFlags() + int llGetRegionFlags(); + //wiki: string llXorBase64StringsCorrect(string str1, string str2) + string llXorBase64StringsCorrect(string str1, string str2); + void llHTTPRequest(); + //wiki: llResetLandBanList() + void llResetLandBanList(); + //wiki: llResetLandPassList() + void llResetLandPassList(); + //wiki integer llGetParcelPrimCount(vector pos, integer category, integer sim_wide) + int llGetParcelPrimCount(LSL_Types.Vector3 pos, int category, int sim_wide); + //wiki: list llGetParcelPrimOwners( vector pos ) + List llGetParcelPrimOwners(LSL_Types.Vector3 pos); + //wiki: integer llGetObjectPrimCount(key object_id) + int llGetObjectPrimCount(string object_id); + //wiki: integer llGetParcelMaxPrims( vector pos, integer sim_wide ) + int llGetParcelMaxPrims(LSL_Types.Vector3 pos, int sim_wide); + //wiki list llGetParcelDetails(vector pos, list params) + List llGetParcelDetails(LSL_Types.Vector3 pos, List param); + } +} diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Common/LSL_Types.cs new file mode 100644 index 0000000000..b151d5aa11 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Common/LSL_Types.cs @@ -0,0 +1,53 @@ +using System; + +namespace OpenSim.Region.ScriptEngine.Common +{ + [Serializable] + public class LSL_Types + { + [Serializable] + public struct Vector3 + { + public double X; + public double Y; + public double Z; + + public Vector3(Vector3 vector) + { + X = (float)vector.X; + Y = (float)vector.Y; + Z = (float)vector.Z; + } + public Vector3(double x, double y, double z) + { + X = x; + Y = y; + Z = z; + } + } + [Serializable] + public struct Quaternion + { + public double X; + public double Y; + public double Z; + public double R; + + public Quaternion(Quaternion Quat) + { + X = (float)Quat.X; + Y = (float)Quat.Y; + Z = (float)Quat.Z; + R = (float)Quat.R; + } + public Quaternion(double x, double y, double z, double r) + { + X = x; + Y = y; + Z = z; + R = r; + } + + } + } +} diff --git a/OpenSim/Region/ScriptEngine/Common/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Common/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..def39100ed --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Common/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.Region.ScriptEngine.Common")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OpenSim.Region.ScriptEngine.Common")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("0bf07c53-ae51-487f-a907-e9b30c251602")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs new file mode 100644 index 0000000000..1218b193c6 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/AppDomainManager.cs @@ -0,0 +1,194 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Reflection; +using System.Threading; +using System.Runtime.Remoting; +using System.IO; +using OpenSim.Region.Environment.Scenes; +using OpenSim.Region.Environment.Scenes.Scripting; +using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL; +using OpenSim.Region.ScriptEngine.Common; + +namespace OpenSim.Region.ScriptEngine.DotNetEngine +{ + public class AppDomainManager + { + private int MaxScriptsPerAppDomain = 3; + /// + /// Internal list of all AppDomains + /// + private List AppDomains = new List(); + /// + /// Structure to keep track of data around AppDomain + /// + private class AppDomainStructure + { + /// + /// The AppDomain itself + /// + public AppDomain CurrentAppDomain; + /// + /// Number of scripts loaded into AppDomain + /// + public int ScriptsLoaded; + /// + /// Number of dead scripts + /// + public int ScriptsWaitingUnload; + } + /// + /// Current AppDomain + /// + private AppDomainStructure CurrentAD; + private object GetLock = new object(); // Mutex + private object FreeLock = new object(); // Mutex + + //private ScriptEngine m_scriptEngine; + //public AppDomainManager(ScriptEngine scriptEngine) + public AppDomainManager() + { + //m_scriptEngine = scriptEngine; + } + + /// + /// Find a free AppDomain, creating one if necessary + /// + /// Free AppDomain + private AppDomainStructure GetFreeAppDomain() + { + FreeAppDomains(); // Outsite lock, has its own GetLock + lock (GetLock) + { + // Current full? + if (CurrentAD != null && CurrentAD.ScriptsLoaded >= MaxScriptsPerAppDomain) + { + // Add it to AppDomains list and empty current + AppDomains.Add(CurrentAD); + CurrentAD = null; + } + // No current + if (CurrentAD == null) + { + // Create a new current AppDomain + CurrentAD = new AppDomainStructure(); + CurrentAD.CurrentAppDomain = PrepareNewAppDomain(); + } + + Console.WriteLine("Scripts loaded in this Appdomain: " + CurrentAD.ScriptsLoaded); + return CurrentAD; + } // lock + } + + private int AppDomainNameCount; + /// + /// Create and prepare a new AppDomain for scripts + /// + /// The new AppDomain + private AppDomain PrepareNewAppDomain() + { + // Create and prepare a new AppDomain + AppDomainNameCount++; + // TODO: Currently security match current appdomain + + // Construct and initialize settings for a second AppDomain. + AppDomainSetup ads = new AppDomainSetup(); + ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; + ads.DisallowBindingRedirects = false; + ads.DisallowCodeDownload = true; + ads.ShadowCopyFiles = "true"; // Enabled shadowing + ads.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; + + AppDomain AD = AppDomain.CreateDomain("ScriptAppDomain_" + AppDomainNameCount, null, ads); + + // Return the new AppDomain + return AD; + + } + + /// + /// Unload appdomains that are full and have only dead scripts + /// + private void FreeAppDomains() + { + lock (FreeLock) + { + // Go through all + foreach (AppDomainStructure ads in new System.Collections.ArrayList(AppDomains)) + { + // Don't process current AppDomain + if (ads.CurrentAppDomain != CurrentAD.CurrentAppDomain) + { + // Not current AppDomain + // Is number of unloaded bigger or equal to number of loaded? + if (ads.ScriptsLoaded <= ads.ScriptsWaitingUnload) + { + // Remove from internal list + AppDomains.Remove(ads); + // Unload + AppDomain.Unload(ads.CurrentAppDomain); + } + } + } // foreach + } // lock + } + + + + public OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.LSL_BaseClass LoadScript(string FileName) + { + // Find next available AppDomain to put it in + AppDomainStructure FreeAppDomain = GetFreeAppDomain(); + + if (FreeAppDomain == null) Console.WriteLine("FreeAppDomain == null"); + if (FreeAppDomain.CurrentAppDomain == null) Console.WriteLine("FreeAppDomain.CurrentAppDomain == null"); + LSL_BaseClass mbrt = (LSL_BaseClass)FreeAppDomain.CurrentAppDomain.CreateInstanceFromAndUnwrap(FileName, "SecondLife.Script"); + //Type mytype = mbrt.GetType(); + Console.WriteLine("ScriptEngine AppDomainManager: is proxy={0}", RemotingServices.IsTransparentProxy(mbrt)); + + // Increase script count in tihs AppDomain + FreeAppDomain.ScriptsLoaded++; + + //mbrt.Start(); + return mbrt; + //return (LSL_BaseClass)mbrt; + + } + + + /// + /// Increase "dead script" counter for an AppDomain + /// + /// + [Obsolete("Needs fixing, needs a real purpose in life!!!")] + public void StopScript(AppDomain ad) + { + lock (FreeLock) + { + // Check if it is current AppDomain + if (CurrentAD.CurrentAppDomain == ad) + { + // Yes - increase + CurrentAD.ScriptsWaitingUnload++; + return; + } + + // Lopp through all AppDomains + foreach (AppDomainStructure ads in new System.Collections.ArrayList(AppDomains)) + { + if (ads.CurrentAppDomain == ad) + { + // Found it - messy code to increase structure + //AppDomainStructure ads2 = ads; + ads.ScriptsWaitingUnload++; + //AppDomains.Remove(ads); + //AppDomains.Add(ads2); + return; + } + } // foreach + } // lock + } + + + } +} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Common.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Common.cs new file mode 100644 index 0000000000..232b2a601c --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Common.cs @@ -0,0 +1,59 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +/* Original code: Tedd Hansen */ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Region.ScriptEngine.DotNetEngine +{ + public static class Common + { + static public bool Debug = true; + static public ScriptEngine mySE; + + //public delegate void SendToDebugEventDelegate(string Message); + //public delegate void SendToLogEventDelegate(string Message); + //static public event SendToDebugEventDelegate SendToDebugEvent; + //static public event SendToLogEventDelegate SendToLogEvent; + + static public void SendToDebug(string Message) + { + //if (Debug == true) + mySE.Log.Verbose("ScriptEngine", "Debug: " + Message); + //SendToDebugEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message); + } + static public void SendToLog(string Message) + { + //if (Debug == true) + mySE.Log.Verbose("ScriptEngine", "LOG: " + Message); + //SendToLogEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message); + } + } + +} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs new file mode 100644 index 0000000000..ad2717cf18 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/Compiler.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using Microsoft.CSharp; +using System.CodeDom.Compiler; +using System.Reflection; + +namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL +{ + + public class Compiler + { + private LSL2CSConverter LSL_Converter = new LSL2CSConverter(); + private CSharpCodeProvider codeProvider = new CSharpCodeProvider(); + //private ICodeCompiler icc = codeProvider.CreateCompiler(); + public string Compile(string LSOFileName) + { + + + // Output assembly name + string OutFile = Path.Combine("ScriptEngines", Path.GetFileNameWithoutExtension(LSOFileName) + ".dll"); + //string OutFile = Path.Combine("ScriptEngines", "SecondLife.Script.dll"); + + Common.SendToDebug("Reading source code into memory"); + // TODO: Add error handling + string CS_Code; + switch (System.IO.Path.GetExtension(LSOFileName).ToLower()) + { + case ".txt": + case ".lsl": + Common.SendToDebug("Source code is LSL, converting to CS"); + CS_Code = LSL_Converter.Convert(File.ReadAllText(LSOFileName)); + break; + case ".cs": + Common.SendToDebug("Source code is CS"); + CS_Code = File.ReadAllText(LSOFileName); + break; + default: + throw new Exception("Unknown script type."); + } + + Common.SendToDebug("Compiling"); + + // DEBUG - write source to disk + try + { + File.WriteAllText(Path.Combine("ScriptEngines", "debug_" + Path.GetFileNameWithoutExtension(LSOFileName) + ".cs"), CS_Code); + } + catch { } + + // Do actual compile + System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters(); + parameters.IncludeDebugInformation = true; + // Add all available assemblies + foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) + { + //Console.WriteLine("Adding assembly: " + asm.Location); + //parameters.ReferencedAssemblies.Add(asm.Location); + } + + string rootPath = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory); + string rootPathSE = Path.GetDirectoryName(this.GetType().Assembly.Location); + //Console.WriteLine("Assembly location: " + rootPath); + parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Common.dll")); + parameters.ReferencedAssemblies.Add(Path.Combine(rootPathSE, "OpenSim.Region.ScriptEngine.DotNetEngine.dll")); + + //parameters.ReferencedAssemblies.Add("OpenSim.Region.Environment"); + parameters.GenerateExecutable = false; + parameters.OutputAssembly = OutFile; + CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, CS_Code); + + // Go through errors + // TODO: Return errors to user somehow + if (results.Errors.Count > 0) + { + foreach (CompilerError CompErr in results.Errors) + { + Console.WriteLine("Line number " + CompErr.Line + + ", Error Number: " + CompErr.ErrorNumber + + ", '" + CompErr.ErrorText + ";"); + } + } + + + return OutFile; + } + + } +} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/LSL2CSConverter.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/LSL2CSConverter.cs new file mode 100644 index 0000000000..de61ab73d3 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/LSL2CSConverter.cs @@ -0,0 +1,248 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; + +namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL +{ + public class LSL2CSConverter + { + //private Regex rnw = new Regex(@"[a-zA-Z0-9_\-]", RegexOptions.Compiled); + private Dictionary DataTypes = new Dictionary(); + private Dictionary QUOTES = new Dictionary(); + + public LSL2CSConverter() + { + DataTypes.Add("void", "void"); + DataTypes.Add("integer", "int"); + DataTypes.Add("float", "double"); + DataTypes.Add("string", "string"); + DataTypes.Add("key", "string"); + DataTypes.Add("vector", "LSL_Types.Vector3"); + DataTypes.Add("rotation", "LSL_Types.Quaternion"); + DataTypes.Add("list", "list"); + DataTypes.Add("null", "null"); + } + + + + + public string Convert(string Script) + { + string Return = ""; + Script = " \r\n" + Script; + + // + // Prepare script for processing + // + + // Clean up linebreaks + Script = Regex.Replace(Script, @"\r\n", "\n"); + Script = Regex.Replace(Script, @"\n", "\r\n"); + + + // QUOTE REPLACEMENT + // temporarily replace quotes so we can work our magic on the script without + // always considering if we are inside our outside ""'s + string _Script = ""; + string C; + bool in_quote = false; + bool quote_replaced = false; + string quote_replacement_string = "Q_U_O_T_E_REPLACEMENT_"; + string quote = ""; + bool last_was_escape = false; + int quote_replaced_count = 0; + for (int p = 0; p < Script.Length; p++) + { + + C = Script.Substring(p, 1); + while (true) + { + // found " and last was not \ so this is not an escaped \" + if (C == "\"" && last_was_escape == false) + { + // Toggle inside/outside quote + in_quote = !in_quote; + if (in_quote) + { + quote_replaced_count++; + } + else + { + if (quote == "") + { + // We didn't replace quote, probably because of empty string? + _Script += quote_replacement_string + quote_replaced_count.ToString().PadLeft(5, "0".ToCharArray()[0]); + } + // We just left a quote + QUOTES.Add(quote_replacement_string + quote_replaced_count.ToString().PadLeft(5, "0".ToCharArray()[0]), quote); + quote = ""; + } + break; + } + + if (!in_quote) + { + // We are not inside a quote + quote_replaced = false; + + } + else + { + // We are inside a quote + if (!quote_replaced) + { + // Replace quote + _Script += quote_replacement_string + quote_replaced_count.ToString().PadLeft(5, "0".ToCharArray()[0]); + quote_replaced = true; + } + quote += C; + break; + } + _Script += C; + break; + } + last_was_escape = false; + if (C == @"\") + { + last_was_escape = true; + } + } + Script = _Script; + // + // END OF QUOTE REPLACEMENT + // + + + + // + // PROCESS STATES + // Remove state definitions and add state names to start of each event within state + // + int ilevel = 0; + int lastlevel = 0; + string ret = ""; + string cache = ""; + bool in_state = false; + string current_statename = ""; + for (int p = 0; p < Script.Length; p++) + { + C = Script.Substring(p, 1); + while (true) + { + // inc / dec level + if (C == @"{") + ilevel++; + if (C == @"}") + ilevel--; + if (ilevel < 0) + ilevel = 0; + cache += C; + + // if level == 0, add to return + if (ilevel == 1 && lastlevel == 0) + { + // 0 => 1: Get last + Match m = Regex.Match(cache, @"(?![a-zA-Z_]+)\s*([a-zA-Z_]+)[^a-zA-Z_\(\)]*{", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); + + in_state = false; + if (m.Success) + { + // Go back to level 0, this is not a state + in_state = true; + current_statename = m.Groups[1].Captures[0].Value; + //Console.WriteLine("Current statename: " + current_statename); + cache = Regex.Replace(cache, @"(?![a-zA-Z_]+)\s*([a-zA-Z_]+)[^a-zA-Z_\(\)]*{", "", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); + } + ret += cache; + cache = ""; + } + if (ilevel == 0 && lastlevel == 1) + { + // 1 => 0: Remove last } + if (in_state == true) + { + cache = cache.Remove(cache.Length - 1, 1); + //cache = Regex.Replace(cache, "}$", "", RegexOptions.Multiline | RegexOptions.Singleline); + + //Replace function names + // void dataserver(key query_id, string data) { + //cache = Regex.Replace(cache, @"([^a-zA-Z_]\s*)((?!if|switch|for)[a-zA-Z_]+\s*\([^\)]*\)[^{]*{)", "$1" + "" + "$2", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); + //Console.WriteLine("Replacing using statename: " + current_statename); + cache = Regex.Replace(cache, @"^(\s*)((?!(if|switch|for)[^a-zA-Z0-9_])[a-zA-Z0-9_]*\s*\([^\)]*\)[^;]*\{)", @"public $1" + current_statename + "_event_$2", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); + } + + ret += cache; + cache = ""; + in_state = true; + current_statename = ""; + } + + break; + } + lastlevel = ilevel; + } + ret += cache; + cache = ""; + + Script = ret; + ret = ""; + + + + foreach (string key in DataTypes.Keys) + { + string val; + DataTypes.TryGetValue(key, out val); + + // Replace CAST - (integer) with (int) + Script = Regex.Replace(Script, @"\(" + key + @"\)", @"(" + val + ")", RegexOptions.Compiled | RegexOptions.Multiline); + // Replace return types and function variables - integer a() and f(integer a, integer a) + Script = Regex.Replace(Script, @"(^|;|}|[\(,])(\s*)" + key + @"(\s*)", @"$1$2" + val + "$3", RegexOptions.Compiled | RegexOptions.Multiline); + } + + // Add "void" in front of functions that needs it + Script = Regex.Replace(Script, @"^(\s*)((?!(if|switch|for)[^a-zA-Z0-9_])[a-zA-Z0-9_]*\s*\([^\)]*\)[^;]*\{)", @"$1void $2", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); + + // Replace and + Script = Regex.Replace(Script, @"<([^,>]*,[^,>]*,[^,>]*,[^,>]*)>", @"new LSL_Types.Quaternion($1)", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); + Script = Regex.Replace(Script, @"<([^,>]*,[^,>]*,[^,>]*)>", @"new LSL_Types.Vector3($1)", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); + + // Replace List []'s + Script = Regex.Replace(Script, @"\[([^\]]*)\]", @"List.Parse($1)", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); + + + // Replace (string) to .ToString() // + Script = Regex.Replace(Script, @"\(string\)\s*([a-zA-Z0-9_]+(\s*\([^\)]*\))?)", @"$1.ToString()", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); + Script = Regex.Replace(Script, @"\((float|int)\)\s*([a-zA-Z0-9_]+(\s*\([^\)]*\))?)", @"$1.Parse($2)", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); + + + // REPLACE BACK QUOTES + foreach (string key in QUOTES.Keys) + { + string val; + QUOTES.TryGetValue(key, out val); + Script = Script.Replace(key, "\"" + val + "\""); + } + + + // Add namespace, class name and inheritance + Return = "" + + "using System;\r\n" + + "using System.Collections.Generic;\r\n" + + "using System.Text;\r\n" + + "using OpenSim.Region.ScriptEngine.Common;\r\n" + + "namespace SecondLife {\r\n"; + Return += "" + + //"[Serializable] " + + "public class Script : OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.LSL_BaseClass {\r\n"; + Return += @"public Script() { }"+"\r\n"; + Return += Script; + Return += "} }\r\n"; + + return Return; + } + + + } +} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/LSL_BaseClass.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/LSL_BaseClass.cs new file mode 100644 index 0000000000..bfb8913a5b --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/LSL_BaseClass.cs @@ -0,0 +1,757 @@ +using System; +using System.Collections.Generic; +using System.Text; +using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler; +using OpenSim.Region.ScriptEngine.Common; +using System.Threading; +using System.Reflection; + + +namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL +{ + public class LSL_BaseClass : MarshalByRefObject, LSL_BuiltIn_Commands_Interface, IScript + { + private Executor m_Exec; + public Executor Exec { + get + { + if (m_Exec == null) + m_Exec = new Executor(this); + return m_Exec; + } + } + + public LSL_BuiltIn_Commands_Interface m_LSL_Functions; + + public LSL_BaseClass() + { + } + public string State() + { + return m_LSL_Functions.State(); + } + + + public void Start(LSL_BuiltIn_Commands_Interface LSL_Functions) + { + m_LSL_Functions = LSL_Functions; + + //MainLog.Instance.Notice("ScriptEngine", "LSL_BaseClass.Start() called."); + + // Get this AppDomain's settings and display some of them. + AppDomainSetup ads = AppDomain.CurrentDomain.SetupInformation; + Console.WriteLine("AppName={0}, AppBase={1}, ConfigFile={2}", + ads.ApplicationName, + ads.ApplicationBase, + ads.ConfigurationFile + ); + + // Display the name of the calling AppDomain and the name + // of the second domain. + // NOTE: The application's thread has transitioned between + // AppDomains. + Console.WriteLine("Calling to '{0}'.", + Thread.GetDomain().FriendlyName + ); + + return; + } + + + + // + // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs + // + // They are only forwarders to LSL_BuiltIn_Commands.cs + // + public double llSin(double f) { return m_LSL_Functions.llSin(f); } + public double llCos(double f) { return m_LSL_Functions.llCos(f); } + public double llTan(double f) { return m_LSL_Functions.llTan(f); } + public double llAtan2(double x, double y) { return m_LSL_Functions.llAtan2(x, y); } + public double llSqrt(double f) { return m_LSL_Functions.llSqrt(f); } + public double llPow(double fbase, double fexponent) { return m_LSL_Functions.llPow(fbase, fexponent); } + public int llAbs(int i) { return m_LSL_Functions.llAbs(i); } + public double llFabs(double f) { return m_LSL_Functions.llFabs(f); } + public double llFrand(double mag) { return m_LSL_Functions.llFrand(mag); } + public int llFloor(double f) { return m_LSL_Functions.llFloor(f); } + public int llCeil(double f) { return m_LSL_Functions.llCeil(f); } + public int llRound(double f) { return m_LSL_Functions.llRound(f); } + public double llVecMag(LSL_Types.Vector3 v) { return m_LSL_Functions.llVecMag(v); } + public LSL_Types.Vector3 llVecNorm(LSL_Types.Vector3 v) { return m_LSL_Functions.llVecNorm(v); } + public double llVecDist(LSL_Types.Vector3 a, LSL_Types.Vector3 b) { return m_LSL_Functions.llVecDist(a, b); } + public LSL_Types.Vector3 llRot2Euler(LSL_Types.Quaternion r) { return m_LSL_Functions.llRot2Euler(r); } + public LSL_Types.Quaternion llEuler2Rot(LSL_Types.Vector3 v) { return m_LSL_Functions.llEuler2Rot(v); } + public LSL_Types.Quaternion llAxes2Rot(LSL_Types.Vector3 fwd, LSL_Types.Vector3 left, LSL_Types.Vector3 up) { return m_LSL_Functions.llAxes2Rot(fwd, left, up); } + public LSL_Types.Vector3 llRot2Fwd(LSL_Types.Quaternion r) { return m_LSL_Functions.llRot2Fwd(r); } + public LSL_Types.Vector3 llRot2Left(LSL_Types.Quaternion r) { return m_LSL_Functions.llRot2Left(r); } + public LSL_Types.Vector3 llRot2Up(LSL_Types.Quaternion r) { return m_LSL_Functions.llRot2Up(r); } + public LSL_Types.Quaternion llRotBetween(LSL_Types.Vector3 start, LSL_Types.Vector3 end) { return m_LSL_Functions.llRotBetween(start, end); } + public void llWhisper(int channelID, string text) { m_LSL_Functions.llWhisper(channelID, text); } + public void llSay(int channelID, string text) { m_LSL_Functions.llSay(channelID, text); } + // + // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs + // + public void llShout(int channelID, string text) { m_LSL_Functions.llShout(channelID, text); } + public int llListen(int channelID, string name, string ID, string msg) { return m_LSL_Functions.llListen(channelID, name, ID, msg); } + public void llListenControl(int number, int active) { m_LSL_Functions.llListenControl(number, active); } + public void llListenRemove(int number) { m_LSL_Functions.llListenRemove(number); } + public void llSensor(string name, string id, int type, double range, double arc) { m_LSL_Functions.llSensor(name, id, type, range, arc); } + public void llSensorRepeat(string name, string id, int type, double range, double arc, double rate) { m_LSL_Functions.llSensorRepeat(name, id, type, range, arc, rate); } + public void llSensorRemove() { m_LSL_Functions.llSensorRemove(); } + public string llDetectedName(int number) { return m_LSL_Functions.llDetectedName(number); } + public string llDetectedKey(int number) { return m_LSL_Functions.llDetectedKey(number); } + public string llDetectedOwner(int number) { return m_LSL_Functions.llDetectedOwner(number); } + public int llDetectedType(int number) { return m_LSL_Functions.llDetectedType(number); } + public LSL_Types.Vector3 llDetectedPos(int number) { return m_LSL_Functions.llDetectedPos(number); } + public LSL_Types.Vector3 llDetectedVel(int number) { return m_LSL_Functions.llDetectedVel(number); } + public LSL_Types.Vector3 llDetectedGrab(int number) { return m_LSL_Functions.llDetectedGrab(number); } + public LSL_Types.Quaternion llDetectedRot(int number) { return m_LSL_Functions.llDetectedRot(number); } + public int llDetectedGroup(int number) { return m_LSL_Functions.llDetectedGroup(number); } + public int llDetectedLinkNumber(int number) { return m_LSL_Functions.llDetectedLinkNumber(number); } + // + // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs + // + public void llDie() { m_LSL_Functions.llDie(); } + public double llGround(LSL_Types.Vector3 offset) { return m_LSL_Functions.llGround(offset); } + public double llCloud(LSL_Types.Vector3 offset) { return m_LSL_Functions.llCloud(offset); } + public LSL_Types.Vector3 llWind(LSL_Types.Vector3 offset) { return m_LSL_Functions.llWind(offset); } + public void llSetStatus(int status, int value) { m_LSL_Functions.llSetStatus(status, value); } + public int llGetStatus(int status) { return m_LSL_Functions.llGetStatus(status); } + public void llSetScale(LSL_Types.Vector3 scale) { m_LSL_Functions.llSetScale(scale); } + public LSL_Types.Vector3 llGetScale() { return m_LSL_Functions.llGetScale(); } + public void llSetColor(LSL_Types.Vector3 color, int face) { m_LSL_Functions.llSetColor(color, face); } + public double llGetAlpha(int face) { return m_LSL_Functions.llGetAlpha(face); } + public void llSetAlpha(double alpha, int face) { m_LSL_Functions.llSetAlpha(alpha, face); } + public LSL_Types.Vector3 llGetColor(int face) { return m_LSL_Functions.llGetColor(face); } + public void llSetTexture(string texture, int face) { m_LSL_Functions.llSetTexture(texture, face); } + public void llScaleTexture(double u, double v, int face) { m_LSL_Functions.llScaleTexture(u, v, face); } + public void llOffsetTexture(double u, double v, int face) { m_LSL_Functions.llOffsetTexture(u, v, face); } + public void llRotateTexture(double rotation, int face) { m_LSL_Functions.llRotateTexture(rotation, face); } + public string llGetTexture(int face) { return m_LSL_Functions.llGetTexture(face); } + // + // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs + // + public void llSetPos(LSL_Types.Vector3 pos) { m_LSL_Functions.llSetPos(pos); } + public LSL_Types.Vector3 llGetPos() { return m_LSL_Functions.llGetPos(); } + public LSL_Types.Vector3 llGetLocalPos() { return m_LSL_Functions.llGetLocalPos(); } + public void llSetRot(LSL_Types.Quaternion rot) { m_LSL_Functions.llSetRot(rot); } + public LSL_Types.Quaternion llGetRot() { return m_LSL_Functions.llGetRot(); } + public LSL_Types.Quaternion llGetLocalRot() { return m_LSL_Functions.llGetLocalRot(); } + public void llSetForce(LSL_Types.Vector3 force, int local) { m_LSL_Functions.llSetForce(force, local); } + public LSL_Types.Vector3 llGetForce() { return m_LSL_Functions.llGetForce(); } + public int llTarget(LSL_Types.Vector3 position, double range) { return m_LSL_Functions.llTarget(position, range); } + public void llTargetRemove(int number) { m_LSL_Functions.llTargetRemove(number); } + public int llRotTarget(LSL_Types.Quaternion rot, double error) { return m_LSL_Functions.llRotTarget(rot, error); } + public void llRotTargetRemove(int number) { m_LSL_Functions.llRotTargetRemove(number); } + public void llMoveToTarget(LSL_Types.Vector3 target, double tau) { m_LSL_Functions.llMoveToTarget(target, tau); } + public void llStopMoveToTarget() { m_LSL_Functions.llStopMoveToTarget(); } + public void llApplyImpulse(LSL_Types.Vector3 force, int local) { m_LSL_Functions.llApplyImpulse(force, local); } + // + // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs + // + public void llApplyRotationalImpulse(LSL_Types.Vector3 force, int local) { m_LSL_Functions.llApplyRotationalImpulse(force, local); } + public void llSetTorque(LSL_Types.Vector3 torque, int local) { m_LSL_Functions.llSetTorque(torque, local); } + public LSL_Types.Vector3 llGetTorque() { return m_LSL_Functions.llGetTorque(); } + public void llSetForceAndTorque(LSL_Types.Vector3 force, LSL_Types.Vector3 torque, int local) { m_LSL_Functions.llSetForceAndTorque(force, torque, local); } + public LSL_Types.Vector3 llGetVel() { return m_LSL_Functions.llGetVel(); } + public LSL_Types.Vector3 llGetAccel() { return m_LSL_Functions.llGetAccel(); } + public LSL_Types.Vector3 llGetOmega() { return m_LSL_Functions.llGetOmega(); } + public double llGetTimeOfDay() { return m_LSL_Functions.llGetTimeOfDay(); } + public double llGetWallclock() { return m_LSL_Functions.llGetWallclock(); } + public double llGetTime() { return m_LSL_Functions.llGetTime(); } + public void llResetTime() { m_LSL_Functions.llResetTime(); } + public double llGetAndResetTime() { return m_LSL_Functions.llGetAndResetTime(); } + public void llSound() { m_LSL_Functions.llSound(); } + public void llPlaySound(string sound, double volume) { m_LSL_Functions.llPlaySound(sound, volume); } + public void llLoopSound(string sound, double volume) { m_LSL_Functions.llLoopSound(sound, volume); } + public void llLoopSoundMaster(string sound, double volume) { m_LSL_Functions.llLoopSoundMaster(sound, volume); } + public void llLoopSoundSlave(string sound, double volume) { m_LSL_Functions.llLoopSoundSlave(sound, volume); } + public void llPlaySoundSlave(string sound, double volume) { m_LSL_Functions.llPlaySoundSlave(sound, volume); } + // + // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs + // + public void llTriggerSound(string sound, double volume) { m_LSL_Functions.llTriggerSound(sound, volume); } + public void llStopSound() { m_LSL_Functions.llStopSound(); } + public void llPreloadSound(string sound) { m_LSL_Functions.llPreloadSound(sound); } + public string llGetSubString(string src, int start, int end) { return m_LSL_Functions.llGetSubString(src, start, end); } + public string llDeleteSubString(string src, int start, int end) { return m_LSL_Functions.llDeleteSubString(src, start, end); } + public string llInsertString(string dst, int position, string src) { return m_LSL_Functions.llInsertString(dst, position, src); } + public string llToUpper(string source) { return m_LSL_Functions.llToUpper(source); } + public string llToLower(string source) { return m_LSL_Functions.llToLower(source); } + public int llGiveMoney(string destination, int amount) { return m_LSL_Functions.llGiveMoney(destination, amount); } + public void llMakeExplosion() { m_LSL_Functions.llMakeExplosion(); } + public void llMakeFountain() { m_LSL_Functions.llMakeFountain(); } + public void llMakeSmoke() { m_LSL_Functions.llMakeSmoke(); } + public void llMakeFire() { m_LSL_Functions.llMakeFire(); } + public void llRezObject(string inventory, LSL_Types.Vector3 pos, LSL_Types.Quaternion rot, int param) { m_LSL_Functions.llRezObject(inventory, pos, rot, param); } + public void llLookAt(LSL_Types.Vector3 target, double strength, double damping) { m_LSL_Functions.llLookAt(target, strength, damping); } + public void llStopLookAt() { m_LSL_Functions.llStopLookAt(); } + public void llSetTimerEvent(double sec) { m_LSL_Functions.llSetTimerEvent(sec); } + public void llSleep(double sec) { m_LSL_Functions.llSleep(sec); } + // + // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs + // + public double llGetMass() { return m_LSL_Functions.llGetMass(); } + public void llCollisionFilter(string name, string id, int accept) { m_LSL_Functions.llCollisionFilter(name, id, accept); } + public void llTakeControls(int controls, int accept, int pass_on) { m_LSL_Functions.llTakeControls(controls, accept, pass_on); } + public void llReleaseControls() { m_LSL_Functions.llReleaseControls(); } + public void llAttachToAvatar(int attachment) { m_LSL_Functions.llAttachToAvatar(attachment); } + public void llDetachFromAvatar() { m_LSL_Functions.llDetachFromAvatar(); } + public void llTakeCamera() { m_LSL_Functions.llTakeCamera(); } + public void llReleaseCamera() { m_LSL_Functions.llReleaseCamera(); } + public string llGetOwner() { return m_LSL_Functions.llGetOwner(); } + public void llInstantMessage(string user, string message) { m_LSL_Functions.llInstantMessage(user, message); } + public void llEmail(string address, string subject, string message) { m_LSL_Functions.llEmail(address, subject, message); } + public void llGetNextEmail(string address, string subject) { m_LSL_Functions.llGetNextEmail(address, subject); } + public string llGetKey() { return m_LSL_Functions.llGetKey(); } + public void llSetBuoyancy(double buoyancy) { m_LSL_Functions.llSetBuoyancy(buoyancy); } + public void llSetHoverHeight(double height, int water, double tau) { m_LSL_Functions.llSetHoverHeight(height, water, tau); } + public void llStopHover() { m_LSL_Functions.llStopHover(); } + public void llMinEventDelay(double delay) { m_LSL_Functions.llMinEventDelay(delay); } + public void llSoundPreload() { m_LSL_Functions.llSoundPreload(); } + public void llRotLookAt(LSL_Types.Quaternion target, double strength, double damping) { m_LSL_Functions.llRotLookAt(target, strength, damping); } + // + // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs + // + public int llStringLength(string str) { return m_LSL_Functions.llStringLength(str); } + public void llStartAnimation(string anim) { m_LSL_Functions.llStartAnimation(anim); } + public void llStopAnimation(string anim) { m_LSL_Functions.llStopAnimation(anim); } + public void llPointAt() { m_LSL_Functions.llPointAt(); } + public void llStopPointAt() { m_LSL_Functions.llStopPointAt(); } + public void llTargetOmega(LSL_Types.Vector3 axis, double spinrate, double gain) { m_LSL_Functions.llTargetOmega(axis, spinrate, gain); } + public int llGetStartParameter() { return m_LSL_Functions.llGetStartParameter(); } + public void llGodLikeRezObject(string inventory, LSL_Types.Vector3 pos) { m_LSL_Functions.llGodLikeRezObject(inventory, pos); } + public void llRequestPermissions(string agent, int perm) { m_LSL_Functions.llRequestPermissions(agent, perm); } + public string llGetPermissionsKey() { return m_LSL_Functions.llGetPermissionsKey(); } + public int llGetPermissions() { return m_LSL_Functions.llGetPermissions(); } + public int llGetLinkNumber() { return m_LSL_Functions.llGetLinkNumber(); } + public void llSetLinkColor(int linknumber, LSL_Types.Vector3 color, int face) { m_LSL_Functions.llSetLinkColor(linknumber, color, face); } + public void llCreateLink(string target, int parent) { m_LSL_Functions.llCreateLink(target, parent); } + public void llBreakLink(int linknum) { m_LSL_Functions.llBreakLink(linknum); } + public void llBreakAllLinks() { m_LSL_Functions.llBreakAllLinks(); } + public string llGetLinkKey(int linknum) { return m_LSL_Functions.llGetLinkKey(linknum); } + public void llGetLinkName(int linknum) { m_LSL_Functions.llGetLinkName(linknum); } + public int llGetInventoryNumber(int type) { return m_LSL_Functions.llGetInventoryNumber(type); } + public string llGetInventoryName(int type, int number) { return m_LSL_Functions.llGetInventoryName(type, number); } + // + // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs + // + public void llSetScriptState(string name, int run) { m_LSL_Functions.llSetScriptState(name, run); } + public double llGetEnergy() { return m_LSL_Functions.llGetEnergy(); } + public void llGiveInventory(string destination, string inventory) { m_LSL_Functions.llGiveInventory(destination, inventory); } + public void llRemoveInventory(string item) { m_LSL_Functions.llRemoveInventory(item); } + public void llSetText(string text, LSL_Types.Vector3 color, double alpha) { m_LSL_Functions.llSetText(text, color, alpha); } + public double llWater(LSL_Types.Vector3 offset) { return m_LSL_Functions.llWater(offset); } + public void llPassTouches(int pass) { m_LSL_Functions.llPassTouches(pass); } + public string llRequestAgentData(string id, int data) { return m_LSL_Functions.llRequestAgentData(id, data); } + public string llRequestInventoryData(string name) { return m_LSL_Functions.llRequestInventoryData(name); } + public void llSetDamage(double damage) { m_LSL_Functions.llSetDamage(damage); } + public void llTeleportAgentHome(string agent) { m_LSL_Functions.llTeleportAgentHome(agent); } + public void llModifyLand(int action, int brush) { m_LSL_Functions.llModifyLand(action, brush); } + public void llCollisionSound(string impact_sound, double impact_volume) { m_LSL_Functions.llCollisionSound(impact_sound, impact_volume); } + public void llCollisionSprite(string impact_sprite) { m_LSL_Functions.llCollisionSprite(impact_sprite); } + public string llGetAnimation(string id) { return m_LSL_Functions.llGetAnimation(id); } + public void llResetScript() { m_LSL_Functions.llResetScript(); } + public void llMessageLinked(int linknum, int num, string str, string id) { m_LSL_Functions.llMessageLinked(linknum, num, str, id); } + public void llPushObject(string target, LSL_Types.Vector3 impulse, LSL_Types.Vector3 ang_impulse, int local) { m_LSL_Functions.llPushObject(target, impulse, ang_impulse, local); } + public void llPassCollisions(int pass) { m_LSL_Functions.llPassCollisions(pass); } + public string llGetScriptName() { return m_LSL_Functions.llGetScriptName(); } + public int llGetNumberOfSides() { return m_LSL_Functions.llGetNumberOfSides(); } + // + // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs + // + public LSL_Types.Quaternion llAxisAngle2Rot(LSL_Types.Vector3 axis, double angle) { return m_LSL_Functions.llAxisAngle2Rot(axis, angle); } + public LSL_Types.Vector3 llRot2Axis(LSL_Types.Quaternion rot) { return m_LSL_Functions.llRot2Axis(rot); } + public void llRot2Angle() { m_LSL_Functions.llRot2Angle(); } + public double llAcos(double val) { return m_LSL_Functions.llAcos(val); } + public double llAsin(double val) { return m_LSL_Functions.llAsin(val); } + public double llAngleBetween(LSL_Types.Quaternion a, LSL_Types.Quaternion b) { return m_LSL_Functions.llAngleBetween(a, b); } + public string llGetInventoryKey(string name) { return m_LSL_Functions.llGetInventoryKey(name); } + public void llAllowInventoryDrop(int add) { m_LSL_Functions.llAllowInventoryDrop(add); } + public LSL_Types.Vector3 llGetSunDirection() { return m_LSL_Functions.llGetSunDirection(); } + public LSL_Types.Vector3 llGetTextureOffset(int face) { return m_LSL_Functions.llGetTextureOffset(face); } + public LSL_Types.Vector3 llGetTextureScale(int side) { return m_LSL_Functions.llGetTextureScale(side); } + public double llGetTextureRot(int side) { return m_LSL_Functions.llGetTextureRot(side); } + public int llSubStringIndex(string source, string pattern) { return m_LSL_Functions.llSubStringIndex(source, pattern); } + public string llGetOwnerKey(string id) { return m_LSL_Functions.llGetOwnerKey(id); } + public LSL_Types.Vector3 llGetCenterOfMass() { return m_LSL_Functions.llGetCenterOfMass(); } + public List llListSort(List src, int stride, int ascending) { return m_LSL_Functions.llListSort(src, stride, ascending); } + public int llGetListLength(List src) { return m_LSL_Functions.llGetListLength(src); } + // + // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs + // + public int llList2Integer(List src, int index) { return m_LSL_Functions.llList2Integer(src, index); } + public double llList2double(List src, int index) { return m_LSL_Functions.llList2double(src, index); } + public string llList2String(List src, int index) { return m_LSL_Functions.llList2String(src, index); } + public string llList2Key(List src, int index) { return m_LSL_Functions.llList2Key(src, index); } + public LSL_Types.Vector3 llList2Vector(List src, int index) { return m_LSL_Functions.llList2Vector(src, index); } + public LSL_Types.Quaternion llList2Rot(List src, int index) { return m_LSL_Functions.llList2Rot(src, index); } + public List llList2List(List src, int start, int end) { return m_LSL_Functions.llList2List(src, start, end); } + public List llDeleteSubList(List src, int start, int end) { return m_LSL_Functions.llDeleteSubList(src, start, end); } + public int llGetListEntryType(List src, int index) { return m_LSL_Functions.llGetListEntryType(src, index); } + public string llList2CSV(List src) { return m_LSL_Functions.llList2CSV(src); } + public List llCSV2List(string src) { return m_LSL_Functions.llCSV2List(src); } + public List llListRandomize(List src, int stride) { return m_LSL_Functions.llListRandomize(src, stride); } + public List llList2ListStrided(List src, int start, int end, int stride) { return m_LSL_Functions.llList2ListStrided(src, start, end, stride); } + public LSL_Types.Vector3 llGetRegionCorner() { return m_LSL_Functions.llGetRegionCorner(); } + public List llListInsertList(List dest, List src, int start) { return m_LSL_Functions.llListInsertList(dest, src, start); } + public int llListFindList(List src, List test) { return m_LSL_Functions.llListFindList(src, test); } + public string llGetObjectName() { return m_LSL_Functions.llGetObjectName(); } + public void llSetObjectName(string name) { m_LSL_Functions.llSetObjectName(name); } + public string llGetDate() { return m_LSL_Functions.llGetDate(); } + public int llEdgeOfWorld(LSL_Types.Vector3 pos, LSL_Types.Vector3 dir) { return m_LSL_Functions.llEdgeOfWorld(pos, dir); } + public int llGetAgentInfo(string id) { return m_LSL_Functions.llGetAgentInfo(id); } + // + // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs + // + public void llAdjustSoundVolume(double volume) { m_LSL_Functions.llAdjustSoundVolume(volume); } + public void llSetSoundQueueing(int queue) { m_LSL_Functions.llSetSoundQueueing(queue); } + public void llSetSoundRadius(double radius) { m_LSL_Functions.llSetSoundRadius(radius); } + public string llKey2Name(string id) { return m_LSL_Functions.llKey2Name(id); } + public void llSetTextureAnim(int mode, int face, int sizex, int sizey, double start, double length, double rate) { m_LSL_Functions.llSetTextureAnim(mode, face, sizex, sizey, start, length, rate); } + public void llTriggerSoundLimited(string sound, double volume, LSL_Types.Vector3 top_north_east, LSL_Types.Vector3 bottom_south_west) { m_LSL_Functions.llTriggerSoundLimited(sound, volume, top_north_east, bottom_south_west); } + public void llEjectFromLand(string pest) { m_LSL_Functions.llEjectFromLand(pest); } + public void llParseString2List() { m_LSL_Functions.llParseString2List(); } + public int llOverMyLand(string id) { return m_LSL_Functions.llOverMyLand(id); } + public string llGetLandOwnerAt(LSL_Types.Vector3 pos) { return m_LSL_Functions.llGetLandOwnerAt(pos); } + public string llGetNotecardLine(string name, int line) { return m_LSL_Functions.llGetNotecardLine(name, line); } + public LSL_Types.Vector3 llGetAgentSize(string id) { return m_LSL_Functions.llGetAgentSize(id); } + public int llSameGroup(string agent) { return m_LSL_Functions.llSameGroup(agent); } + public void llUnSit(string id) { m_LSL_Functions.llUnSit(id); } + public LSL_Types.Vector3 llGroundSlope(LSL_Types.Vector3 offset) { return m_LSL_Functions.llGroundSlope(offset); } + public LSL_Types.Vector3 llGroundNormal(LSL_Types.Vector3 offset) { return m_LSL_Functions.llGroundNormal(offset); } + public LSL_Types.Vector3 llGroundContour(LSL_Types.Vector3 offset) { return m_LSL_Functions.llGroundContour(offset); } + public int llGetAttached() { return m_LSL_Functions.llGetAttached(); } + public int llGetFreeMemory() { return m_LSL_Functions.llGetFreeMemory(); } + public string llGetRegionName() { return m_LSL_Functions.llGetRegionName(); } + public double llGetRegionTimeDilation() { return m_LSL_Functions.llGetRegionTimeDilation(); } + public double llGetRegionFPS() { return m_LSL_Functions.llGetRegionFPS(); } + // + // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs + // + public void llParticleSystem(List rules) { m_LSL_Functions.llParticleSystem(rules); } + public void llGroundRepel(double height, int water, double tau) { m_LSL_Functions.llGroundRepel(height, water, tau); } + public void llGiveInventoryList() { m_LSL_Functions.llGiveInventoryList(); } + public void llSetVehicleType(int type) { m_LSL_Functions.llSetVehicleType(type); } + public void llSetVehicledoubleParam(int param, double value) { m_LSL_Functions.llSetVehicledoubleParam(param, value); } + public void llSetVehicleVectorParam(int param, LSL_Types.Vector3 vec) { m_LSL_Functions.llSetVehicleVectorParam(param, vec); } + public void llSetVehicleRotationParam(int param, LSL_Types.Quaternion rot) { m_LSL_Functions.llSetVehicleRotationParam(param, rot); } + public void llSetVehicleFlags(int flags) { m_LSL_Functions.llSetVehicleFlags(flags); } + public void llRemoveVehicleFlags(int flags) { m_LSL_Functions.llRemoveVehicleFlags(flags); } + public void llSitTarget(LSL_Types.Vector3 offset, LSL_Types.Quaternion rot) { m_LSL_Functions.llSitTarget(offset, rot); } + public string llAvatarOnSitTarget() { return m_LSL_Functions.llAvatarOnSitTarget(); } + public void llAddToLandPassList(string avatar, double hours) { m_LSL_Functions.llAddToLandPassList(avatar, hours); } + public void llSetTouchText(string text) { m_LSL_Functions.llSetTouchText(text); } + public void llSetSitText(string text) { m_LSL_Functions.llSetSitText(text); } + public void llSetCameraEyeOffset(LSL_Types.Vector3 offset) { m_LSL_Functions.llSetCameraEyeOffset(offset); } + public void llSetCameraAtOffset(LSL_Types.Vector3 offset) { m_LSL_Functions.llSetCameraAtOffset(offset); } + public void llDumpList2String() { m_LSL_Functions.llDumpList2String(); } + public void llScriptDanger(LSL_Types.Vector3 pos) { m_LSL_Functions.llScriptDanger(pos); } + public void llDialog(string avatar, string message, List buttons, int chat_channel) { m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); } + public void llVolumeDetect(int detect) { m_LSL_Functions.llVolumeDetect(detect); } + public void llResetOtherScript(string name) { m_LSL_Functions.llResetOtherScript(name); } + public int llGetScriptState(string name) { return m_LSL_Functions.llGetScriptState(name); } + public void llRemoteLoadScript() { m_LSL_Functions.llRemoteLoadScript(); } + public void llSetRemoteScriptAccessPin(int pin) { m_LSL_Functions.llSetRemoteScriptAccessPin(pin); } + public void llRemoteLoadScriptPin(string target, string name, int pin, int running, int start_param) { m_LSL_Functions.llRemoteLoadScriptPin(target, name, pin, running, start_param); } + // + // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs + // + public void llOpenRemoteDataChannel() { m_LSL_Functions.llOpenRemoteDataChannel(); } + public string llSendRemoteData(string channel, string dest, int idata, string sdata) { return m_LSL_Functions.llSendRemoteData(channel, dest, idata, sdata); } + public void llRemoteDataReply(string channel, string message_id, string sdata, int idata) { m_LSL_Functions.llRemoteDataReply(channel, message_id, sdata, idata); } + public void llCloseRemoteDataChannel(string channel) { m_LSL_Functions.llCloseRemoteDataChannel(channel); } + public string llMD5String(string src, int nonce) { return m_LSL_Functions.llMD5String(src, nonce); } + public void llSetPrimitiveParams(List rules) { m_LSL_Functions.llSetPrimitiveParams(rules); } + public string llStringToBase64(string str) { return m_LSL_Functions.llStringToBase64(str); } + public string llBase64ToString(string str) { return m_LSL_Functions.llBase64ToString(str); } + public void llXorBase64Strings() { m_LSL_Functions.llXorBase64Strings(); } + public void llRemoteDataSetRegion() { m_LSL_Functions.llRemoteDataSetRegion(); } + public double llLog10(double val) { return m_LSL_Functions.llLog10(val); } + public double llLog(double val) { return m_LSL_Functions.llLog(val); } + public List llGetAnimationList(string id) { return m_LSL_Functions.llGetAnimationList(id); } + public void llSetParcelMusicURL(string url) { m_LSL_Functions.llSetParcelMusicURL(url); } + public LSL_Types.Vector3 llGetRootPosition() { return m_LSL_Functions.llGetRootPosition(); } + public LSL_Types.Quaternion llGetRootRotation() { return m_LSL_Functions.llGetRootRotation(); } + public string llGetObjectDesc() { return m_LSL_Functions.llGetObjectDesc(); } + public void llSetObjectDesc(string desc) { m_LSL_Functions.llSetObjectDesc(desc); } + public string llGetCreator() { return m_LSL_Functions.llGetCreator(); } + public string llGetTimestamp() { return m_LSL_Functions.llGetTimestamp(); } + public void llSetLinkAlpha(int linknumber, double alpha, int face) { m_LSL_Functions.llSetLinkAlpha(linknumber, alpha, face); } + public int llGetNumberOfPrims() { return m_LSL_Functions.llGetNumberOfPrims(); } + public string llGetNumberOfNotecardLines(string name) { return m_LSL_Functions.llGetNumberOfNotecardLines(name); } + public List llGetBoundingBox(string obj) { return m_LSL_Functions.llGetBoundingBox(obj); } + public LSL_Types.Vector3 llGetGeometricCenter() { return m_LSL_Functions.llGetGeometricCenter(); } + public void llGetPrimitiveParams() { m_LSL_Functions.llGetPrimitiveParams(); } + // + // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs + // + public string llIntegerToBase64(int number) { return m_LSL_Functions.llIntegerToBase64(number); } + public int llBase64ToInteger(string str) { return m_LSL_Functions.llBase64ToInteger(str); } + public double llGetGMTclock() { return m_LSL_Functions.llGetGMTclock(); } + public string llGetSimulatorHostname() { return m_LSL_Functions.llGetSimulatorHostname(); } + public void llSetLocalRot(LSL_Types.Quaternion rot) { m_LSL_Functions.llSetLocalRot(rot); } + public List llParseStringKeepNulls(string src, List seperators, List spacers) { return m_LSL_Functions.llParseStringKeepNulls(src, seperators, spacers); } + public void llRezAtRoot(string inventory, LSL_Types.Vector3 position, LSL_Types.Vector3 velocity, LSL_Types.Quaternion rot, int param) { m_LSL_Functions.llRezAtRoot(inventory, position, velocity, rot, param); } + public int llGetObjectPermMask(int mask) { return m_LSL_Functions.llGetObjectPermMask(mask); } + public void llSetObjectPermMask(int mask, int value) { m_LSL_Functions.llSetObjectPermMask(mask, value); } + public void llGetInventoryPermMask(string item, int mask) { m_LSL_Functions.llGetInventoryPermMask(item, mask); } + public void llSetInventoryPermMask(string item, int mask, int value) { m_LSL_Functions.llSetInventoryPermMask(item, mask, value); } + public string llGetInventoryCreator(string item) { return m_LSL_Functions.llGetInventoryCreator(item); } + public void llOwnerSay(string msg) { m_LSL_Functions.llOwnerSay(msg); } + public void llRequestSimulatorData(string simulator, int data) { m_LSL_Functions.llRequestSimulatorData(simulator, data); } + public void llForceMouselook(int mouselook) { m_LSL_Functions.llForceMouselook(mouselook); } + public double llGetObjectMass(string id) { return m_LSL_Functions.llGetObjectMass(id); } + public void llListReplaceList() { m_LSL_Functions.llListReplaceList(); } + public void llLoadURL(string avatar_id, string message, string url) { m_LSL_Functions.llLoadURL(avatar_id, message, url); } + public void llParcelMediaCommandList(List commandList) { m_LSL_Functions.llParcelMediaCommandList(commandList); } + public void llParcelMediaQuery() { m_LSL_Functions.llParcelMediaQuery(); } + public int llModPow(int a, int b, int c) { return m_LSL_Functions.llModPow(a, b, c); } + // + // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs + // + public int llGetInventoryType(string name) { return m_LSL_Functions.llGetInventoryType(name); } + public void llSetPayPrice(int price, List quick_pay_buttons) { m_LSL_Functions.llSetPayPrice(price, quick_pay_buttons); } + public LSL_Types.Vector3 llGetCameraPos() { return m_LSL_Functions.llGetCameraPos(); } + public LSL_Types.Quaternion llGetCameraRot() { return m_LSL_Functions.llGetCameraRot(); } + public void llSetPrimURL() { m_LSL_Functions.llSetPrimURL(); } + public void llRefreshPrimURL() { m_LSL_Functions.llRefreshPrimURL(); } + public string llEscapeURL(string url) { return m_LSL_Functions.llEscapeURL(url); } + public string llUnescapeURL(string url) { return m_LSL_Functions.llUnescapeURL(url); } + public void llMapDestination(string simname, LSL_Types.Vector3 pos, LSL_Types.Vector3 look_at) { m_LSL_Functions.llMapDestination(simname, pos, look_at); } + public void llAddToLandBanList(string avatar, double hours) { m_LSL_Functions.llAddToLandBanList(avatar, hours); } + public void llRemoveFromLandPassList(string avatar) { m_LSL_Functions.llRemoveFromLandPassList(avatar); } + public void llRemoveFromLandBanList(string avatar) { m_LSL_Functions.llRemoveFromLandBanList(avatar); } + public void llSetCameraParams(List rules) { m_LSL_Functions.llSetCameraParams(rules); } + public void llClearCameraParams() { m_LSL_Functions.llClearCameraParams(); } + public double llListStatistics(int operation, List src) { return m_LSL_Functions.llListStatistics(operation, src); } + public int llGetUnixTime() { return m_LSL_Functions.llGetUnixTime(); } + public int llGetParcelFlags(LSL_Types.Vector3 pos) { return m_LSL_Functions.llGetParcelFlags(pos); } + public int llGetRegionFlags() { return m_LSL_Functions.llGetRegionFlags(); } + public string llXorBase64StringsCorrect(string str1, string str2) { return m_LSL_Functions.llXorBase64StringsCorrect(str1, str2); } + public void llHTTPRequest() { m_LSL_Functions.llHTTPRequest(); } + public void llResetLandBanList() { m_LSL_Functions.llResetLandBanList(); } + public void llResetLandPassList() { m_LSL_Functions.llResetLandPassList(); } + public int llGetParcelPrimCount(LSL_Types.Vector3 pos, int category, int sim_wide) { return m_LSL_Functions.llGetParcelPrimCount(pos, category, sim_wide); } + public List llGetParcelPrimOwners(LSL_Types.Vector3 pos) { return m_LSL_Functions.llGetParcelPrimOwners(pos); } + public int llGetObjectPrimCount(string object_id) { return m_LSL_Functions.llGetObjectPrimCount(object_id); } + // + // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs + // + public int llGetParcelMaxPrims(LSL_Types.Vector3 pos, int sim_wide) { return m_LSL_Functions.llGetParcelMaxPrims(pos, sim_wide); } + public List llGetParcelDetails(LSL_Types.Vector3 pos, List param) { return m_LSL_Functions.llGetParcelDetails(pos, param); } + + + + + // LSL CONSTANTS + public const int TRUE = 1; + public const int FALSE = 0; + public const int STATUS_PHYSICS = 1; + public const int STATUS_ROTATE_X = 2; + public const int STATUS_ROTATE_Y = 4; + public const int STATUS_ROTATE_Z = 8; + public const int STATUS_PHANTOM = 16; + public const int STATUS_SANDBOX = 32; + public const int STATUS_BLOCK_GRAB = 64; + public const int STATUS_DIE_AT_EDGE = 128; + public const int STATUS_RETURN_AT_EDGE = 256; + public const int AGENT = 1; + public const int ACTIVE = 2; + public const int PASSIVE = 4; + public const int SCRIPTED = 8; + public const int CONTROL_FWD = 1; + public const int CONTROL_BACK = 2; + public const int CONTROL_LEFT = 4; + public const int CONTROL_RIGHT = 8; + public const int CONTROL_UP = 16; + public const int CONTROL_DOWN = 32; + public const int CONTROL_ROT_LEFT = 256; + public const int CONTROL_ROT_RIGHT = 512; + public const int CONTROL_LBUTTON = 268435456; + public const int CONTROL_ML_LBUTTON = 1073741824; + public const int PERMISSION_DEBIT = 2; + public const int PERMISSION_TAKE_CONTROLS = 4; + public const int PERMISSION_REMAP_CONTROLS = 8; + public const int PERMISSION_TRIGGER_ANIMATION = 16; + public const int PERMISSION_ATTACH = 32; + public const int PERMISSION_RELEASE_OWNERSHIP = 64; + public const int PERMISSION_CHANGE_LINKS = 128; + public const int PERMISSION_CHANGE_JOINTS = 256; + public const int PERMISSION_CHANGE_PERMISSIONS = 512; + public const int PERMISSION_TRACK_CAMERA = 1024; + public const int AGENT_FLYING = 1; + public const int AGENT_ATTACHMENTS = 2; + public const int AGENT_SCRIPTED = 4; + public const int AGENT_MOUSELOOK = 8; + public const int AGENT_SITTING = 16; + public const int AGENT_ON_OBJECT = 32; + public const int AGENT_AWAY = 64; + public const int AGENT_WALKING = 128; + public const int AGENT_IN_AIR = 256; + public const int AGENT_TYPING = 512; + public const int AGENT_CROUCHING = 1024; + public const int AGENT_BUSY = 2048; + public const int AGENT_ALWAYS_RUN = 4096; + public const int PSYS_PART_INTERP_COLOR_MASK = 1; + public const int PSYS_PART_INTERP_SCALE_MASK = 2; + public const int PSYS_PART_BOUNCE_MASK = 4; + public const int PSYS_PART_WIND_MASK = 8; + public const int PSYS_PART_FOLLOW_SRC_MASK = 16; + public const int PSYS_PART_FOLLOW_VELOCITY_MASK = 32; + public const int PSYS_PART_TARGET_POS_MASK = 64; + public const int PSYS_PART_TARGET_LINEAR_MASK = 128; + public const int PSYS_PART_EMISSIVE_MASK = 256; + public const int PSYS_PART_FLAGS = 0; + public const int PSYS_PART_START_COLOR = 1; + public const int PSYS_PART_START_ALPHA = 2; + public const int PSYS_PART_END_COLOR = 3; + public const int PSYS_PART_END_ALPHA = 4; + public const int PSYS_PART_START_SCALE = 5; + public const int PSYS_PART_END_SCALE = 6; + public const int PSYS_PART_MAX_AGE = 7; + public const int PSYS_SRC_ACCEL = 8; + public const int PSYS_SRC_PATTERN = 9; + public const int PSYS_SRC_INNERANGLE = 10; + public const int PSYS_SRC_OUTERANGLE = 11; + public const int PSYS_SRC_TEXTURE = 12; + public const int PSYS_SRC_BURST_RATE = 13; + public const int PSYS_SRC_BURST_PART_COUNT = 15; + public const int PSYS_SRC_BURST_RADIUS = 16; + public const int PSYS_SRC_BURST_SPEED_MIN = 17; + public const int PSYS_SRC_BURST_SPEED_MAX = 18; + public const int PSYS_SRC_MAX_AGE = 19; + public const int PSYS_SRC_TARGET_KEY = 20; + public const int PSYS_SRC_OMEGA = 21; + public const int PSYS_SRC_ANGLE_BEGIN = 22; + public const int PSYS_SRC_ANGLE_END = 23; + public const int PSYS_SRC_PATTERN_DROP = 1; + public const int PSYS_SRC_PATTERN_EXPLODE = 2; + public const int PSYS_SRC_PATTERN_ANGLE = 4; + public const int PSYS_SRC_PATTERN_ANGLE_CONE = 8; + public const int PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY = 16; + public const int VEHICLE_TYPE_NONE = 0; + public const int VEHICLE_TYPE_SLED = 1; + public const int VEHICLE_TYPE_CAR = 2; + public const int VEHICLE_TYPE_BOAT = 3; + public const int VEHICLE_TYPE_AIRPLANE = 4; + public const int VEHICLE_TYPE_BALLOON = 5; + public const int VEHICLE_LINEAR_FRICTION_TIMESCALE = 16; + public const int VEHICLE_ANGULAR_FRICTION_TIMESCALE = 17; + public const int VEHICLE_LINEAR_MOTOR_DIRECTION = 18; + public const int VEHICLE_LINEAR_MOTOR_OFFSET = 20; + public const int VEHICLE_ANGULAR_MOTOR_DIRECTION = 19; + public const int VEHICLE_HOVER_HEIGHT = 24; + public const int VEHICLE_HOVER_EFFICIENCY = 25; + public const int VEHICLE_HOVER_TIMESCALE = 26; + public const int VEHICLE_BUOYANCY = 27; + public const int VEHICLE_LINEAR_DEFLECTION_EFFICIENCY = 28; + public const int VEHICLE_LINEAR_DEFLECTION_TIMESCALE = 29; + public const int VEHICLE_LINEAR_MOTOR_TIMESCALE = 30; + public const int VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE = 31; + public const int VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY = 32; + public const int VEHICLE_ANGULAR_DEFLECTION_TIMESCALE = 33; + public const int VEHICLE_ANGULAR_MOTOR_TIMESCALE = 34; + public const int VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE = 35; + public const int VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY = 36; + public const int VEHICLE_VERTICAL_ATTRACTION_TIMESCALE = 37; + public const int VEHICLE_BANKING_EFFICIENCY = 38; + public const int VEHICLE_BANKING_MIX = 39; + public const int VEHICLE_BANKING_TIMESCALE = 40; + public const int VEHICLE_REFERENCE_FRAME = 44; + public const int VEHICLE_FLAG_NO_DEFLECTION_UP = 1; + public const int VEHICLE_FLAG_LIMIT_ROLL_ONLY = 2; + public const int VEHICLE_FLAG_HOVER_WATER_ONLY = 4; + public const int VEHICLE_FLAG_HOVER_TERRAIN_ONLY = 8; + public const int VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT = 16; + public const int VEHICLE_FLAG_HOVER_UP_ONLY = 32; + public const int VEHICLE_FLAG_LIMIT_MOTOR_UP = 64; + public const int VEHICLE_FLAG_MOUSELOOK_STEER = 128; + public const int VEHICLE_FLAG_MOUSELOOK_BANK = 256; + public const int VEHICLE_FLAG_CAMERA_DECOUPLED = 512; + public const int INVENTORY_ALL = -1; + public const int INVENTORY_NONE = -1; + public const int INVENTORY_TEXTURE = 0; + public const int INVENTORY_SOUND = 1; + public const int INVENTORY_LANDMARK = 3; + public const int INVENTORY_CLOTHING = 5; + public const int INVENTORY_OBJECT = 6; + public const int INVENTORY_NOTECARD = 7; + public const int INVENTORY_SCRIPT = 10; + public const int INVENTORY_BODYPART = 13; + public const int INVENTORY_ANIMATION = 20; + public const int INVENTORY_GESTURE = 21; + public const int ATTACH_CHEST = 1; + public const int ATTACH_HEAD = 2; + public const int ATTACH_LSHOULDER = 3; + public const int ATTACH_RSHOULDER = 4; + public const int ATTACH_LHAND = 5; + public const int ATTACH_RHAND = 6; + public const int ATTACH_LFOOT = 7; + public const int ATTACH_RFOOT = 8; + public const int ATTACH_BACK = 9; + public const int ATTACH_PELVIS = 10; + public const int ATTACH_MOUTH = 11; + public const int ATTACH_CHIN = 12; + public const int ATTACH_LEAR = 13; + public const int ATTACH_REAR = 14; + public const int ATTACH_LEYE = 15; + public const int ATTACH_REYE = 16; + public const int ATTACH_NOSE = 17; + public const int ATTACH_RUARM = 18; + public const int ATTACH_RLARM = 19; + public const int ATTACH_LUARM = 20; + public const int ATTACH_LLARM = 21; + public const int ATTACH_RHIP = 22; + public const int ATTACH_RULEG = 23; + public const int ATTACH_RLLEG = 24; + public const int ATTACH_LHIP = 25; + public const int ATTACH_LULEG = 26; + public const int ATTACH_LLLEG = 27; + public const int ATTACH_BELLY = 28; + public const int ATTACH_RPEC = 29; + public const int ATTACH_LPEC = 30; + public const int LAND_LEVEL = 0; + public const int LAND_RAISE = 1; + public const int LAND_LOWER = 2; + public const int LAND_SMOOTH = 3; + public const int LAND_NOISE = 4; + public const int LAND_REVERT = 5; + public const int LAND_SMALL_BRUSH = 1; + public const int LAND_MEDIUM_BRUSH = 2; + public const int LAND_LARGE_BRUSH = 3; + public const int DATA_ONLINE = 1; + public const int DATA_NAME = 2; + public const int DATA_BORN = 3; + public const int DATA_RATING = 4; + public const int DATA_SIM_POS = 5; + public const int DATA_SIM_STATUS = 6; + public const int DATA_SIM_RATING = 7; + public const int ANIM_ON = 1; + public const int LOOP = 2; + public const int REVERSE = 4; + public const int PING_PONG = 8; + public const int SMOOTH = 16; + public const int ROTATE = 32; + public const int SCALE = 64; + public const int ALL_SIDES = -1; + public const int LINK_SET = -1; + public const int LINK_ROOT = 1; + public const int LINK_ALL_OTHERS = -2; + public const int LINK_ALL_CHILDREN = -3; + public const int LINK_THIS = -4; + public const int CHANGED_INVENTORY = 1; + public const int CHANGED_COLOR = 2; + public const int CHANGED_SHAPE = 4; + public const int CHANGED_SCALE = 8; + public const int CHANGED_TEXTURE = 16; + public const int CHANGED_LINK = 32; + public const int CHANGED_ALLOWED_DROP = 64; + public const int CHANGED_OWNER = 128; + public const int TYPE_INVALID = 0; + public const int TYPE_INTEGER = 1; + public const int TYPE_double = 2; + public const int TYPE_STRING = 3; + public const int TYPE_KEY = 4; + public const int TYPE_VECTOR = 5; + public const int TYPE_ROTATION = 6; + public const int REMOTE_DATA_CHANNEL = 1; + public const int REMOTE_DATA_REQUEST = 2; + public const int REMOTE_DATA_REPLY = 3; + //public const int PRIM_TYPE = 1; + public const int PRIM_MATERIAL = 2; + public const int PRIM_PHYSICS = 3; + public const int PRIM_TEMP_ON_REZ = 4; + public const int PRIM_PHANTOM = 5; + public const int PRIM_POSITION = 6; + public const int PRIM_SIZE = 7; + public const int PRIM_ROTATION = 8; + public const int PRIM_TYPE = 9; + public const int PRIM_TEXTURE = 17; + public const int PRIM_COLOR = 18; + public const int PRIM_BUMP_SHINY = 19; + public const int PRIM_FULLBRIGHT = 20; + public const int PRIM_FLEXIBLE = 21; + public const int PRIM_TEXGEN = 22; + public const int PRIM_TEXGEN_DEFAULT = 0; + public const int PRIM_TEXGEN_PLANAR = 1; + public const int PRIM_TYPE_BOX = 0; + public const int PRIM_TYPE_CYLINDER = 1; + public const int PRIM_TYPE_PRISM = 2; + public const int PRIM_TYPE_SPHERE = 3; + public const int PRIM_TYPE_TORUS = 4; + public const int PRIM_TYPE_TUBE = 5; + public const int PRIM_TYPE_RING = 6; + public const int PRIM_HOLE_DEFAULT = 0; + public const int PRIM_HOLE_CIRCLE = 16; + public const int PRIM_HOLE_SQUARE = 32; + public const int PRIM_HOLE_TRIANGLE = 48; + public const int PRIM_MATERIAL_STONE = 0; + public const int PRIM_MATERIAL_METAL = 1; + public const int PRIM_MATERIAL_GLASS = 2; + public const int PRIM_MATERIAL_WOOD = 3; + public const int PRIM_MATERIAL_FLESH = 4; + public const int PRIM_MATERIAL_PLASTIC = 5; + public const int PRIM_MATERIAL_RUBBER = 6; + public const int PRIM_MATERIAL_LIGHT = 7; + public const int PRIM_SHINY_NONE = 0; + public const int PRIM_SHINY_LOW = 1; + public const int PRIM_SHINY_MEDIUM = 2; + public const int PRIM_SHINY_HIGH = 3; + public const int PRIM_BUMP_NONE = 0; + public const int PRIM_BUMP_BRIGHT = 1; + public const int PRIM_BUMP_DARK = 2; + public const int PRIM_BUMP_WOOD = 3; + public const int PRIM_BUMP_BARK = 4; + public const int PRIM_BUMP_BRICKS = 5; + public const int PRIM_BUMP_CHECKER = 6; + public const int PRIM_BUMP_CONCRETE = 7; + public const int PRIM_BUMP_TILE = 8; + public const int PRIM_BUMP_STONE = 9; + public const int PRIM_BUMP_DISKS = 10; + public const int PRIM_BUMP_GRAVEL = 11; + public const int PRIM_BUMP_BLOBS = 12; + public const int PRIM_BUMP_SIDING = 13; + public const int PRIM_BUMP_LARGETILE = 14; + public const int PRIM_BUMP_STUCCO = 15; + public const int PRIM_BUMP_SUCTION = 16; + public const int PRIM_BUMP_WEAVE = 17; + public const int MASK_BASE = 0; + public const int MASK_OWNER = 1; + public const int MASK_GROUP = 2; + public const int MASK_EVERYONE = 3; + public const int MASK_NEXT = 4; + public const int PERM_TRANSFER = 8192; + public const int PERM_MODIFY = 16384; + public const int PERM_COPY = 32768; + public const int PERM_MOVE = 524288; + public const int PERM_ALL = 2147483647; + public const int PARCEL_MEDIA_COMMAND_STOP = 0; + public const int PARCEL_MEDIA_COMMAND_PAUSE = 1; + public const int PARCEL_MEDIA_COMMAND_PLAY = 2; + public const int PARCEL_MEDIA_COMMAND_LOOP = 3; + public const int PARCEL_MEDIA_COMMAND_TEXTURE = 4; + public const int PARCEL_MEDIA_COMMAND_URL = 5; + public const int PARCEL_MEDIA_COMMAND_TIME = 6; + public const int PARCEL_MEDIA_COMMAND_AGENT = 7; + public const int PARCEL_MEDIA_COMMAND_UNLOAD = 8; + public const int PARCEL_MEDIA_COMMAND_AUTO_ALIGN = 9; + public const int PAY_HIDE = -1; + public const int PAY_DEFAULT = -2; + public const string NULL_KEY = "00000000-0000-0000-0000-000000000000"; + public const string EOF = "\n\n\n"; + public const double PI = 3.14159274f; + public const double TWO_PI = 6.28318548f; + public const double PI_BY_TWO = 1.57079637f; + public const double DEG_TO_RAD = 0.01745329238f; + public const double RAD_TO_DEG = 57.29578f; + public const double SQRT2 = 1.414213538f; + + // Can not be public const? + public LSL_Types.Vector3 ZERO_VECTOR = new LSL_Types.Vector3(0, 0, 0); + public LSL_Types.Quaternion ZERO_ROTATION = new LSL_Types.Quaternion(0, 0, 0, 0); + + + + } +} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/Common.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/Common.cs new file mode 100644 index 0000000000..3ea167c000 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/Common.cs @@ -0,0 +1,84 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +/* Original code: Tedd Hansen */ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSO +{ + public static class Common + { + static public bool Debug = true; + static public bool IL_UseTryCatch = true; + static public bool IL_CreateConstructor = true; + static public bool IL_CreateFunctionList = true; + static public bool IL_ProcessCodeChunks = true; + + public delegate void SendToDebugEventDelegate(string Message); + public delegate void SendToLogEventDelegate(string Message); + static public event SendToDebugEventDelegate SendToDebugEvent; + static public event SendToLogEventDelegate SendToLogEvent; + + static public void SendToDebug(string Message) + { + //if (Debug == true) + Console.WriteLine("COMPILER:Debug: " + Message); + SendToDebugEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message); + } + static public void SendToLog(string Message) + { + //if (Debug == true) + Console.WriteLine("COMPILER:LOG: " + Message); + SendToLogEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message); + } + } + + // TEMPORARY TEST THINGIES + public static class IL_Helper + { + public static string ReverseFormatString(string text1, string format) + { + Common.SendToDebug("ReverseFormatString text1: " + text1); + Common.SendToDebug("ReverseFormatString format: " + format); + return string.Format(format, text1); + } + public static string ReverseFormatString(string text1, UInt32 text2, string format) + { + Common.SendToDebug("ReverseFormatString text1: " + text1); + Common.SendToDebug("ReverseFormatString text2: " + text2.ToString()); + Common.SendToDebug("ReverseFormatString format: " + format); + return string.Format(format, text1, text2.ToString()); + } + public static string Cast_ToString(object obj) + { + Common.SendToDebug("OBJECT TO BE CASTED: " + obj.GetType().ToString()); + return "ABCDEFGIHJKLMNOPQ123"; + } + } +} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/Engine.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/Engine.cs new file mode 100644 index 0000000000..b0608411c9 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/Engine.cs @@ -0,0 +1,300 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +/* Original code: Tedd Hansen */ +using System; +using System.Reflection; +using System.Reflection.Emit; +using System.Threading; + + +namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSO +{ + + + public class Engine + { + //private string LSO_FileName = @"LSO\AdditionTest.lso"; + private string LSO_FileName;// = @"LSO\CloseToDefault.lso"; + AppDomain appDomain; + + public string Compile(string LSOFileName) + { + LSO_FileName = LSOFileName; + + + //appDomain = AppDomain.CreateDomain("AlternateAppDomain"); + appDomain = Thread.GetDomain(); + + // Create Assembly Name + AssemblyName asmName = new AssemblyName(); + asmName.Name = System.IO.Path.GetFileNameWithoutExtension(LSO_FileName); + //asmName.Name = "TestAssembly"; + + string DLL_FileName = asmName.Name + ".dll"; + string DLL_FileName_WithPath = System.IO.Path.GetDirectoryName(LSO_FileName) + @"\" + DLL_FileName; + + Common.SendToLog("LSO File Name: " + System.IO.Path.GetFileName(LSO_FileName)); + Common.SendToLog("Assembly name: " + asmName.Name); + Common.SendToLog("Assembly File Name: " + asmName.Name + ".dll"); + Common.SendToLog("Starting processing of LSL ByteCode..."); + Common.SendToLog(""); + + + + // Create Assembly + AssemblyBuilder asmBuilder = appDomain.DefineDynamicAssembly( + asmName, + AssemblyBuilderAccess.RunAndSave + ); + //// Create Assembly + //AssemblyBuilder asmBuilder = + // Thread.GetDomain().DefineDynamicAssembly + //(asmName, AssemblyBuilderAccess.RunAndSave); + + // Create a module (and save to disk) + ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule + (asmName.Name, + DLL_FileName); + + //Common.SendToDebug("asmName.Name is still \"" + asmName.Name + "\""); + // Create a Class (/Type) + TypeBuilder typeBuilder = modBuilder.DefineType( + "LSL_ScriptObject", + TypeAttributes.Public | TypeAttributes.BeforeFieldInit, + typeof(OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSO.LSL_BaseClass)); + //, + // typeof()); + //, typeof(LSL_BuiltIn_Commands_Interface)); + //, + // typeof(object), + // new Type[] { typeof(LSL_CLRInterface.LSLScript) }); + + + + /* + * Generate the IL itself + */ + + LSO_Parser LSOP = new LSO_Parser(LSO_FileName, typeBuilder); + LSOP.OpenFile(); + LSOP.Parse(); + + // Constructor has to be created AFTER LSO_Parser because of accumulated variables + if (Common.IL_CreateConstructor) + IL_CREATE_CONSTRUCTOR(typeBuilder, LSOP); + + LSOP.CloseFile(); + /* + * Done generating. Create a type and run it. + */ + + + Common.SendToLog("Attempting to compile assembly..."); + // Compile it + Type type = typeBuilder.CreateType(); + Common.SendToLog("Compilation successful!"); + + Common.SendToLog("Saving assembly: " + DLL_FileName); + asmBuilder.Save(DLL_FileName); + + Common.SendToLog("Returning assembly filename: " + DLL_FileName); + + + return DLL_FileName; + + + //Common.SendToLog("Creating an instance of new assembly..."); + //// Create an instance we can play with + ////LSLScript hello = (LSLScript)Activator.CreateInstance(type); + ////LSL_CLRInterface.LSLScript MyScript = (LSL_CLRInterface.LSLScript)Activator.CreateInstance(type); + //object MyScript = (object)Activator.CreateInstance(type); + + + + + + //System.Reflection.MemberInfo[] Members = type.GetMembers(); + + //Common.SendToLog("Members of assembly " + type.ToString() + ":"); + //foreach (MemberInfo member in Members) + // Common.SendToLog(member.ToString()); + + + //// Play with it + ////MyScript.event_state_entry("Test"); + //object[] args = { null }; + ////System.Collections.Generic.List Functions = (System.Collections.Generic.List)type.InvokeMember("GetFunctions", BindingFlags.InvokeMethod, null, MyScript, null); + + //string[] ret = { }; + //if (Common.IL_CreateFunctionList) + // ret = (string[])type.InvokeMember("GetFunctions", BindingFlags.InvokeMethod, null, MyScript, null); + + //foreach (string s in ret) + //{ + // Common.SendToLog(""); + // Common.SendToLog("*** Executing LSL Server Event: " + s); + // //object test = type.GetMember(s); + // //object runner = type.InvokeMember(s, BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, MyScript, args); + // //runner(); + // //objBooks_Late = type.InvokeMember(s, BindingFlags.CreateInstance, null, objApp_Late, null); + // type.InvokeMember(s, BindingFlags.InvokeMethod, null, MyScript, new object[] { "Test" }); + + //} + + + } + + + private static void IL_CREATE_CONSTRUCTOR(TypeBuilder typeBuilder, LSO_Parser LSOP) + { + + + Common.SendToDebug("IL_CREATE_CONSTRUCTOR()"); + //ConstructorBuilder constructor = typeBuilder.DefineConstructor( + // MethodAttributes.Public, + // CallingConventions.Standard, + // new Type[0]); + ConstructorBuilder constructor = typeBuilder.DefineConstructor( + MethodAttributes.Public | + MethodAttributes.SpecialName | + MethodAttributes.RTSpecialName, + CallingConventions.Standard, + new Type[0]); + + //Define the reflection ConstructorInfor for System.Object + ConstructorInfo conObj = typeof(LSL_BaseClass).GetConstructor(new Type[0]); + + //call constructor of base object + ILGenerator il = constructor.GetILGenerator(); + + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Call, conObj); + + + //Common.SendToDebug("IL_CREATE_CONSTRUCTOR: Creating global: UInt32 State = 0;"); + //string FieldName; + //// Create state object + //FieldName = "State"; + //FieldBuilder State_fb = typeBuilder.DefineField( + // FieldName, + // typeof(UInt32), + // FieldAttributes.Public); + //il.Emit(OpCodes.Ldarg_0); + //il.Emit(OpCodes.Ldc_I4, 0); + //il.Emit(OpCodes.Stfld, State_fb); + + + //Common.SendToDebug("IL_CREATE_CONSTRUCTOR: Creating global: LSL_BuiltIn_Commands_TestImplementation LSL_BuiltIns = New LSL_BuiltIn_Commands_TestImplementation();"); + ////Type objType1 = typeof(object); + //Type objType1 = typeof(LSL_BuiltIn_Commands_TestImplementation); + + //FieldName = "LSL_BuiltIns"; + //FieldBuilder LSL_BuiltIns_fb = typeBuilder.DefineField( + // FieldName, + // objType1, + // FieldAttributes.Public); + + ////LSL_BuiltIn_Commands_TestImplementation _ti = new LSL_BuiltIn_Commands_TestImplementation(); + //il.Emit(OpCodes.Ldarg_0); + ////il.Emit(OpCodes.Ldstr, "Test 123"); + //il.Emit(OpCodes.Newobj, objType1.GetConstructor(new Type[] { })); + //il.Emit(OpCodes.Stfld, LSL_BuiltIns_fb); + + foreach (UInt32 pos in LSOP.StaticBlocks.Keys) + { + LSO_Struct.StaticBlock sb; + LSOP.StaticBlocks.TryGetValue(pos, out sb); + + if (sb.ObjectType > 0 && sb.ObjectType < 8) { // We don't want void or null's + + il.Emit(OpCodes.Ldarg_0); + // Push position to stack + il.Emit(OpCodes.Ldc_I4, pos); + //il.Emit(OpCodes.Box, typeof(UInt32)); + + + Type datatype = null; + + // Push data to stack + Common.SendToDebug("Adding to static (" + pos + ") type: " + ((LSO_Enums.Variable_Type_Codes)sb.ObjectType).ToString() + " (" + sb.ObjectType + ")"); + switch ((LSO_Enums.Variable_Type_Codes)sb.ObjectType) + { + case LSO_Enums.Variable_Type_Codes.Float: + case LSO_Enums.Variable_Type_Codes.Integer: + //UInt32 + il.Emit(OpCodes.Ldc_I4, BitConverter.ToUInt32(sb.BlockVariable, 0)); + datatype = typeof(UInt32); + il.Emit(OpCodes.Box, datatype); + break; + case LSO_Enums.Variable_Type_Codes.String: + case LSO_Enums.Variable_Type_Codes.Key: + //String + LSO_Struct.HeapBlock hb = LSOP.GetHeap(LSOP.myHeader.HR + BitConverter.ToUInt32(sb.BlockVariable, 0) - 1); + il.Emit(OpCodes.Ldstr, System.Text.Encoding.UTF8.GetString(hb.Data)); + datatype = typeof(string); + break; + case LSO_Enums.Variable_Type_Codes.Vector: + datatype = typeof(LSO_Enums.Vector); + //TODO: Not implemented + break; + case LSO_Enums.Variable_Type_Codes.Rotation: + //Object + //TODO: Not implemented + datatype = typeof(LSO_Enums.Rotation); + break; + default: + datatype = typeof(object); + break; + } + + + // Make call + il.Emit(OpCodes.Call, typeof(LSL_BaseClass).GetMethod("AddToStatic", new Type[] { typeof(UInt32), datatype })); + } + + } + + + + + ////il.Emit(OpCodes.Newobj, typeof(UInt32)); + //il.Emit(OpCodes.Starg_0); + //// Create LSL function library + //FieldBuilder LSL_BuiltIns_fb = typeBuilder.DefineField("LSL_BuiltIns", typeof(LSL_BuiltIn_Commands_Interface), FieldAttributes.Public); + //il.Emit(OpCodes.Newobj, typeof(LSL_BuiltIn_Commands_Interface)); + //il.Emit(OpCodes.Stloc_1); + + il.Emit(OpCodes.Ret); + } + + + + + // End of class + } +} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/IL_common_functions.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/IL_common_functions.cs new file mode 100644 index 0000000000..70533fbc1d --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/IL_common_functions.cs @@ -0,0 +1,56 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +/* Original code: Tedd Hansen */ +using System; +using System.Collections.Generic; +using System.Text; +using System.Reflection; +using System.Reflection.Emit; + +namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSO +{ + partial class LSO_Parser + { + private static TypeBuilder CreateType(ModuleBuilder modBuilder, string typeName) + { + TypeBuilder typeBuilder = modBuilder.DefineType(typeName, + TypeAttributes.Public | + TypeAttributes.Class | + TypeAttributes.AutoClass | + TypeAttributes.AnsiClass | + TypeAttributes.BeforeFieldInit | + TypeAttributes.AutoLayout, + typeof(object), + new Type[] { typeof(object) }); + return typeBuilder; + + } + + + } +} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSL_BaseClass.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSL_BaseClass.cs new file mode 100644 index 0000000000..374d37d1cf --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSL_BaseClass.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler; +using OpenSim.Region.ScriptEngine.Common; + +namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSO +{ + public partial class LSL_BaseClass + { + //public MemoryStream LSLStack = new MemoryStream(); + public Stack LSLStack = new Stack(); + public Dictionary StaticVariables = new Dictionary(); + public Dictionary GlobalVariables = new Dictionary(); + public Dictionary LocalVariables = new Dictionary(); + //public System.Collections.Generic.List FunctionList = new System.Collections.Generic.List(); + //public void AddFunction(String x) { + // FunctionList.Add(x); + //} + //public Stack LSLStack = new Stack; + //public struct StackItemStruct + //{ + // public LSO_Enums.Variable_Type_Codes ItemType; + // public object Data; + //} + public UInt32 State = 0; + public LSL_BuiltIn_Commands_Interface LSL_Builtins; + public LSL_BuiltIn_Commands_Interface GetLSL_BuiltIn() + { + return LSL_Builtins; + } + + + public LSL_BaseClass() { } + + + public virtual int OverrideMe() + { + return 0; + } + public void Start(LSL_BuiltIn_Commands_Interface LSLBuiltins) + { + LSL_Builtins = LSLBuiltins; + + Common.SendToLog("OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSO.LSL_BaseClass.Start() called"); + //LSL_Builtins.llSay(0, "Test"); + return; + } + + public void AddToStatic(UInt32 index, object obj) + { + Common.SendToDebug("AddToStatic: " + index + " type: " + obj.GetType()); + StaticVariables.Add(index, obj); + } + + + + } +} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSL_BaseClass_Builtins.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSL_BaseClass_Builtins.cs new file mode 100644 index 0000000000..d3ca62524d --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSL_BaseClass_Builtins.cs @@ -0,0 +1,373 @@ +//using System; +//using System.Collections.Generic; +//using System.Text; + +//namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSO +//{ +// public partial class LSL_BaseClass +// { + + +// public float llSin() { +// float f = (float)LSLStack.Pop(); +// return LSL_Builtins.llSin(f); +// } +// public float llCos() { +// float f = (float)LSLStack.Pop(); +// return LSL_Builtins.llCos(f); +// } +// public float llTan() { +// float f = (float)LSLStack.Pop(); +// return LSL_Builtins.llTan(f); +// } +// public float llAtan2() { +// float x = (float)LSLStack.Pop(); +// float y = (float)LSLStack.Pop(); +// return LSL_Builtins.llAtan2(x, y); +// } +// public float llSqrt() { +// float f = (float)LSLStack.Pop(); +// return LSL_Builtins.llSqrt(f); +// } +// float llPow() +// { +// float fexponent = (float)LSLStack.Pop(); +// float fbase = (float)LSLStack.Pop(); +// return LSL_Builtins.llPow(fbase, fexponent); +// } +// //UInt32 llAbs(UInt32 i){ return; } +// //float llFabs(float f){ return; } +// //float llFrand(float mag){ return; } +// //UInt32 llFloor(float f){ return; } +// //UInt32 llCeil(float f){ return; } +// //UInt32 llRound(float f){ return; } +// //float llVecMag(LSO_Enums.Vector v){ return; } +// //LSO_Enums.Vector llVecNorm(LSO_Enums.Vector v){ return; } +// //float llVecDist(LSO_Enums.Vector a, LSO_Enums.Vector b){ return; } +// //LSO_Enums.Vector llRot2Euler(LSO_Enums.Rotation r){ return; } +// //LSO_Enums.Rotation llEuler2Rot(LSO_Enums.Vector v){ return; } +// //LSO_Enums.Rotation llAxes2Rot(LSO_Enums.Vector fwd, LSO_Enums.Vector left, LSO_Enums.Vector up){ return; } +// //LSO_Enums.Vector llRot2Fwd(LSO_Enums.Rotation r){ return; } +// //LSO_Enums.Vector llRot2Left(LSO_Enums.Rotation r){ return; } +// //LSO_Enums.Vector llRot2Up(LSO_Enums.Rotation r){ return; } +// //LSO_Enums.Rotation llRotBetween(LSO_Enums.Vector start, LSO_Enums.Vector end){ return; } +// public void llWhisper() +// { +// UInt16 i = (UInt16)LSLStack.Pop(); +// string s = (string)LSLStack.Pop(); +// LSL_Builtins.llWhisper(i, s); +// } +// public void llSay() +// { +// UInt16 i = (UInt16)LSLStack.Pop(); +// string s = (string)LSLStack.Pop(); +// LSL_Builtins.llSay(i, s); +// } +// //void llShout(UInt16 channelID, string text); +// //UInt32 llListen(UInt16 channelID, string name, LSO_Enums.Key ID, string msg); +// //void llListenControl(UInt32 number, UInt32 active); +// //void llListenRemove(UInt32 number); +// //void llSensor(string name, LSO_Enums.Key id, UInt32 type, float range, float arc); +// //void llSensorRepeat(string name, LSO_Enums.Key id, UInt32 type, float range, float arc, float rate); +// //void llSensorRemove(); +// //string llDetectedName(UInt32 number); +// //LSO_Enums.Key llDetectedKey(UInt32 number); +// //LSO_Enums.Key llDetectedOwner(UInt32 number); +// //UInt32 llDetectedType(UInt32 number); +// //LSO_Enums.Vector llDetectedPos(UInt32 number); +// //LSO_Enums.Vector llDetectedVel(UInt32 number); +// //LSO_Enums.Vector llDetectedGrab(UInt32 number); +// //LSO_Enums.Rotation llDetectedRot(UInt32 number); +// //UInt32 llDetectedGroup(UInt32 number); +// //UInt32 llDetectedLinkNumber(UInt32 number); +// //void llDie(); +// //float llGround(LSO_Enums.Vector offset); +// //float llCloud(LSO_Enums.Vector offset); +// //LSO_Enums.Vector llWind(LSO_Enums.Vector offset); +// //void llSetStatus(UInt32 status, UInt32 value); +// //UInt32 llGetStatus(UInt32 status); +// //void llSetScale(LSO_Enums.Vector scale); +// //LSO_Enums.Vector llGetScale(); +// //void llSetColor(); +// //float llGetAlpha(); +// //void llSetAlpha(); +// //LSO_Enums.Vector llGetColor(); +// //void llSetTexture(); +// //void llScaleTexture(); +// //void llOffsetTexture(); +// //void llRotateTexture(); +// //string llGetTexture(); +// //void llSetPos(); + +// public void llGetPos() { } +// public void llGetLocalPos() { } +// public void llSetRot() { } +// public void llGetRot() { } +// public void llGetLocalRot() { } +// public void llSetForce() { } +// public void llGetForce() { } +// public void llTarget() { } +// public void llTargetRemove() { } +// public void llRotTarget() { } +// public void llRotTargetRemove() { } +// public void llMoveToTarget() { } +// public void llStopMoveToTarget() { } +// public void llApplyImpulse() { } +// public void llApplyRotationalImpulse() { } +// public void llSetTorque() { } +// public void llGetTorque() { } +// public void llSetForceAndTorque() { } +// public void llGetVel() { } +// public void llGetAccel() { } +// public void llGetOmega() { } +// public void llGetTimeOfDay() { } +// public void llGetWallclock() { } +// public void llGetTime() { } +// public void llResetTime() { } +// public void llGetAndResetTime() { } +// public void llSound() { } +// public void llPlaySound() { } +// public void llLoopSound() { } +// public void llLoopSoundMaster() { } +// public void llLoopSoundSlave() { } +// public void llPlaySoundSlave() { } +// public void llTriggerSound() { } +// public void llStopSound() { } +// public void llPreloadSound() { } +// public void llGetSubString() { } +// public void llDeleteSubString() { } +// public void llInsertString() { } +// public void llToUpper() { } +// public void llToLower() { } +// public void llGiveMoney() { } +// public void llMakeExplosion() { } +// public void llMakeFountain() { } +// public void llMakeSmoke() { } +// public void llMakeFire() { } +// public void llRezObject() { } +// public void llLookAt() { } +// public void llStopLookAt() { } +// public void llSetTimerEvent() { } +// public void llSleep() { } +// public void llGetMass() { } +// public void llCollisionFilter() { } +// public void llTakeControls() { } +// public void llReleaseControls() { } +// public void llAttachToAvatar() { } +// public void llDetachFromAvatar() { } +// public void llTakeCamera() { } +// public void llReleaseCamera() { } +// public void llGetOwner() { } +// public void llInstantMessage() { } +// public void llEmail() { } +// public void llGetNextEmail() { } +// public void llGetKey() { } +// public void llSetBuoyancy() { } +// public void llSetHoverHeight() { } +// public void llStopHover() { } +// public void llMinEventDelay() { } +// public void llSoundPreload() { } +// public void llRotLookAt() { } +// public void llStringLength() { } +// public void llStartAnimation() { } +// public void llStopAnimation() { } +// public void llPointAt() { } +// public void llStopPointAt() { } +// public void llTargetOmega() { } +// public void llGetStartParameter() { } +// public void llGodLikeRezObject() { } +// public void llRequestPermissions() { } +// public void llGetPermissionsKey() { } +// public void llGetPermissions() { } +// public void llGetLinkNumber() { } +// public void llSetLinkColor() { } +// public void llCreateLink() { } +// public void llBreakLink() { } +// public void llBreakAllLinks() { } +// public void llGetLinkKey() { } +// public void llGetLinkName() { } +// public void llGetInventoryNumber() { } +// public void llGetInventoryName() { } +// public void llSetScriptState() { } +// public void llGetEnergy() { } +// public void llGiveInventory() { } +// public void llRemoveInventory() { } +// public void llSetText() { } +// public void llWater() { } +// public void llPassTouches() { } +// public void llRequestAgentData() { } +// public void llRequestInventoryData() { } +// public void llSetDamage() { } +// public void llTeleportAgentHome() { } +// public void llModifyLand() { } +// public void llCollisionSound() { } +// public void llCollisionSprite() { } +// public void llGetAnimation() { } +// public void llResetScript() { } +// public void llMessageLinked() { } +// public void llPushObject() { } +// public void llPassCollisions() { } +// public void llGetScriptName() { } +// public void llGetNumberOfSides() { } +// public void llAxisAngle2Rot() { } +// public void llRot2Axis() { } +// public void llRot2Angle() { } +// public void llAcos() { } +// public void llAsin() { } +// public void llAngleBetween() { } +// public void llGetInventoryKey() { } +// public void llAllowInventoryDrop() { } +// public void llGetSunDirection() { } +// public void llGetTextureOffset() { } +// public void llGetTextureScale() { } +// public void llGetTextureRot() { } +// public void llSubStringIndex() { } +// public void llGetOwnerKey() { } +// public void llGetCenterOfMass() { } +// public void llListSort() { } +// public void llGetListLength() { } +// public void llList2Integer() { } +// public void llList2Float() { } +// public void llList2String() { } +// public void llList2Key() { } +// public void llList2Vector() { } +// public void llList2Rot() { } +// public void llList2List() { } +// public void llDeleteSubList() { } +// public void llGetListEntryType() { } +// public void llList2CSV() { } +// public void llCSV2List() { } +// public void llListRandomize() { } +// public void llList2ListStrided() { } +// public void llGetRegionCorner() { } +// public void llListInsertList() { } +// public void llListFindList() { } +// public void llGetObjectName() { } +// public void llSetObjectName() { } +// public void llGetDate() { } +// public void llEdgeOfWorld() { } +// public void llGetAgentInfo() { } +// public void llAdjustSoundVolume() { } +// public void llSetSoundQueueing() { } +// public void llSetSoundRadius() { } +// public void llKey2Name() { } +// public void llSetTextureAnim() { } +// public void llTriggerSoundLimited() { } +// public void llEjectFromLand() { } +// public void llParseString2List() { } +// public void llOverMyLand() { } +// public void llGetLandOwnerAt() { } +// public void llGetNotecardLine() { } +// public void llGetAgentSize() { } +// public void llSameGroup() { } +// public void llUnSit() { } +// public void llGroundSlope() { } +// public void llGroundNormal() { } +// public void llGroundContour() { } +// public void llGetAttached() { } +// public void llGetFreeMemory() { } +// public void llGetRegionName() { } +// public void llGetRegionTimeDilation() { } +// public void llGetRegionFPS() { } +// public void llParticleSystem() { } +// public void llGroundRepel() { } +// public void llGiveInventoryList() { } +// public void llSetVehicleType() { } +// public void llSetVehicleFloatParam() { } +// public void llSetVehicleVectorParam() { } +// public void llSetVehicleRotationParam() { } +// public void llSetVehicleFlags() { } +// public void llRemoveVehicleFlags() { } +// public void llSitTarget() { } +// public void llAvatarOnSitTarget() { } +// public void llAddToLandPassList() { } +// public void llSetTouchText() { } +// public void llSetSitText() { } +// public void llSetCameraEyeOffset() { } +// public void llSetCameraAtOffset() { } +// public void llDumpList2String() { } +// public void llScriptDanger() { } +// public void llDialog() { } +// public void llVolumeDetect() { } +// public void llResetOtherScript() { } +// public void llGetScriptState() { } +// public void llRemoteLoadScript() { } +// public void llSetRemoteScriptAccessPin() { } +// public void llRemoteLoadScriptPin() { } +// public void llOpenRemoteDataChannel() { } +// public void llSendRemoteData() { } +// public void llRemoteDataReply() { } +// public void llCloseRemoteDataChannel() { } +// public void llMD5String() { } +// public void llSetPrimitiveParams() { } +// public void llStringToBase64() { } +// public void llBase64ToString() { } +// public void llXorBase64Strings() { } +// public void llRemoteDataSetRegion() { } +// public void llLog10() { } +// public void llLog() { } +// public void llGetAnimationList() { } +// public void llSetParcelMusicURL() { } +// public void llGetRootPosition() { } +// public void llGetRootRotation() { } +// public void llGetObjectDesc() { } +// public void llSetObjectDesc() { } +// public void llGetCreator() { } +// public void llGetTimestamp() { } +// public void llSetLinkAlpha() { } +// public void llGetNumberOfPrims() { } +// public void llGetNumberOfNotecardLines() { } +// public void llGetBoundingBox() { } +// public void llGetGeometricCenter() { } +// public void llGetPrimitiveParams() { } +// public void llIntegerToBase64() { } +// public void llBase64ToInteger() { } +// public void llGetGMTclock() { } +// public void llGetSimulatorHostname() { } +// public void llSetLocalRot() { } +// public void llParseStringKeepNulls() { } +// public void llRezAtRoot() { } +// public void llGetObjectPermMask() { } +// public void llSetObjectPermMask() { } +// public void llGetInventoryPermMask() { } +// public void llSetInventoryPermMask() { } +// public void llGetInventoryCreator() { } +// public void llOwnerSay() { } +// public void llRequestSimulatorData() { } +// public void llForceMouselook() { } +// public void llGetObjectMass() { } +// public void llListReplaceList() { } +// public void llLoadURL() { } +// public void llParcelMediaCommandList() { } +// public void llParcelMediaQuery() { } +// public void llModPow() { } +// public void llGetInventoryType() { } +// public void llSetPayPrice() { } +// public void llGetCameraPos() { } +// public void llGetCameraRot() { } +// public void llSetPrimURL() { } +// public void llRefreshPrimURL() { } +// public void llEscapeURL() { } +// public void llUnescapeURL() { } +// public void llMapDestination() { } +// public void llAddToLandBanList() { } +// public void llRemoveFromLandPassList() { } +// public void llRemoveFromLandBanList() { } +// public void llSetCameraParams() { } +// public void llClearCameraParams() { } +// public void llListStatistics() { } +// public void llGetUnixTime() { } +// public void llGetParcelFlags() { } +// public void llGetRegionFlags() { } +// public void llXorBase64StringsCorrect() { } +// public void llHTTPRequest() { } +// public void llResetLandBanList() { } +// public void llResetLandPassList() { } +// public void llGetParcelPrimCount() { } +// public void llGetParcelPrimOwners() { } +// public void llGetObjectPrimCount() { } +// public void llGetParcelMaxPrims() { } +// public void llGetParcelDetails() { } + +// } +//} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSL_BaseClass_OPCODES.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSL_BaseClass_OPCODES.cs new file mode 100644 index 0000000000..e55f28df8c --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSL_BaseClass_OPCODES.cs @@ -0,0 +1,350 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSO +{ + public partial class LSL_BaseClass + { + /* + * OPCODES + * + * These are internal "assembly" commands, + * basic operators like "ADD", "PUSH" and "POP" + * + * It also contains managed stack and keeps track of internal variables, etc. + * + */ + + + public void StoreToLocal(UInt32 index) + { + // TODO: How to determine local? + Common.SendToDebug("::StoreToLocal " + index); + if (LocalVariables.ContainsKey(index)) + LocalVariables.Remove(index); + LocalVariables.Add(index, LSLStack.Peek()); + } + public void StoreToGlobal(UInt32 index) + { + Common.SendToDebug("::StoreToGlobal " + index); + if (GlobalVariables.ContainsKey(index)) + GlobalVariables.Remove(index); + GlobalVariables.Add(index, LSLStack.Peek()); + } + public void StoreToStatic(UInt32 index) + { + Common.SendToDebug("::StoreToStatic " + index); + //if (StaticVariables.ContainsKey(index)) + // StaticVariables.Remove(index); + StaticVariables.Add(index, LSLStack.Peek()); + } + public void GetFromLocal(UInt32 index) + { + // TODO: How to determine local? + Common.SendToDebug("::GetFromLocal " + index); + object ret; + LocalVariables.TryGetValue(index, out ret); + LSLStack.Push(ret); + //return ret; + } + public void GetFromGlobal(UInt32 index) + { + Common.SendToDebug("::GetFromGlobal " + index); + object ret; + GlobalVariables.TryGetValue(index, out ret); + LSLStack.Push(ret); + //return ret; + } + public void GetFromStatic(UInt32 index) + { + Common.SendToDebug("::GetFromStatic " + index); + object ret; + StaticVariables.TryGetValue(index, out ret); + Common.SendToDebug("::GetFromStatic - ObjectType: " + ret.GetType().ToString()); + LSLStack.Push(ret); + //return ret; + } + + public object POPToStack() + { + Common.SendToDebug("::POPToStack"); + //return LSLStack.Pop(); + object p = LSLStack.Pop(); + if (p.GetType() == typeof(UInt32)) + return (UInt32)p; + if (p.GetType() == typeof(string)) + return (string)p; + if (p.GetType() == typeof(Int32)) + return (Int32)p; + if (p.GetType() == typeof(UInt16)) + return (UInt16)p; + if (p.GetType() == typeof(float)) + return (float)p; + if (p.GetType() == typeof(LSO_Enums.Vector)) + return (LSO_Enums.Vector)p; + if (p.GetType() == typeof(LSO_Enums.Rotation)) + return (LSO_Enums.Rotation)p; + if (p.GetType() == typeof(LSO_Enums.Key)) + return (LSO_Enums.Key)p; + + return p; + } + + //public object POPToStack(UInt32 count) + //{ + // // POP NUMBER FROM TOP OF STACK + // //LSLStack.SetLength(LSLStack.Length - 4); + // Common.SendToDebug("::POPToStack " + count); + // if (count < 2) + // return LSLStack.Pop(); + + // Stack s = new Stack(); + // for (int i = 0; i < count; i++) + // { + // s.Push(LSLStack.Pop); + + // } + + //} + + public void POP() + { + // POP NUMBER FROM TOP OF STACK + //LSLStack.SetLength(LSLStack.Length - 4); + Common.SendToDebug("::POP"); + if (LSLStack.Count < 1) + { + //TODO: Temporary fix + Common.SendToDebug("ERROR: TRYING TO POP EMPTY STACK!"); + } + else + { + LSLStack.Pop(); + } + } + public void PUSH(object Param) + { + if (Param == null) + { + Common.SendToDebug("::PUSH: "); + } + else + { + + //Common.SendToDebug("::PUSH: " + Param.GetType()); + } + + LSLStack.Push(Param); + } + public void ADD(UInt32 Param) + { + Common.SendToDebug("::ADD: " + Param); + object o2 = LSLStack.Pop(); + object o1 = LSLStack.Pop(); + Common.SendToDebug("::ADD: Debug: o1: " + o1.GetType() + " (" + o1.ToString() + "), o2: " + o2.GetType() + " (" + o2.ToString() + ")"); + if (o2.GetType() == typeof(string)) + { + LSLStack.Push((string)o1 + (string)o2); + return; + } + if (o2.GetType() == typeof(UInt32)) + { + LSLStack.Push((UInt32)o1 + (UInt32)o2); + return; + } + + } + public void SUB(UInt32 Param) + { + Common.SendToDebug("::SUB: " + Param); + UInt32 i2 = (UInt32)LSLStack.Pop(); + UInt32 i1 = (UInt32)LSLStack.Pop(); + LSLStack.Push((UInt32)(i1 - i2)); + } + public void MUL(UInt32 Param) + { + Common.SendToDebug("::SUB: " + Param); + UInt32 i2 = (UInt32)LSLStack.Pop(); + UInt32 i1 = (UInt32)LSLStack.Pop(); + LSLStack.Push((UInt32)(i1 * i2)); + } + public void DIV(UInt32 Param) + { + Common.SendToDebug("::DIV: " + Param); + UInt32 i2 = (UInt32)LSLStack.Pop(); + UInt32 i1 = (UInt32)LSLStack.Pop(); + LSLStack.Push((UInt32)(i1 / i2)); + } + + + public void MOD(UInt32 Param) + { + Common.SendToDebug("::MOD: " + Param); + UInt32 i2 = (UInt32)LSLStack.Pop(); + UInt32 i1 = (UInt32)LSLStack.Pop(); + LSLStack.Push((UInt32)(i1 % i2)); + } + public void EQ(UInt32 Param) + { + Common.SendToDebug("::EQ: " + Param); + UInt32 i2 = (UInt32)LSLStack.Pop(); + UInt32 i1 = (UInt32)LSLStack.Pop(); + if (i1 == i2) + { + LSLStack.Push((UInt32)1); + } + else + { + LSLStack.Push((UInt32)0); + } + } + public void NEQ(UInt32 Param) + { + Common.SendToDebug("::NEQ: " + Param); + UInt32 i2 = (UInt32)LSLStack.Pop(); + UInt32 i1 = (UInt32)LSLStack.Pop(); + if (i1 != i2) + { + LSLStack.Push((UInt32)1); + } + else + { + LSLStack.Push((UInt32)0); + } + } + public void LEQ(UInt32 Param) + { + Common.SendToDebug("::LEQ: " + Param); + UInt32 i2 = (UInt32)LSLStack.Pop(); + UInt32 i1 = (UInt32)LSLStack.Pop(); + if (i1 <= i2) + { + LSLStack.Push((UInt32)1); + } + else + { + LSLStack.Push((UInt32)0); + } + } + public void GEQ(UInt32 Param) + { + Common.SendToDebug("::GEQ: " + Param); + UInt32 i2 = (UInt32)LSLStack.Pop(); + UInt32 i1 = (UInt32)LSLStack.Pop(); + if (i1 >= i2) + { + LSLStack.Push((UInt32)1); + } + else + { + LSLStack.Push((UInt32)0); + } + } + public void LESS(UInt32 Param) + { + Common.SendToDebug("::LESS: " + Param); + UInt32 i2 = (UInt32)LSLStack.Pop(); + UInt32 i1 = (UInt32)LSLStack.Pop(); + if (i1 < i2) + { + LSLStack.Push((UInt32)1); + } + else + { + LSLStack.Push((UInt32)0); + } + } + public void GREATER(UInt32 Param) + { + Common.SendToDebug("::GREATER: " + Param); + UInt32 i2 = (UInt32)LSLStack.Pop(); + UInt32 i1 = (UInt32)LSLStack.Pop(); + if (i1 > i2) + { + LSLStack.Push((UInt32)1); + } + else + { + LSLStack.Push((UInt32)0); + } + } + + + + public void BITAND() + { + Common.SendToDebug("::BITAND"); + UInt32 i2 = (UInt32)LSLStack.Pop(); + UInt32 i1 = (UInt32)LSLStack.Pop(); + LSLStack.Push((UInt32)(i1 & i2)); + } + public void BITOR() + { + Common.SendToDebug("::BITOR"); + UInt32 i2 = (UInt32)LSLStack.Pop(); + UInt32 i1 = (UInt32)LSLStack.Pop(); + LSLStack.Push((UInt32)(i1 | i2)); + } + public void BITXOR() + { + Common.SendToDebug("::BITXOR"); + UInt32 i2 = (UInt32)LSLStack.Pop(); + UInt32 i1 = (UInt32)LSLStack.Pop(); + LSLStack.Push((UInt32)(i1 ^ i2)); + } + public void BOOLAND() + { + Common.SendToDebug("::BOOLAND"); + bool b2 = bool.Parse((string)LSLStack.Pop()); + bool b1 = bool.Parse((string)LSLStack.Pop()); + if (b1 && b2) + { + LSLStack.Push((UInt32)1); + } + else + { + LSLStack.Push((UInt32)0); + } + } + public void BOOLOR() + { + Common.SendToDebug("::BOOLOR"); + bool b2 = bool.Parse((string)LSLStack.Pop()); + bool b1 = bool.Parse((string)LSLStack.Pop()); + + if (b1 || b2) + { + LSLStack.Push((UInt32)1); + } + else + { + LSLStack.Push((UInt32)0); + } + + } + public void NEG(UInt32 Param) + { + Common.SendToDebug("::NEG: " + Param); + //UInt32 i2 = (UInt32)LSLStack.Pop(); + UInt32 i1 = (UInt32)LSLStack.Pop(); + LSLStack.Push((UInt32)(i1 * -1)); + } + public void BITNOT() + { + //Common.SendToDebug("::BITNOT"); + //UInt32 i2 = (UInt32)LSLStack.Pop(); + //UInt32 i1 = (UInt32)LSLStack.Pop(); + //LSLStack.Push((UInt32)(i1 / i2)); + } + public void BOOLNOT() + { + //Common.SendToDebug("::BOOLNOT"); + ////UInt32 i2 = (UInt32)LSLStack.Pop(); + //UInt32 i1 = (UInt32)LSLStack.Pop(); + //LSLStack.Push((UInt32)(i1)); + } + + + } +} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSL_CLRInterface.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSL_CLRInterface.cs new file mode 100644 index 0000000000..7d5356062a --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSL_CLRInterface.cs @@ -0,0 +1,79 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +/* Original code: Tedd Hansen */ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSO +{ + public class LSL_CLRInterface + { + public interface LSLScript + { + //public virtual void Run(object arg) + //{ + //} + //void Run(object arg); + + //void event_state_entry(object arg); + //void event_state_exit(); + //void event_touch_start(object arg); + //void event_touch(); + //void event_touch_end(); + //void event_collision_start(); + //void event_collision(); + //void event_collision_end(); + //void event_land_collision_start(); + //void event_land_collision(); + //void event_land_collision_end(); + //void event_timer(); + //void event_listen(); + //void event_on_rez(); + //void event_sensor(); + //void event_no_sensor(); + //void event_control(); + //void event_money(); + //void event_email(); + //void event_at_target(); + //void event_not_at_target(); + //void event_at_rot_target(); + //void event_not_at_rot_target(); + //void event_run_time_permissions(); + //void event_changed(); + //void event_attach(); + //void event_dataserver(); + //void event_link_message(); + //void event_moving_start(); + //void event_moving_end(); + //void event_object_rez(); + //void event_remote_data(); + //void event_http_response(); + } + } +} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSL_OPCODE_IL_processor.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSL_OPCODE_IL_processor.cs new file mode 100644 index 0000000000..18a2b55aec --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSL_OPCODE_IL_processor.cs @@ -0,0 +1,436 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +/* Original code: Tedd Hansen */ +using System; +using System.Collections.Generic; +using System.Text; +using System.Reflection; +using System.Reflection.Emit; +using OpenSim.Region.ScriptEngine.Common; + +namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSO +{ + partial class LSO_Parser + { + //internal Stack ILStack = new Stack(); + //LSO_Enums MyLSO_Enums = new LSO_Enums(); + + internal bool LSL_PROCESS_OPCODE(ILGenerator il) + { + + byte bp1; + UInt32 u32p1; + float fp1; + UInt16 opcode = br_read(1)[0]; + Common.SendToDebug("OPCODE: " + ((LSO_Enums.Operation_Table)opcode).ToString()); + string idesc = ((LSO_Enums.Operation_Table)opcode).ToString(); + switch ((LSO_Enums.Operation_Table)opcode) + { + + /*************** + * IMPLEMENTED * + ***************/ + case LSO_Enums.Operation_Table.NOOP: + break; + case LSO_Enums.Operation_Table.PUSHSP: + // Push Stack Top (Memory Address) to stack + Common.SendToDebug("Instruction " + idesc); + Common.SendToDebug("Instruction " + idesc + ": Description: Pushing Stack Top (Memory Address from header) to stack"); + IL_Push(il, (UInt32)myHeader.SP); + break; + // BYTE + case LSO_Enums.Operation_Table.PUSHARGB: + Common.SendToDebug("Param1: " + br_read(1)[0]); + break; + // INTEGER + case LSO_Enums.Operation_Table.PUSHARGI: + u32p1 = BitConverter.ToUInt32(br_read(4), 0); + Common.SendToDebug("Instruction " + idesc + ", Param1: " + u32p1); + IL_Push(il, u32p1); + break; + // FLOAT + case LSO_Enums.Operation_Table.PUSHARGF: + fp1 = BitConverter.ToUInt32(br_read(4), 0); + Common.SendToDebug("Instruction " + idesc + ", Param1: " + fp1); + IL_Push(il, fp1); + break; + // STRING + case LSO_Enums.Operation_Table.PUSHARGS: + string s = Read_String(); + Common.SendToDebug("Instruction " + idesc + ", Param1: " + s); + IL_Debug(il, "OPCODE: " + idesc + ":" + s); + IL_Push(il, s); + break; + // VECTOR z,y,x + case LSO_Enums.Operation_Table.PUSHARGV: + LSO_Enums.Vector v = new LSO_Enums.Vector(); + v.Z = BitConverter.ToUInt32(br_read(4), 0); + v.Y = BitConverter.ToUInt32(br_read(4), 0); + v.X = BitConverter.ToUInt32(br_read(4), 0); + Common.SendToDebug("Param1 Z: " + v.Z); + Common.SendToDebug("Param1 Y: " + v.Y); + Common.SendToDebug("Param1 X: " + v.X); + IL_Push(il, v); + break; + // ROTATION s,z,y,x + case LSO_Enums.Operation_Table.PUSHARGQ: + LSO_Enums.Rotation r = new LSO_Enums.Rotation(); + r.S = BitConverter.ToUInt32(br_read(4), 0); + r.Z = BitConverter.ToUInt32(br_read(4), 0); + r.Y = BitConverter.ToUInt32(br_read(4), 0); + r.X = BitConverter.ToUInt32(br_read(4), 0); + Common.SendToDebug("Param1 S: " + r.S); + Common.SendToDebug("Param1 Z: " + r.Z); + Common.SendToDebug("Param1 Y: " + r.Y); + Common.SendToDebug("Param1 X: " + r.X); + IL_Push(il, r); + break; + + case LSO_Enums.Operation_Table.PUSHE: + IL_Push(il, (UInt32)0); + break; + + case LSO_Enums.Operation_Table.PUSHARGE: + u32p1 = BitConverter.ToUInt32(br_read(4), 0); + Common.SendToDebug("Param1: " + u32p1); + //IL_Push(il, new string(" ".ToCharArray()[0], Convert.ToInt32(u32p1))); + IL_Push(il, u32p1); + break; + // BYTE + case LSO_Enums.Operation_Table.ADD: + case LSO_Enums.Operation_Table.SUB: + case LSO_Enums.Operation_Table.MUL: + case LSO_Enums.Operation_Table.DIV: + case LSO_Enums.Operation_Table.EQ: + case LSO_Enums.Operation_Table.NEQ: + case LSO_Enums.Operation_Table.LEQ: + case LSO_Enums.Operation_Table.GEQ: + case LSO_Enums.Operation_Table.LESS: + case LSO_Enums.Operation_Table.GREATER: + case LSO_Enums.Operation_Table.NEG: + case LSO_Enums.Operation_Table.MOD: + bp1 = br_read(1)[0]; + Common.SendToDebug("Param1: " + bp1); + IL_CallBaseFunction(il, idesc, (UInt32)bp1); + break; + + // NO ARGUMENTS + case LSO_Enums.Operation_Table.BITAND: + case LSO_Enums.Operation_Table.BITOR: + case LSO_Enums.Operation_Table.BITXOR: + case LSO_Enums.Operation_Table.BOOLAND: + case LSO_Enums.Operation_Table.BOOLOR: + case LSO_Enums.Operation_Table.BITNOT: + case LSO_Enums.Operation_Table.BOOLNOT: + IL_CallBaseFunction(il, idesc); + break; + // SHORT + case LSO_Enums.Operation_Table.CALLLIB_TWO_BYTE: + // TODO: What is size of short? + UInt16 U16p1 = BitConverter.ToUInt16(br_read(2), 0); + Common.SendToDebug("Instruction " + idesc + ": Builtin Command: " + ((LSO_Enums.BuiltIn_Functions)U16p1).ToString()); + //Common.SendToDebug("Param1: " + U16p1); + string fname = ((LSO_Enums.BuiltIn_Functions)U16p1).ToString(); + + bool cmdFound = false; + foreach (MethodInfo mi in typeof(LSL_BuiltIn_Commands_Interface).GetMethods()) + { + // Found command + if (mi.Name == fname) + { + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Call, typeof(LSL_BaseClass).GetMethod("GetLSL_BuiltIn", new Type[] { })); + // Pop required number of items from my stack to .Net stack + IL_PopToStack(il, mi.GetParameters().Length); + il.Emit(OpCodes.Callvirt, mi); + cmdFound = true; + break; + } + } + if (cmdFound == false) + { + Common.SendToDebug("ERROR: UNABLE TO LOCATE OPCODE " + idesc + " IN BASECLASS"); + } + + break; + + // RETURN + case LSO_Enums.Operation_Table.RETURN: + + Common.SendToDebug("OPCODE: RETURN"); + return true; + + case LSO_Enums.Operation_Table.POP: + case LSO_Enums.Operation_Table.POPS: + case LSO_Enums.Operation_Table.POPL: + case LSO_Enums.Operation_Table.POPV: + case LSO_Enums.Operation_Table.POPQ: + // Pops a specific datatype from the stack + // We just ignore the datatype for now + IL_Pop(il); + break; + + // LONG + case LSO_Enums.Operation_Table.STORE: + case LSO_Enums.Operation_Table.STORES: + case LSO_Enums.Operation_Table.STOREL: + case LSO_Enums.Operation_Table.STOREV: + case LSO_Enums.Operation_Table.STOREQ: + u32p1 = BitConverter.ToUInt32(br_read(4), 0); + Common.SendToDebug("Param1: " + u32p1.ToString()); + IL_CallBaseFunction(il, "StoreToLocal", u32p1); + break; + + case LSO_Enums.Operation_Table.STOREG: + case LSO_Enums.Operation_Table.STOREGS: + case LSO_Enums.Operation_Table.STOREGL: + case LSO_Enums.Operation_Table.STOREGV: + case LSO_Enums.Operation_Table.STOREGQ: + u32p1 = BitConverter.ToUInt32(br_read(4), 0); + Common.SendToDebug("Param1: " + u32p1.ToString()); + IL_CallBaseFunction(il, "StoreToGlobal", u32p1); + break; + + case LSO_Enums.Operation_Table.LOADP: + case LSO_Enums.Operation_Table.LOADSP: + case LSO_Enums.Operation_Table.LOADLP: + case LSO_Enums.Operation_Table.LOADVP: + case LSO_Enums.Operation_Table.LOADQP: + u32p1 = BitConverter.ToUInt32(br_read(4), 0); + Common.SendToDebug("Param1: " + u32p1.ToString()); + IL_CallBaseFunction(il, "StoreToLocal", u32p1); + IL_Pop(il); + break; + + case LSO_Enums.Operation_Table.LOADGP: + case LSO_Enums.Operation_Table.LOADGSP: + case LSO_Enums.Operation_Table.LOADGLP: + case LSO_Enums.Operation_Table.LOADGVP: + case LSO_Enums.Operation_Table.LOADGQP: + u32p1 = BitConverter.ToUInt32(br_read(4), 0); + Common.SendToDebug("Param1: " + u32p1.ToString()); + IL_CallBaseFunction(il, "StoreToStatic", u32p1 - 6 + myHeader.GVR); + IL_Pop(il); + break; + + // PUSH FROM LOCAL FRAME + case LSO_Enums.Operation_Table.PUSH: + case LSO_Enums.Operation_Table.PUSHS: + case LSO_Enums.Operation_Table.PUSHL: + case LSO_Enums.Operation_Table.PUSHV: + case LSO_Enums.Operation_Table.PUSHQ: + u32p1 = BitConverter.ToUInt32(br_read(4), 0); + Common.SendToDebug("Param1: " + u32p1.ToString()); + IL_CallBaseFunction(il, "GetFromLocal", u32p1); + + break; + + // PUSH FROM STATIC FRAME + case LSO_Enums.Operation_Table.PUSHG: + case LSO_Enums.Operation_Table.PUSHGS: + case LSO_Enums.Operation_Table.PUSHGL: + case LSO_Enums.Operation_Table.PUSHGV: + case LSO_Enums.Operation_Table.PUSHGQ: + u32p1 = BitConverter.ToUInt32(br_read(4), 0); + Common.SendToDebug("Param1: " + u32p1.ToString()); + IL_CallBaseFunction(il, "GetFromStatic", u32p1 - 6 + myHeader.GVR); + break; + + + /*********************** + * NOT IMPLEMENTED YET * + ***********************/ + + + + case LSO_Enums.Operation_Table.POPIP: + case LSO_Enums.Operation_Table.POPSP: + case LSO_Enums.Operation_Table.POPSLR: + case LSO_Enums.Operation_Table.POPARG: + case LSO_Enums.Operation_Table.POPBP: + //Common.SendToDebug("Instruction " + idesc + ": Ignored"); + Common.SendToDebug("Instruction " + idesc + ": Description: Drop x bytes from the stack (TODO: Only popping 1)"); + //Common.SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4), 0)); + IL_Pop(il); + break; + + + + // None + case LSO_Enums.Operation_Table.PUSHIP: + // PUSH INSTRUCTION POINTER + break; + case LSO_Enums.Operation_Table.PUSHBP: + + case LSO_Enums.Operation_Table.PUSHEV: + break; + case LSO_Enums.Operation_Table.PUSHEQ: + break; + + + // LONG + case LSO_Enums.Operation_Table.JUMP: + Common.SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4), 0)); + break; + // BYTE, LONG + case LSO_Enums.Operation_Table.JUMPIF: + case LSO_Enums.Operation_Table.JUMPNIF: + Common.SendToDebug("Param1: " + br_read(1)[0]); + Common.SendToDebug("Param2: " + BitConverter.ToUInt32(br_read(4), 0)); + break; + // LONG + case LSO_Enums.Operation_Table.STATE: + bp1 = br_read(1)[0]; + //il.Emit(OpCodes.Ld); // Load local variable 0 onto stack + //il.Emit(OpCodes.Ldc_I4, 0); // Push index position + //il.Emit(OpCodes.Ldstr, EventList[p1]); // Push value + //il.Emit(OpCodes.Stelem_Ref); // Perform array[index] = value + break; + case LSO_Enums.Operation_Table.CALL: + Common.SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4), 0)); + Common.SendToDebug("ERROR: Function CALL not implemented yet."); + break; + // BYTE + case LSO_Enums.Operation_Table.CAST: + bp1 = br_read(1)[0]; + Common.SendToDebug("Instruction " + idesc + ": Cast to type: " + ((LSO_Enums.OpCode_Cast_TypeDefs)bp1)); + Common.SendToDebug("Param1: " + bp1); + switch ((LSO_Enums.OpCode_Cast_TypeDefs)bp1) + { + case LSO_Enums.OpCode_Cast_TypeDefs.String: + Common.SendToDebug("Instruction " + idesc + ": il.Emit(OpCodes.Box, ILStack.Pop());"); + break; + default: + Common.SendToDebug("Instruction " + idesc + ": Unknown cast type!"); + break; + } + break; + // LONG + case LSO_Enums.Operation_Table.STACKTOS: + case LSO_Enums.Operation_Table.STACKTOL: + Common.SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4), 0)); + break; + // BYTE + case LSO_Enums.Operation_Table.PRINT: + case LSO_Enums.Operation_Table.CALLLIB: + Common.SendToDebug("Param1: " + br_read(1)[0]); + break; + } + return false; + } + + private void IL_PopToStack(ILGenerator il) + { + IL_PopToStack(il, 1); + } + private void IL_PopToStack(ILGenerator il, int count) + { + Common.SendToDebug("IL_PopToStack();"); + for (int i = 0; i < count; i++) + { + IL_CallBaseFunction(il, "POPToStack"); + //il.Emit(OpCodes.Ldarg_0); + //il.Emit(OpCodes.Call, + // typeof(LSL_BaseClass).GetMethod("POPToStack", + // new Type[] { })); + } + } + private void IL_Pop(ILGenerator il) + { + Common.SendToDebug("IL_Pop();"); + IL_CallBaseFunction(il, "POP"); + } + private void IL_Debug(ILGenerator il, string text) + { + il.Emit(OpCodes.Ldstr, text); + il.Emit(OpCodes.Call, typeof(Common).GetMethod("SendToDebug", + new Type[] { typeof(string) } + )); + } + private void IL_CallBaseFunction(ILGenerator il, string methodname) + { + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Call, typeof(LSL_BaseClass).GetMethod(methodname, new Type[] { })); + } + private void IL_CallBaseFunction(ILGenerator il, string methodname, object data) + { + il.Emit(OpCodes.Ldarg_0); + if (data.GetType() == typeof(string)) + il.Emit(OpCodes.Ldstr, (string)data); + if (data.GetType() == typeof(UInt32)) + il.Emit(OpCodes.Ldc_I4, (UInt32)data); + il.Emit(OpCodes.Call, typeof(LSL_BaseClass).GetMethod(methodname, new Type[] { data.GetType() })); + } + + private void IL_Push(ILGenerator il, object data) + { + il.Emit(OpCodes.Ldarg_0); + Common.SendToDebug("PUSH datatype: " + data.GetType()); + + IL_PushDataTypeToILStack(il, data); + + il.Emit(OpCodes.Call, typeof(LSL_BaseClass).GetMethod("PUSH", new Type[] { data.GetType() })); + + } + + private void IL_PushDataTypeToILStack(ILGenerator il, object data) + { + if (data.GetType() == typeof(UInt16)) + { + il.Emit(OpCodes.Ldc_I4, (UInt16)data); + il.Emit(OpCodes.Box, data.GetType()); + } + if (data.GetType() == typeof(UInt32)) + { + il.Emit(OpCodes.Ldc_I4, (UInt32)data); + il.Emit(OpCodes.Box, data.GetType()); + } + if (data.GetType() == typeof(Int32)) + { + il.Emit(OpCodes.Ldc_I4, (Int32)data); + il.Emit(OpCodes.Box, data.GetType()); + } + if (data.GetType() == typeof(float)) + { + il.Emit(OpCodes.Ldc_I4, (float)data); + il.Emit(OpCodes.Box, data.GetType()); + } + if (data.GetType() == typeof(string)) + il.Emit(OpCodes.Ldstr, (string)data); + //if (data.GetType() == typeof(LSO_Enums.Rotation)) + // il.Emit(OpCodes.Ldobj, (LSO_Enums.Rotation)data); + //if (data.GetType() == typeof(LSO_Enums.Vector)) + // il.Emit(OpCodes.Ldobj, (LSO_Enums.Vector)data); + //if (data.GetType() == typeof(LSO_Enums.Key)) + // il.Emit(OpCodes.Ldobj, (LSO_Enums.Key)data); + + } + + + } +} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSO_Enums.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSO_Enums.cs new file mode 100644 index 0000000000..dde6609aa5 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSO_Enums.cs @@ -0,0 +1,557 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +/* Original code: Tedd Hansen */ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSO +{ + public static class LSO_Enums + { + //public System.Collections.Generic.Dictionary OpCode_Add_Types; + + //LSO_Enums() { + // OpCode_Add_Types.Add(51, typeof(String)); + // OpCode_Add_Types.Add(17, typeof(UInt32)); + //} + + [Serializable] + public enum OpCode_Add_TypeDefs + { + String = 51, + UInt32 = 17 + } + [Serializable] + public enum OpCode_Cast_TypeDefs + { + String = 19 + } + + [Serializable] + public struct Key + { + public string KeyString; + } + + [Serializable] + public struct Vector + { + public UInt32 Z; + public UInt32 Y; + public UInt32 X; + } + [Serializable] + public struct Rotation + { + public UInt32 S; + public UInt32 Z; + public UInt32 Y; + public UInt32 X; + } + [Serializable] + public enum Variable_Type_Codes + { + Void = 0, + Integer = 1, + Float = 2, + String = 3, + Key = 4, + Vector = 5, + Rotation = 6, + List = 7, + Null = 8 + } + [Serializable] + public enum Event_Mask_Values + { + state_entry = 0, + state_exit = 1, + touch_start = 2, + touch = 3, + touch_end = 4, + collision_start = 5, + collision = 6, + collision_end = 7, + land_collision_start = 8, + land_collision = 9, + land_collision_end = 10, + timer = 11, + listen = 12, + on_rez = 13, + sensor = 14, + no_sensor = 15, + control = 16, + money = 17, + email = 18, + at_target = 19, + not_at_target = 20, + at_rot_target = 21, + not_at_rot_target = 22, + run_time_permissions = 23, + changed = 24, + attach = 25, + dataserver = 26, + link_message = 27, + moving_start = 28, + moving_end = 29, + object_rez = 30, + remote_data = 31, + http_response = 32 + } + [Serializable] + public enum Operation_Table + { + NOOP = 0x0, + POP = 0x1, + POPS = 0x2, + POPL = 0x3, + POPV = 0x4, + POPQ = 0x5, + POPARG = 0x6, + POPIP = 0x7, + POPBP = 0x8, + POPSP = 0x9, + POPSLR = 0xa, + DUP = 0x20, + DUPS = 0x21, + DUPL = 0x22, + DUPV = 0x23, + DUPQ = 0x24, + STORE = 0x30, + STORES = 0x31, + STOREL = 0x32, + STOREV = 0x33, + STOREQ = 0x34, + STOREG = 0x35, + STOREGS = 0x36, + STOREGL = 0x37, + STOREGV = 0x38, + STOREGQ = 0x39, + LOADP = 0x3a, + LOADSP = 0x3b, + LOADLP = 0x3c, + LOADVP = 0x3d, + LOADQP = 0x3e, + LOADGP = 0x3f, + LOADGSP = 0x40, + LOADGLP = 0x41, + LOADGVP = 0x42, + LOADGQP = 0x43, + PUSH = 0x50, + PUSHS = 0x51, + PUSHL = 0x52, + PUSHV = 0x53, + PUSHQ = 0x54, + PUSHG = 0x55, + PUSHGS = 0x56, + PUSHGL = 0x57, + PUSHGV = 0x58, + PUSHGQ = 0x59, + PUSHIP = 0x5a, + PUSHBP = 0x5b, + PUSHSP = 0x5c, + PUSHARGB = 0x5d, + PUSHARGI = 0x5e, + PUSHARGF = 0x5f, + PUSHARGS = 0x60, + PUSHARGV = 0x61, + PUSHARGQ = 0x62, + PUSHE = 0x63, + PUSHEV = 0x64, + PUSHEQ = 0x65, + PUSHARGE = 0x66, + ADD = 0x70, + SUB = 0x71, + MUL = 0x72, + DIV = 0x73, + MOD = 0x74, + EQ = 0x75, + NEQ = 0x76, + LEQ = 0x77, + GEQ = 0x78, + LESS = 0x79, + GREATER = 0x7a, + BITAND = 0x7b, + BITOR = 0x7c, + BITXOR = 0x7d, + BOOLAND = 0x7e, + BOOLOR = 0x7f, + NEG = 0x80, + BITNOT = 0x81, + BOOLNOT = 0x82, + JUMP = 0x90, + JUMPIF = 0x91, + JUMPNIF = 0x92, + STATE = 0x93, + CALL = 0x94, + RETURN = 0x95, + CAST = 0xa0, + STACKTOS = 0xb0, + STACKTOL = 0xb1, + PRINT = 0xc0, + CALLLIB = 0xd0, + CALLLIB_TWO_BYTE = 0xd1, + SHL = 0xe0, + SHR = 0xe1 + } + [Serializable] + public enum BuiltIn_Functions + { + llSin = 0, + llCos = 1, + llTan = 2, + llAtan2 = 3, + llSqrt = 4, + llPow = 5, + llAbs = 6, + llFabs = 7, + llFrand = 8, + llFloor = 9, + llCeil = 10, + llRound = 11, + llVecMag = 12, + llVecNorm = 13, + llVecDist = 14, + llRot2Euler = 15, + llEuler2Rot = 16, + llAxes2Rot = 17, + llRot2Fwd = 18, + llRot2Left = 19, + llRot2Up = 20, + llRotBetween = 21, + llWhisper = 22, + llSay = 23, + llShout = 24, + llListen = 25, + llListenControl = 26, + llListenRemove = 27, + llSensor = 28, + llSensorRepeat = 29, + llSensorRemove = 30, + llDetectedName = 31, + llDetectedKey = 32, + llDetectedOwner = 33, + llDetectedType = 34, + llDetectedPos = 35, + llDetectedVel = 36, + llDetectedGrab = 37, + llDetectedRot = 38, + llDetectedGroup = 39, + llDetectedLinkNumber = 40, + llDie = 41, + llGround = 42, + llCloud = 43, + llWind = 44, + llSetStatus = 45, + llGetStatus = 46, + llSetScale = 47, + llGetScale = 48, + llSetColor = 49, + llGetAlpha = 50, + llSetAlpha = 51, + llGetColor = 52, + llSetTexture = 53, + llScaleTexture = 54, + llOffsetTexture = 55, + llRotateTexture = 56, + llGetTexture = 57, + llSetPos = 58, + llGetPos = 59, + llGetLocalPos = 60, + llSetRot = 61, + llGetRot = 62, + llGetLocalRot = 63, + llSetForce = 64, + llGetForce = 65, + llTarget = 66, + llTargetRemove = 67, + llRotTarget = 68, + llRotTargetRemove = 69, + llMoveToTarget = 70, + llStopMoveToTarget = 71, + llApplyImpulse = 72, + llApplyRotationalImpulse = 73, + llSetTorque = 74, + llGetTorque = 75, + llSetForceAndTorque = 76, + llGetVel = 77, + llGetAccel = 78, + llGetOmega = 79, + llGetTimeOfDay = 80, + llGetWallclock = 81, + llGetTime = 82, + llResetTime = 83, + llGetAndResetTime = 84, + llSound = 85, + llPlaySound = 86, + llLoopSound = 87, + llLoopSoundMaster = 88, + llLoopSoundSlave = 89, + llPlaySoundSlave = 90, + llTriggerSound = 91, + llStopSound = 92, + llPreloadSound = 93, + llGetSubString = 94, + llDeleteSubString = 95, + llInsertString = 96, + llToUpper = 97, + llToLower = 98, + llGiveMoney = 99, + llMakeExplosion = 100, + llMakeFountain = 101, + llMakeSmoke = 102, + llMakeFire = 103, + llRezObject = 104, + llLookAt = 105, + llStopLookAt = 106, + llSetTimerEvent = 107, + llSleep = 108, + llGetMass = 109, + llCollisionFilter = 110, + llTakeControls = 111, + llReleaseControls = 112, + llAttachToAvatar = 113, + llDetachFromAvatar = 114, + llTakeCamera = 115, + llReleaseCamera = 116, + llGetOwner = 117, + llInstantMessage = 118, + llEmail = 119, + llGetNextEmail = 120, + llGetKey = 121, + llSetBuoyancy = 122, + llSetHoverHeight = 123, + llStopHover = 124, + llMinEventDelay = 125, + llSoundPreload = 126, + llRotLookAt = 127, + llStringLength = 128, + llStartAnimation = 129, + llStopAnimation = 130, + llPointAt = 131, + llStopPointAt = 132, + llTargetOmega = 133, + llGetStartParameter = 134, + llGodLikeRezObject = 135, + llRequestPermissions = 136, + llGetPermissionsKey = 137, + llGetPermissions = 138, + llGetLinkNumber = 139, + llSetLinkColor = 140, + llCreateLink = 141, + llBreakLink = 142, + llBreakAllLinks = 143, + llGetLinkKey = 144, + llGetLinkName = 145, + llGetInventoryNumber = 146, + llGetInventoryName = 147, + llSetScriptState = 148, + llGetEnergy = 149, + llGiveInventory = 150, + llRemoveInventory = 151, + llSetText = 152, + llWater = 153, + llPassTouches = 154, + llRequestAgentData = 155, + llRequestInventoryData = 156, + llSetDamage = 157, + llTeleportAgentHome = 158, + llModifyLand = 159, + llCollisionSound = 160, + llCollisionSprite = 161, + llGetAnimation = 162, + llResetScript = 163, + llMessageLinked = 164, + llPushObject = 165, + llPassCollisions = 166, + llGetScriptName = 167, + llGetNumberOfSides = 168, + llAxisAngle2Rot = 169, + llRot2Axis = 170, + llRot2Angle = 171, + llAcos = 172, + llAsin = 173, + llAngleBetween = 174, + llGetInventoryKey = 175, + llAllowInventoryDrop = 176, + llGetSunDirection = 177, + llGetTextureOffset = 178, + llGetTextureScale = 179, + llGetTextureRot = 180, + llSubStringIndex = 181, + llGetOwnerKey = 182, + llGetCenterOfMass = 183, + llListSort = 184, + llGetListLength = 185, + llList2Integer = 186, + llList2Float = 187, + llList2String = 188, + llList2Key = 189, + llList2Vector = 190, + llList2Rot = 191, + llList2List = 192, + llDeleteSubList = 193, + llGetListEntryType = 194, + llList2CSV = 195, + llCSV2List = 196, + llListRandomize = 197, + llList2ListStrided = 198, + llGetRegionCorner = 199, + llListInsertList = 200, + llListFindList = 201, + llGetObjectName = 202, + llSetObjectName = 203, + llGetDate = 204, + llEdgeOfWorld = 205, + llGetAgentInfo = 206, + llAdjustSoundVolume = 207, + llSetSoundQueueing = 208, + llSetSoundRadius = 209, + llKey2Name = 210, + llSetTextureAnim = 211, + llTriggerSoundLimited = 212, + llEjectFromLand = 213, + llParseString2List = 214, + llOverMyLand = 215, + llGetLandOwnerAt = 216, + llGetNotecardLine = 217, + llGetAgentSize = 218, + llSameGroup = 219, + llUnSit = 220, + llGroundSlope = 221, + llGroundNormal = 222, + llGroundContour = 223, + llGetAttached = 224, + llGetFreeMemory = 225, + llGetRegionName = 226, + llGetRegionTimeDilation = 227, + llGetRegionFPS = 228, + llParticleSystem = 229, + llGroundRepel = 230, + llGiveInventoryList = 231, + llSetVehicleType = 232, + llSetVehicleFloatParam = 233, + llSetVehicleVectorParam = 234, + llSetVehicleRotationParam = 235, + llSetVehicleFlags = 236, + llRemoveVehicleFlags = 237, + llSitTarget = 238, + llAvatarOnSitTarget = 239, + llAddToLandPassList = 240, + llSetTouchText = 241, + llSetSitText = 242, + llSetCameraEyeOffset = 243, + llSetCameraAtOffset = 244, + llDumpList2String = 245, + llScriptDanger = 246, + llDialog = 247, + llVolumeDetect = 248, + llResetOtherScript = 249, + llGetScriptState = 250, + llRemoteLoadScript = 251, + llSetRemoteScriptAccessPin = 252, + llRemoteLoadScriptPin = 253, + llOpenRemoteDataChannel = 254, + llSendRemoteData = 255, + llRemoteDataReply = 256, + llCloseRemoteDataChannel = 257, + llMD5String = 258, + llSetPrimitiveParams = 259, + llStringToBase64 = 260, + llBase64ToString = 261, + llXorBase64Strings = 262, + llRemoteDataSetRegion = 263, + llLog10 = 264, + llLog = 265, + llGetAnimationList = 266, + llSetParcelMusicURL = 267, + llGetRootPosition = 268, + llGetRootRotation = 269, + llGetObjectDesc = 270, + llSetObjectDesc = 271, + llGetCreator = 272, + llGetTimestamp = 273, + llSetLinkAlpha = 274, + llGetNumberOfPrims = 275, + llGetNumberOfNotecardLines = 276, + llGetBoundingBox = 277, + llGetGeometricCenter = 278, + llGetPrimitiveParams = 279, + llIntegerToBase64 = 280, + llBase64ToInteger = 281, + llGetGMTclock = 282, + llGetSimulatorHostname = 283, + llSetLocalRot = 284, + llParseStringKeepNulls = 285, + llRezAtRoot = 286, + llGetObjectPermMask = 287, + llSetObjectPermMask = 288, + llGetInventoryPermMask = 289, + llSetInventoryPermMask = 290, + llGetInventoryCreator = 291, + llOwnerSay = 292, + llRequestSimulatorData = 293, + llForceMouselook = 294, + llGetObjectMass = 295, + llListReplaceList = 296, + llLoadURL = 297, + llParcelMediaCommandList = 298, + llParcelMediaQuery = 299, + llModPow = 300, + llGetInventoryType = 301, + llSetPayPrice = 302, + llGetCameraPos = 303, + llGetCameraRot = 304, + llSetPrimURL = 305, + llRefreshPrimURL = 306, + llEscapeURL = 307, + llUnescapeURL = 308, + llMapDestination = 309, + llAddToLandBanList = 310, + llRemoveFromLandPassList = 311, + llRemoveFromLandBanList = 312, + llSetCameraParams = 313, + llClearCameraParams = 314, + llListStatistics = 315, + llGetUnixTime = 316, + llGetParcelFlags = 317, + llGetRegionFlags = 318, + llXorBase64StringsCorrect = 319, + llHTTPRequest = 320, + llResetLandBanList = 321, + llResetLandPassList = 322, + llGetParcelPrimCount = 323, + llGetParcelPrimOwners = 324, + llGetObjectPrimCount = 325, + llGetParcelMaxPrims = 326, + llGetParcelDetails = 327 + } + + } +} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSO_Parser.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSO_Parser.cs new file mode 100644 index 0000000000..324f201000 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSO_Parser.cs @@ -0,0 +1,722 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +/* Original code: Tedd Hansen */ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Reflection; +using System.Reflection.Emit; + +namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSO +{ + partial class LSO_Parser + { + private string FileName; + private FileStream fs; + private BinaryReader br; + internal LSO_Struct.Header myHeader; + internal Dictionary StaticBlocks = new Dictionary(); + //private System.Collections.Hashtable StaticBlocks = new System.Collections.Hashtable(); + + private TypeBuilder typeBuilder; + private System.Collections.Generic.List EventList = new System.Collections.Generic.List(); + + public LSO_Parser(string _FileName, TypeBuilder _typeBuilder) + { + FileName = _FileName; + typeBuilder = _typeBuilder; + } + + internal void OpenFile() + { + // Open + Common.SendToDebug("Opening filename: " + FileName); + fs = File.Open(FileName, FileMode.Open, FileAccess.Read, FileShare.Read); + br = new BinaryReader(fs, Encoding.BigEndianUnicode); + + } + internal void CloseFile() + { + + // Close + br.Close(); + fs.Close(); + } + + + /// + /// Parse LSO file. + /// + public void Parse() + { + + + + // The LSO Format consist of 6 major blocks: header, statics, functions, states, heap, and stack. + + + // HEADER BLOCK + Common.SendToDebug("Reading HEADER BLOCK at: 0"); + fs.Seek(0, SeekOrigin.Begin); + myHeader = new LSO_Struct.Header(); + myHeader.TM = BitConverter.ToUInt32(br_read(4), 0); + myHeader.IP = BitConverter.ToUInt32(br_read(4), 0); + myHeader.VN = BitConverter.ToUInt32(br_read(4), 0); + myHeader.BP = BitConverter.ToUInt32(br_read(4), 0); + myHeader.SP = BitConverter.ToUInt32(br_read(4), 0); + myHeader.HR = BitConverter.ToUInt32(br_read(4), 0); + myHeader.HP = BitConverter.ToUInt32(br_read(4), 0); + myHeader.CS = BitConverter.ToUInt32(br_read(4), 0); + myHeader.NS = BitConverter.ToUInt32(br_read(4), 0); + myHeader.CE = BitConverter.ToUInt32(br_read(4), 0); + myHeader.IE = BitConverter.ToUInt32(br_read(4), 0); + myHeader.ER = BitConverter.ToUInt32(br_read(4), 0); + myHeader.FR = BitConverter.ToUInt32(br_read(4), 0); + myHeader.SLR = BitConverter.ToUInt32(br_read(4), 0); + myHeader.GVR = BitConverter.ToUInt32(br_read(4), 0); + myHeader.GFR = BitConverter.ToUInt32(br_read(4), 0); + myHeader.PR = BitConverter.ToUInt32(br_read(4), 0); + myHeader.ESR = BitConverter.ToUInt32(br_read(4), 0); + myHeader.SR = BitConverter.ToUInt32(br_read(4), 0); + myHeader.NCE = BitConverter.ToUInt64(br_read(8), 0); + myHeader.NIE = BitConverter.ToUInt64(br_read(8), 0); + myHeader.NER = BitConverter.ToUInt64(br_read(8), 0); + + // Print Header Block to debug + Common.SendToDebug("TM - Top of memory (size): " + myHeader.TM); + Common.SendToDebug("IP - Instruction Pointer (0=not running): " + myHeader.IP); + Common.SendToDebug("VN - Version number: " + myHeader.VN); + Common.SendToDebug("BP - Local Frame Pointer: " + myHeader.BP); + Common.SendToDebug("SP - Stack Pointer: " + myHeader.SP); + Common.SendToDebug("HR - Heap Register: " + myHeader.HR); + Common.SendToDebug("HP - Heap Pointer: " + myHeader.HP); + Common.SendToDebug("CS - Current State: " + myHeader.CS); + Common.SendToDebug("NS - Next State: " + myHeader.NS); + Common.SendToDebug("CE - Current Events: " + myHeader.CE); + Common.SendToDebug("IE - In Event: " + myHeader.IE); + Common.SendToDebug("ER - Event Register: " + myHeader.ER); + Common.SendToDebug("FR - Fault Register: " + myHeader.FR); + Common.SendToDebug("SLR - Sleep Register: " + myHeader.SLR); + Common.SendToDebug("GVR - Global Variable Register: " + myHeader.GVR); + Common.SendToDebug("GFR - Global Function Register: " + myHeader.GFR); + Common.SendToDebug("PR - Parameter Register: " + myHeader.PR); + Common.SendToDebug("ESR - Energy Supply Register: " + myHeader.ESR); + Common.SendToDebug("SR - State Register: " + myHeader.SR); + Common.SendToDebug("NCE - 64-bit Current Events: " + myHeader.NCE); + Common.SendToDebug("NIE - 64-bit In Events: " + myHeader.NIE); + Common.SendToDebug("NER - 64-bit Event Register: " + myHeader.NER); + Common.SendToDebug("Read position when exiting HEADER BLOCK: " + fs.Position); + + // STATIC BLOCK + Common.SendToDebug("Reading STATIC BLOCK at: " + myHeader.GVR); + fs.Seek(myHeader.GVR, SeekOrigin.Begin); + int StaticBlockCount = 0; + // Read function blocks until we hit GFR + while (fs.Position < myHeader.GFR) + { + StaticBlockCount++; + long startReadPos = fs.Position; + Common.SendToDebug("Reading Static Block " + StaticBlockCount + " at: " + startReadPos); + + //fs.Seek(myHeader.GVR, SeekOrigin.Begin); + LSO_Struct.StaticBlock myStaticBlock = new LSO_Struct.StaticBlock(); + myStaticBlock.Static_Chunk_Header_Size = BitConverter.ToUInt32(br_read(4), 0); + myStaticBlock.ObjectType = br_read(1)[0]; + Common.SendToDebug("Static Block ObjectType: " + ((LSO_Enums.Variable_Type_Codes)myStaticBlock.ObjectType).ToString()); + myStaticBlock.Unknown = br_read(1)[0]; + // Size of datatype varies -- what about strings? + if (myStaticBlock.ObjectType != 0) + myStaticBlock.BlockVariable = br_read(getObjectSize(myStaticBlock.ObjectType)); + + StaticBlocks.Add((UInt32)startReadPos, myStaticBlock); + + } + Common.SendToDebug("Number of Static Blocks read: " + StaticBlockCount); + + + // FUNCTION BLOCK + // Always right after STATIC BLOCK + LSO_Struct.FunctionBlock myFunctionBlock = new LSO_Struct.FunctionBlock(); + if (myHeader.GFR == myHeader.SR) + { + // If GFR and SR are at same position then there is no fuction block + Common.SendToDebug("No FUNCTION BLOCK found"); + } + else + { + Common.SendToDebug("Reading FUNCTION BLOCK at: " + myHeader.GFR); + fs.Seek(myHeader.GFR, SeekOrigin.Begin); + myFunctionBlock.FunctionCount = BitConverter.ToUInt32(br_read(4), 0); + Common.SendToDebug("Number of functions in Fuction Block: " + myFunctionBlock.FunctionCount); + if (myFunctionBlock.FunctionCount > 0) + { + myFunctionBlock.CodeChunkPointer = new UInt32[myFunctionBlock.FunctionCount]; + for (int i = 0; i < myFunctionBlock.FunctionCount; i++) + { + Common.SendToDebug("Reading function " + i + " at: " + fs.Position); + // TODO: ADD TO FUNCTION LIST (How do we identify it later?) + // Note! Absolute position + myFunctionBlock.CodeChunkPointer[i] = BitConverter.ToUInt32(br_read(4), 0) + myHeader.GFR; + Common.SendToDebug("Fuction " + i + " code chunk position: " + myFunctionBlock.CodeChunkPointer[i]); + } + } + } + + + // STATE FRAME BLOCK + // Always right after FUNCTION BLOCK + Common.SendToDebug("Reading STATE BLOCK at: " + myHeader.SR); + fs.Seek(myHeader.SR, SeekOrigin.Begin); + LSO_Struct.StateFrameBlock myStateFrameBlock = new LSO_Struct.StateFrameBlock(); + myStateFrameBlock.StateCount = BitConverter.ToUInt32(br_read(4), 0); + if (myStateFrameBlock.StateCount > 0) + { + // Initialize array + myStateFrameBlock.StatePointer = new LSO_Struct.StatePointerBlock[myStateFrameBlock.StateCount]; + for (int i = 0; i < myStateFrameBlock.StateCount; i++) + { + Common.SendToDebug("Reading STATE POINTER BLOCK " + (i + 1) + " at: " + fs.Position); + // Position is relative to state frame + myStateFrameBlock.StatePointer[i].Location = myHeader.SR + BitConverter.ToUInt32(br_read(4), 0); + myStateFrameBlock.StatePointer[i].EventMask = new System.Collections.BitArray(br_read(8)); + Common.SendToDebug("Pointer: " + myStateFrameBlock.StatePointer[i].Location); + Common.SendToDebug("Total potential EventMask bits: " + myStateFrameBlock.StatePointer[i].EventMask.Count); + + //// Read STATE BLOCK + //long CurPos = fs.Position; + //fs.Seek(CurPos, SeekOrigin.Begin); + + } + } + + + // STATE BLOCK + // For each StateFrameBlock there is one StateBlock with multiple event handlers + + if (myStateFrameBlock.StateCount > 0) + { + // Go through all State Frame Pointers found + for (int i = 0; i < myStateFrameBlock.StateCount; i++) + { + + fs.Seek(myStateFrameBlock.StatePointer[i].Location, SeekOrigin.Begin); + Common.SendToDebug("Reading STATE BLOCK " + (i + 1) + " at: " + fs.Position); + + // READ: STATE BLOCK HEADER + myStateFrameBlock.StatePointer[i].StateBlock = new LSO_Struct.StateBlock(); + myStateFrameBlock.StatePointer[i].StateBlock.StartPos = (UInt32)fs.Position; // Note + myStateFrameBlock.StatePointer[i].StateBlock.HeaderSize = BitConverter.ToUInt32(br_read(4), 0); + myStateFrameBlock.StatePointer[i].StateBlock.Unknown = br_read(1)[0]; + myStateFrameBlock.StatePointer[i].StateBlock.EndPos = (UInt32)fs.Position; // Note + Common.SendToDebug("State block Start Pos: " + myStateFrameBlock.StatePointer[i].StateBlock.StartPos); + Common.SendToDebug("State block Header Size: " + myStateFrameBlock.StatePointer[i].StateBlock.HeaderSize); + Common.SendToDebug("State block Header End Pos: " + myStateFrameBlock.StatePointer[i].StateBlock.EndPos); + + // We need to count number of bits flagged in EventMask? + + + // for each bit in myStateFrameBlock.StatePointer[i].EventMask + + // ADDING TO ALL RIGHT NOW, SHOULD LIMIT TO ONLY THE ONES IN USE + //TODO: Create event hooks + myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers = new LSO_Struct.StateBlockHandler[myStateFrameBlock.StatePointer[i].EventMask.Count - 1]; + for (int ii = 0; ii < myStateFrameBlock.StatePointer[i].EventMask.Count - 1; ii++) + { + + if (myStateFrameBlock.StatePointer[i].EventMask.Get(ii) == true) + { + // We got an event + // READ: STATE BLOCK HANDLER + Common.SendToDebug("Reading STATE BLOCK " + (i + 1) + " HANDLER matching EVENT MASK " + ii + " (" + ((LSO_Enums.Event_Mask_Values)ii).ToString() + ") at: " + fs.Position); + myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer = myStateFrameBlock.StatePointer[i].StateBlock.EndPos + BitConverter.ToUInt32(br_read(4), 0); + myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CallFrameSize = BitConverter.ToUInt32(br_read(4), 0); + Common.SendToDebug("Reading STATE BLOCK " + (i + 1) + " HANDLER EVENT MASK " + ii + " (" + ((LSO_Enums.Event_Mask_Values)ii).ToString() + ") Code Chunk Pointer: " + myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer); + Common.SendToDebug("Reading STATE BLOCK " + (i + 1) + " HANDLER EVENT MASK " + ii + " (" + ((LSO_Enums.Event_Mask_Values)ii).ToString() + ") Call Frame Size: " + myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CallFrameSize); + } + } + } + } + + + + + //// READ FUNCTION CODE CHUNKS + //// Functions + Function start pos (GFR) + //// TODO: Somehow be able to identify and reference this + //LSO_Struct.CodeChunk[] myFunctionCodeChunk; + //if (myFunctionBlock.FunctionCount > 0) + //{ + // myFunctionCodeChunk = new LSO_Struct.CodeChunk[myFunctionBlock.FunctionCount]; + // for (int i = 0; i < myFunctionBlock.FunctionCount; i++) + // { + // Common.SendToDebug("Reading Function Code Chunk " + i); + // myFunctionCodeChunk[i] = GetCodeChunk((UInt32)myFunctionBlock.CodeChunkPointer[i]); + // } + + //} + // READ EVENT CODE CHUNKS + LSO_Struct.CodeChunk[] myEventCodeChunk; + if (myStateFrameBlock.StateCount > 0) + { + myEventCodeChunk = new LSO_Struct.CodeChunk[myStateFrameBlock.StateCount]; + for (int i = 0; i < myStateFrameBlock.StateCount; i++) + { + // TODO: Somehow organize events and functions so they can be found again, + // two level search ain't no good + for (int ii = 0; ii < myStateFrameBlock.StatePointer[i].EventMask.Count - 1; ii++) + { + + + if (myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer > 0) + { + Common.SendToDebug("Reading Event Code Chunk state " + i + ", event " + (LSO_Enums.Event_Mask_Values)ii); + + + // Override a Method / Function + string eventname = i + "_event_" + (LSO_Enums.Event_Mask_Values)ii; + Common.SendToDebug("Event Name: " + eventname); + if (Common.IL_ProcessCodeChunks) + { + EventList.Add(eventname); + + // JUMP TO CODE PROCESSOR + ProcessCodeChunk(myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer, typeBuilder, eventname); + } + } + + } + + } + + } + + + + + if (Common.IL_CreateFunctionList) + IL_INSERT_FUNCTIONLIST(); + + } + + internal LSO_Struct.HeapBlock GetHeap(UInt32 pos) + { + // HEAP BLOCK + // TODO:? Special read for strings/keys (null terminated) and lists (pointers to other HEAP entries) + Common.SendToDebug("Reading HEAP BLOCK at: " + pos); + fs.Seek(pos, SeekOrigin.Begin); + + LSO_Struct.HeapBlock myHeapBlock = new LSO_Struct.HeapBlock(); + myHeapBlock.DataBlockSize = BitConverter.ToInt32(br_read(4), 0); + myHeapBlock.ObjectType = br_read(1)[0]; + myHeapBlock.ReferenceCount = BitConverter.ToUInt16(br_read(2), 0); + //myHeapBlock.Data = br_read(getObjectSize(myHeapBlock.ObjectType)); + // Don't read it reversed + myHeapBlock.Data = new byte[myHeapBlock.DataBlockSize - 1]; + br.Read(myHeapBlock.Data, 0, myHeapBlock.DataBlockSize - 1); + + + Common.SendToDebug("Heap Block Data Block Size: " + myHeapBlock.DataBlockSize); + Common.SendToDebug("Heap Block ObjectType: " + ((LSO_Enums.Variable_Type_Codes)myHeapBlock.ObjectType).ToString()); + Common.SendToDebug("Heap Block Reference Count: " + myHeapBlock.ReferenceCount); + + return myHeapBlock; + } + private byte[] br_read(int len) + { + if (len <= 0) + return null; + + try + { + byte[] bytes = new byte[len]; + for (int i = len - 1; i > -1; i--) + bytes[i] = br.ReadByte(); + return bytes; + } + catch (Exception e) + { + Common.SendToDebug("Exception: " + e.ToString()); + throw (e); + } + } + //private byte[] br_read_smallendian(int len) + //{ + // byte[] bytes = new byte[len]; + // br.Read(bytes,0, len); + // return bytes; + //} + private Type getLLObjectType(byte objectCode) + { + switch ((LSO_Enums.Variable_Type_Codes)objectCode) + { + case LSO_Enums.Variable_Type_Codes.Void: return typeof(void); + case LSO_Enums.Variable_Type_Codes.Integer: return typeof(UInt32); + case LSO_Enums.Variable_Type_Codes.Float: return typeof(float); + case LSO_Enums.Variable_Type_Codes.String: return typeof(string); + case LSO_Enums.Variable_Type_Codes.Key: return typeof(string); + case LSO_Enums.Variable_Type_Codes.Vector: return typeof(LSO_Enums.Vector); + case LSO_Enums.Variable_Type_Codes.Rotation: return typeof(LSO_Enums.Rotation); + case LSO_Enums.Variable_Type_Codes.List: + Common.SendToDebug("TODO: List datatype not implemented yet!"); + return typeof(System.Collections.ArrayList); + case LSO_Enums.Variable_Type_Codes.Null: + Common.SendToDebug("TODO: Datatype null is not implemented, using string instead.!"); + return typeof(string); + default: + Common.SendToDebug("Lookup of LSL datatype " + objectCode + " to .Net datatype failed: Unknown LSL datatype. Defaulting to object."); + return typeof(object); + } + } + private int getObjectSize(byte ObjectType) + { + switch ((LSO_Enums.Variable_Type_Codes)ObjectType) + { + case LSO_Enums.Variable_Type_Codes.Integer: + case LSO_Enums.Variable_Type_Codes.Float: + case LSO_Enums.Variable_Type_Codes.String: + case LSO_Enums.Variable_Type_Codes.Key: + case LSO_Enums.Variable_Type_Codes.List: + return 4; + case LSO_Enums.Variable_Type_Codes.Vector: + return 12; + case LSO_Enums.Variable_Type_Codes.Rotation: + return 16; + default: + return 0; + } + } + private string Read_String() + { + string ret = ""; + byte reader = br_read(1)[0]; + while (reader != 0x000) + { + ret += (char)reader; + reader = br_read(1)[0]; + } + return ret; + } + + /// + /// Reads a code chunk and creates IL + /// + /// Absolute position in file. REMEMBER TO ADD myHeader.GFR! + /// TypeBuilder for assembly + /// Name of event (function) to generate + private void ProcessCodeChunk(UInt32 pos, TypeBuilder typeBuilder, string eventname) + { + + LSO_Struct.CodeChunk myCodeChunk = new LSO_Struct.CodeChunk(); + + Common.SendToDebug("Reading Function Code Chunk at: " + pos); + fs.Seek(pos, SeekOrigin.Begin); + myCodeChunk.CodeChunkHeaderSize = BitConverter.ToUInt32(br_read(4), 0); + Common.SendToDebug("CodeChunk Header Size: " + myCodeChunk.CodeChunkHeaderSize); + // Read until null + myCodeChunk.Comment = Read_String(); + Common.SendToDebug("Function comment: " + myCodeChunk.Comment); + myCodeChunk.ReturnTypePos = br_read(1)[0]; + myCodeChunk.ReturnType = GetStaticBlock((long)myCodeChunk.ReturnTypePos + (long)myHeader.GVR); + Common.SendToDebug("Return type #" + myCodeChunk.ReturnType.ObjectType + ": " + ((LSO_Enums.Variable_Type_Codes)myCodeChunk.ReturnType.ObjectType).ToString()); + + + // TODO: How to determine number of codechunks -- does this method work? + myCodeChunk.CodeChunkArguments = new System.Collections.Generic.List(); + byte reader = br_read(1)[0]; + reader = br_read(1)[0]; + + // NOTE ON CODE CHUNK ARGUMENTS + // This determins type definition + int ccount = 0; + while (reader != 0x000) + { + ccount++; + Common.SendToDebug("Reading Code Chunk Argument " + ccount); + LSO_Struct.CodeChunkArgument CCA = new LSO_Struct.CodeChunkArgument(); + CCA.FunctionReturnTypePos = reader; + reader = br_read(1)[0]; + CCA.NullString = reader; + CCA.FunctionReturnType = GetStaticBlock(CCA.FunctionReturnTypePos + myHeader.GVR); + myCodeChunk.CodeChunkArguments.Add(CCA); + Common.SendToDebug("Code Chunk Argument " + ccount + " type #" + CCA.FunctionReturnType.ObjectType + ": " + (LSO_Enums.Variable_Type_Codes)CCA.FunctionReturnType.ObjectType); + } + // Create string array + Type[] MethodArgs = new Type[myCodeChunk.CodeChunkArguments.Count]; + for (int _ic = 0; _ic < myCodeChunk.CodeChunkArguments.Count; _ic++) + { + MethodArgs[_ic] = getLLObjectType(myCodeChunk.CodeChunkArguments[_ic].FunctionReturnType.ObjectType); + Common.SendToDebug("Method argument " + _ic + ": " + getLLObjectType(myCodeChunk.CodeChunkArguments[_ic].FunctionReturnType.ObjectType).ToString()); + } + // End marker is 0x000 + myCodeChunk.EndMarker = reader; + + + // + // Emit: START OF METHOD (FUNCTION) + // + + Common.SendToDebug("CLR:" + eventname + ":MethodBuilder methodBuilder = typeBuilder.DefineMethod..."); + MethodBuilder methodBuilder = typeBuilder.DefineMethod(eventname, + MethodAttributes.Public, + typeof(void), + new Type[] { typeof(object) }); + //MethodArgs); + //typeof(void), //getLLObjectType(myCodeChunk.ReturnType), + // new Type[] { typeof(object) }, //); + + //Common.SendToDebug("CLR:" + eventname + ":typeBuilder.DefineMethodOverride(methodBuilder..."); + //typeBuilder.DefineMethodOverride(methodBuilder, + // typeof(LSL_CLRInterface.LSLScript).GetMethod(eventname)); + + // Create the IL generator + + Common.SendToDebug("CLR:" + eventname + ":ILGenerator il = methodBuilder.GetILGenerator();"); + ILGenerator il = methodBuilder.GetILGenerator(); + + + if (Common.IL_UseTryCatch) + IL_INSERT_TRY(il, eventname); + + + + // Push Console.WriteLine command to stack ... Console.WriteLine("Hello World!"); + //Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call..."); + //il.Emit(OpCodes.Call, typeof(Console).GetMethod + // ("WriteLine", new Type[] { typeof(string) })); + + //Common.SendToDebug("STARTUP: il.Emit(OpCodes.Ldc_I4_S, 0);"); + + //il.Emit(OpCodes.Ldc_I4_S, 0); + for (int _ic = 0; _ic < myCodeChunk.CodeChunkArguments.Count; _ic++) + { + Common.SendToDebug("PARAMS: il.Emit(OpCodes.Ldarg, " + _ic + ");"); + il.Emit(OpCodes.Ldarg, _ic); + } + + + + // + // CALLING OPCODE PROCESSOR, one command at the time TO GENERATE IL + // + bool FoundRet = false; + while (FoundRet == false) + { + FoundRet = LSL_PROCESS_OPCODE(il); + } + + + if (Common.IL_UseTryCatch) + IL_INSERT_END_TRY(il, eventname); + + // Emit: RETURN FROM METHOD + il.Emit(OpCodes.Ret); + + return; + + } + + private void IL_INSERT_FUNCTIONLIST() + { + + Common.SendToDebug("Creating function list"); + + + string eventname = "GetFunctions"; + + Common.SendToDebug("Creating IL " + eventname); + // Define a private String field. + //FieldBuilder myField = myTypeBuilder.DefineField("EventList", typeof(String[]), FieldAttributes.Public); + + + //FieldBuilder mem = typeBuilder.DefineField("mem", typeof(Array), FieldAttributes.Private); + + + + MethodBuilder methodBuilder = typeBuilder.DefineMethod(eventname, + MethodAttributes.Public, + typeof(string[]), + null); + + //typeBuilder.DefineMethodOverride(methodBuilder, + // typeof(LSL_CLRInterface.LSLScript).GetMethod(eventname)); + + ILGenerator il = methodBuilder.GetILGenerator(); + + + + + // IL_INSERT_TRY(il, eventname); + + // // Push string to stack + // il.Emit(OpCodes.Ldstr, "Inside " + eventname); + + //// Push Console.WriteLine command to stack ... Console.WriteLine("Hello World!"); + //il.Emit(OpCodes.Call, typeof(Console).GetMethod + // ("WriteLine", new Type[] { typeof(string) })); + + //initIL.Emit(OpCodes.Newobj, typeof(string[])); + + //string[] MyArray = new string[2] { "TestItem1" , "TestItem2" }; + + ////il.Emit(OpCodes.Ldarg_0); + + il.DeclareLocal(typeof(string[])); + + ////il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldc_I4, EventList.Count); // Specify array length + il.Emit(OpCodes.Newarr, typeof(String)); // create new string array + il.Emit(OpCodes.Stloc_0); // Store array as local variable 0 in stack + ////SetFunctionList + + for (int lv = 0; lv < EventList.Count; lv++) + { + il.Emit(OpCodes.Ldloc_0); // Load local variable 0 onto stack + il.Emit(OpCodes.Ldc_I4, lv); // Push index position + il.Emit(OpCodes.Ldstr, EventList[lv]); // Push value + il.Emit(OpCodes.Stelem_Ref); // Perform array[index] = value + + //il.Emit(OpCodes.Ldarg_0); + //il.Emit(OpCodes.Ldstr, EventList[lv]); // Push value + //il.Emit(OpCodes.Call, typeof(LSL_BaseClass).GetMethod("AddFunction", new Type[] { typeof(string) })); + + } + + + + // IL_INSERT_END_TRY(il, eventname); + + + il.Emit(OpCodes.Ldloc_0); // Load local variable 0 onto stack + // il.Emit(OpCodes.Call, typeof(LSL_BaseClass).GetMethod("SetFunctionList", new Type[] { typeof(Array) })); + + il.Emit(OpCodes.Ret); // Return + + } + + + private void IL_INSERT_TRY(ILGenerator il, string eventname) + { + /* + * CLR TRY + */ + //Common.SendToDebug("CLR:" + eventname + ":il.BeginExceptionBlock()"); + il.BeginExceptionBlock(); + + // Push "Hello World!" string to stack + //Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Ldstr..."); + //il.Emit(OpCodes.Ldstr, "Starting CLR dynamic execution of: " + eventname); + + } + + private void IL_INSERT_END_TRY(ILGenerator il, string eventname) + { + /* + * CATCH + */ + Common.SendToDebug("CLR:" + eventname + ":il.BeginCatchBlock(typeof(Exception));"); + il.BeginCatchBlock(typeof(Exception)); + + // Push "Hello World!" string to stack + Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Ldstr..."); + il.Emit(OpCodes.Ldstr, "Execption executing dynamic CLR function " + eventname + ": "); + + //call void [mscorlib]System.Console::WriteLine(string) + Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call..."); + il.Emit(OpCodes.Call, typeof(Console).GetMethod + ("Write", new Type[] { typeof(string) })); + + //callvirt instance string [mscorlib]System.Exception::get_Message() + Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Callvirt..."); + il.Emit(OpCodes.Callvirt, typeof(Exception).GetMethod + ("get_Message")); + + //call void [mscorlib]System.Console::WriteLine(string) + Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call..."); + il.Emit(OpCodes.Call, typeof(Console).GetMethod + ("WriteLine", new Type[] { typeof(string) })); + + /* + * CLR END TRY + */ + //Common.SendToDebug("CLR:" + eventname + ":il.EndExceptionBlock();"); + il.EndExceptionBlock(); + } + + private LSO_Struct.StaticBlock GetStaticBlock(long pos) + { + long FirstPos = fs.Position; + try + { + UInt32 position = (UInt32)pos; + // STATIC BLOCK + Common.SendToDebug("Reading STATIC BLOCK at: " + position); + fs.Seek(position, SeekOrigin.Begin); + + if (StaticBlocks.ContainsKey(position) == true) + { + Common.SendToDebug("Found cached STATIC BLOCK"); + + + + return StaticBlocks[pos]; + } + + //int StaticBlockCount = 0; + // Read function blocks until we hit GFR + //while (fs.Position < myHeader.GFR) + //{ + //StaticBlockCount++; + + //Common.SendToDebug("Reading Static Block at: " + position); + + //fs.Seek(myHeader.GVR, SeekOrigin.Begin); + LSO_Struct.StaticBlock myStaticBlock = new LSO_Struct.StaticBlock(); + myStaticBlock.Static_Chunk_Header_Size = BitConverter.ToUInt32(br_read(4), 0); + myStaticBlock.ObjectType = br_read(1)[0]; + Common.SendToDebug("Static Block ObjectType: " + ((LSO_Enums.Variable_Type_Codes)myStaticBlock.ObjectType).ToString()); + myStaticBlock.Unknown = br_read(1)[0]; + // Size of datatype varies + if (myStaticBlock.ObjectType != 0) + myStaticBlock.BlockVariable = br_read(getObjectSize(myStaticBlock.ObjectType)); + + StaticBlocks.Add(position, myStaticBlock); + //} + Common.SendToDebug("Done reading Static Block."); + return myStaticBlock; + } + finally + { + // Go back to original read pos + fs.Seek(FirstPos, SeekOrigin.Begin); + } + + } + + } +} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSO_Struct.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSO_Struct.cs new file mode 100644 index 0000000000..74cf1e19bd --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSO/LSO_Struct.cs @@ -0,0 +1,135 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +/* Original code: Tedd Hansen */ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSO +{ + static class LSO_Struct + { + + public struct Header + { + public UInt32 TM; + public UInt32 IP; + public UInt32 VN; + public UInt32 BP; + public UInt32 SP; + public UInt32 HR; + public UInt32 HP; + public UInt32 CS; + public UInt32 NS; + public UInt32 CE; + public UInt32 IE; + public UInt32 ER; + public UInt32 FR; + public UInt32 SLR; + public UInt32 GVR; + public UInt32 GFR; + public UInt32 PR; + public UInt32 ESR; + public UInt32 SR; + public UInt64 NCE; + public UInt64 NIE; + public UInt64 NER; + } + + public struct StaticBlock + { + public UInt32 Static_Chunk_Header_Size; + public byte ObjectType; + public byte Unknown; + public byte[] BlockVariable; + } + /* Not actually a structure + public struct StaticBlockVariable + { + public UInt32 Integer1; + public UInt32 Float1; + public UInt32 HeapPointer_String; + public UInt32 HeapPointer_Key; + public byte[] Vector_12; + public byte[] Rotation_16; + public UInt32 Pointer_List_Structure; + } */ + public struct HeapBlock + { + public Int32 DataBlockSize; + public byte ObjectType; + public UInt16 ReferenceCount; + public byte[] Data; + } + public struct StateFrameBlock + { + public UInt32 StateCount; + public StatePointerBlock[] StatePointer; + } + public struct StatePointerBlock + { + public UInt32 Location; + public System.Collections.BitArray EventMask; + public StateBlock StateBlock; + } + public struct StateBlock + { + public UInt32 StartPos; + public UInt32 EndPos; + public UInt32 HeaderSize; + public byte Unknown; + public StateBlockHandler[] StateBlockHandlers; + } + public struct StateBlockHandler + { + public UInt32 CodeChunkPointer; + public UInt32 CallFrameSize; + } + public struct FunctionBlock + { + public UInt32 FunctionCount; + public UInt32[] CodeChunkPointer; + } + public struct CodeChunk + { + public UInt32 CodeChunkHeaderSize; + public string Comment; + public System.Collections.Generic.List CodeChunkArguments; + public byte EndMarker; + public byte ReturnTypePos; + public StaticBlock ReturnType; + } + public struct CodeChunkArgument + { + public byte FunctionReturnTypePos; + public byte NullString; + public StaticBlock FunctionReturnType; + } + } +} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/Server_API/LSL_BuiltIn_Commands.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/Server_API/LSL_BuiltIn_Commands.cs new file mode 100644 index 0000000000..8982bb6e1e --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/Server_API/LSL_BuiltIn_Commands.cs @@ -0,0 +1,476 @@ +using System; +using System.Collections.Generic; +using System.Text; +using libsecondlife; +using OpenSim.Region.Environment.Scenes; +using OpenSim.Region.Environment.Scenes.Scripting; +using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler; +using OpenSim.Region.ScriptEngine.Common; +using OpenSim.Framework.Console; + +namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler +{ + + /// + /// Contains all LSL ll-functions. This class will be in Default AppDomain. + /// + public class LSL_BuiltIn_Commands: MarshalByRefObject, LSL_BuiltIn_Commands_Interface + { + + private System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); + private ScriptManager m_manager; + private IScriptHost m_host; + + public LSL_BuiltIn_Commands(ScriptManager manager, IScriptHost host) + { + m_manager = manager; + m_host = host; + + MainLog.Instance.Notice("ScriptEngine", "LSL_BaseClass.Start() called. Hosted by [" + m_host.Name + ":" + m_host.UUID + "@" + m_host.AbsolutePosition + "]"); + } + + + private string m_state = "default"; + public string State() { + return m_state; + } + + public Scene World + { + get { return m_manager.World; } + } + + //These are the implementations of the various ll-functions used by the LSL scripts. + //starting out, we use the System.Math library for trig functions. - CFK 8-14-07 + public double llSin(double f) { return (double)Math.Sin(f); } + public double llCos(double f) { return (double)Math.Cos(f); } + public double llTan(double f) { return (double)Math.Tan(f); } + public double llAtan2(double x, double y) { return (double)Math.Atan2(y, x); } + public double llSqrt(double f) { return (double)Math.Sqrt(f); } + public double llPow(double fbase, double fexponent) { return (double)Math.Pow(fbase, fexponent); } + public int llAbs(int i) { return (int)Math.Abs(i); } + public double llFabs(double f) { return (double)Math.Abs(f); } + + public double llFrand(double mag) + { + lock (OpenSim.Framework.Utilities.Util.RandomClass) + { + return OpenSim.Framework.Utilities.Util.RandomClass.Next((int)mag); + } + } + public int llFloor(double f) { return (int)Math.Floor(f); } + public int llCeil(double f) { return (int)Math.Ceiling(f); } + public int llRound(double f) { return (int)Math.Round(f, 1); } + public double llVecMag(LSL_Types.Vector3 v) { return 0; } + public LSL_Types.Vector3 llVecNorm(LSL_Types.Vector3 v) { return new LSL_Types.Vector3(); } + public double llVecDist(LSL_Types.Vector3 a, LSL_Types.Vector3 b) { return 0; } + public LSL_Types.Vector3 llRot2Euler(LSL_Types.Quaternion r) { return new LSL_Types.Vector3(); } + public LSL_Types.Quaternion llEuler2Rot(LSL_Types.Vector3 v) { return new LSL_Types.Quaternion(); } + public LSL_Types.Quaternion llAxes2Rot(LSL_Types.Vector3 fwd, LSL_Types.Vector3 left, LSL_Types.Vector3 up) { return new LSL_Types.Quaternion(); } + public LSL_Types.Vector3 llRot2Fwd(LSL_Types.Quaternion r) { return new LSL_Types.Vector3(); } + public LSL_Types.Vector3 llRot2Left(LSL_Types.Quaternion r) { return new LSL_Types.Vector3(); } + public LSL_Types.Vector3 llRot2Up(LSL_Types.Quaternion r) { return new LSL_Types.Vector3(); } + public LSL_Types.Quaternion llRotBetween(LSL_Types.Vector3 start, LSL_Types.Vector3 end) { return new LSL_Types.Quaternion(); } + + public void llWhisper(int channelID, string text) + { + //Common.SendToDebug("INTERNAL FUNCTION llWhisper(" + channelID + ", \"" + text + "\");"); + //Console.WriteLine("llWhisper Channel " + channelID + ", Text: \"" + text + "\""); + //type for whisper is 0 + World.SimChat(Helpers.StringToField(text), + 0, m_host.AbsolutePosition, m_host.Name, m_host.UUID); + + + } + //public void llSay(int channelID, string text) + public void llSay(int channelID, string text) + { + //TODO: DO SOMETHING USEFUL HERE + //Common.SendToDebug("INTERNAL FUNCTION llSay(" + (int)channelID + ", \"" + (string)text + "\");"); + //Console.WriteLine("llSay Channel " + channelID + ", Text: \"" + text + "\""); + //type for say is 1 + + World.SimChat(Helpers.StringToField(text), + 1, m_host.AbsolutePosition, m_host.Name, m_host.UUID); + } + + public void llShout(int channelID, string text) + { + //Console.WriteLine("llShout Channel " + channelID + ", Text: \"" + text + "\""); + //type for shout is 2 + World.SimChat(Helpers.StringToField(text), + 2, m_host.AbsolutePosition, m_host.Name, m_host.UUID); + + } + + public int llListen(int channelID, string name, string ID, string msg) { return 0; } + public void llListenControl(int number, int active) { return; } + public void llListenRemove(int number) { return; } + public void llSensor(string name, string id, int type, double range, double arc) { return; } + public void llSensorRepeat(string name, string id, int type, double range, double arc, double rate) { return; } + public void llSensorRemove() { return; } + public string llDetectedName(int number) { return ""; } + public string llDetectedKey(int number) { return ""; } + public string llDetectedOwner(int number) { return ""; } + public int llDetectedType(int number) { return 0; } + public LSL_Types.Vector3 llDetectedPos(int number) { return new LSL_Types.Vector3(); } + public LSL_Types.Vector3 llDetectedVel(int number) { return new LSL_Types.Vector3(); } + public LSL_Types.Vector3 llDetectedGrab(int number) { return new LSL_Types.Vector3(); } + public LSL_Types.Quaternion llDetectedRot(int number) { return new LSL_Types.Quaternion(); } + public int llDetectedGroup(int number) { return 0; } + public int llDetectedLinkNumber(int number) { return 0; } + public void llDie() { return; } + public double llGround(LSL_Types.Vector3 offset) { return 0; } + public double llCloud(LSL_Types.Vector3 offset) { return 0; } + public LSL_Types.Vector3 llWind(LSL_Types.Vector3 offset) { return new LSL_Types.Vector3(); } + public void llSetStatus(int status, int value) { return; } + public int llGetStatus(int status) { return 0; } + public void llSetScale(LSL_Types.Vector3 scale) { return; } + public LSL_Types.Vector3 llGetScale() { return new LSL_Types.Vector3(); } + public void llSetColor(LSL_Types.Vector3 color, int face) { return; } + public double llGetAlpha(int face) { return 0; } + public void llSetAlpha(double alpha, int face) { return; } + public LSL_Types.Vector3 llGetColor(int face) { return new LSL_Types.Vector3(); } + public void llSetTexture(string texture, int face) { return; } + public void llScaleTexture(double u, double v, int face) { return; } + public void llOffsetTexture(double u, double v, int face) { return; } + public void llRotateTexture(double rotation, int face) { return; } + public string llGetTexture(int face) { return ""; } + public void llSetPos(LSL_Types.Vector3 pos) { return; } + + public LSL_Types.Vector3 llGetPos() + { + throw new NotImplementedException("llGetPos"); + // return m_host.AbsolutePosition; + } + + public LSL_Types.Vector3 llGetLocalPos() { return new LSL_Types.Vector3(); } + public void llSetRot(LSL_Types.Quaternion rot) { } + public LSL_Types.Quaternion llGetRot() { return new LSL_Types.Quaternion(); } + public LSL_Types.Quaternion llGetLocalRot() { return new LSL_Types.Quaternion(); } + public void llSetForce(LSL_Types.Vector3 force, int local) { } + public LSL_Types.Vector3 llGetForce() { return new LSL_Types.Vector3(); } + public int llTarget(LSL_Types.Vector3 position, double range) { return 0; } + public void llTargetRemove(int number) { } + public int llRotTarget(LSL_Types.Quaternion rot, double error) { return 0; } + public void llRotTargetRemove(int number) { } + public void llMoveToTarget(LSL_Types.Vector3 target, double tau) { } + public void llStopMoveToTarget() { } + public void llApplyImpulse(LSL_Types.Vector3 force, int local) { } + public void llApplyRotationalImpulse(LSL_Types.Vector3 force, int local) { } + public void llSetTorque(LSL_Types.Vector3 torque, int local) { } + public LSL_Types.Vector3 llGetTorque() { return new LSL_Types.Vector3(); } + public void llSetForceAndTorque(LSL_Types.Vector3 force, LSL_Types.Vector3 torque, int local) { } + public LSL_Types.Vector3 llGetVel() { return new LSL_Types.Vector3(); } + public LSL_Types.Vector3 llGetAccel() { return new LSL_Types.Vector3(); } + public LSL_Types.Vector3 llGetOmega() { return new LSL_Types.Vector3(); } + public double llGetTimeOfDay() { return 0; } + public double llGetWallclock() { return 0; } + public double llGetTime() { return 0; } + public void llResetTime() { } + public double llGetAndResetTime() { return 0; } + public void llSound() { } + public void llPlaySound(string sound, double volume) { } + public void llLoopSound(string sound, double volume) { } + public void llLoopSoundMaster(string sound, double volume) { } + public void llLoopSoundSlave(string sound, double volume) { } + public void llPlaySoundSlave(string sound, double volume) { } + public void llTriggerSound(string sound, double volume) { } + public void llStopSound() { } + public void llPreloadSound(string sound) { } + public string llGetSubString(string src, int start, int end) { return src.Substring(start, end); } + public string llDeleteSubString(string src, int start, int end) { return ""; } + public string llInsertString(string dst, int position, string src) { return ""; } + public string llToUpper(string src) { return src.ToUpper(); } + public string llToLower(string src) { return src.ToLower(); } + public int llGiveMoney(string destination, int amount) { return 0; } + public void llMakeExplosion() { } + public void llMakeFountain() { } + public void llMakeSmoke() { } + public void llMakeFire() { } + public void llRezObject(string inventory, LSL_Types.Vector3 pos, LSL_Types.Quaternion rot, int param) { } + public void llLookAt(LSL_Types.Vector3 target, double strength, double damping) { } + public void llStopLookAt() { } + public void llSetTimerEvent(double sec) { } + public void llSleep(double sec) { System.Threading.Thread.Sleep((int)(sec * 1000)); } + public double llGetMass() { return 0; } + public void llCollisionFilter(string name, string id, int accept) { } + public void llTakeControls(int controls, int accept, int pass_on) { } + public void llReleaseControls() { } + public void llAttachToAvatar(int attachment) { } + public void llDetachFromAvatar() { } + public void llTakeCamera() { } + public void llReleaseCamera() { } + public string llGetOwner() { return ""; } + public void llInstantMessage(string user, string message) { } + public void llEmail(string address, string subject, string message) { } + public void llGetNextEmail(string address, string subject) { } + public string llGetKey() { return ""; } + public void llSetBuoyancy(double buoyancy) { } + public void llSetHoverHeight(double height, int water, double tau) { } + public void llStopHover() { } + public void llMinEventDelay(double delay) { } + public void llSoundPreload() { } + public void llRotLookAt(LSL_Types.Quaternion target, double strength, double damping) { } + + public int llStringLength(string str) + { + if (str.Length > 0) + { + return str.Length; + } + else + { + return 0; + } + } + + public void llStartAnimation(string anim) { } + public void llStopAnimation(string anim) { } + public void llPointAt() { } + public void llStopPointAt() { } + public void llTargetOmega(LSL_Types.Vector3 axis, double spinrate, double gain) { } + public int llGetStartParameter() { return 0; } + public void llGodLikeRezObject(string inventory, LSL_Types.Vector3 pos) { } + public void llRequestPermissions(string agent, int perm) { } + public string llGetPermissionsKey() { return ""; } + public int llGetPermissions() { return 0; } + public int llGetLinkNumber() { return 0; } + public void llSetLinkColor(int linknumber, LSL_Types.Vector3 color, int face) { } + public void llCreateLink(string target, int parent) { } + public void llBreakLink(int linknum) { } + public void llBreakAllLinks() { } + public string llGetLinkKey(int linknum) { return ""; } + public void llGetLinkName(int linknum) { } + public int llGetInventoryNumber(int type) { return 0; } + public string llGetInventoryName(int type, int number) { return ""; } + public void llSetScriptState(string name, int run) { } + public double llGetEnergy() { return 1.0f; } + public void llGiveInventory(string destination, string inventory) { } + public void llRemoveInventory(string item) { } + + public void llSetText(string text, LSL_Types.Vector3 color, double alpha) + { + // TEMP DISABLED UNTIL WE CAN AGREE UPON VECTOR/ROTATION FORMAT + //m_host.SetText(text, color, alpha); + } + + public double llWater(LSL_Types.Vector3 offset) { return 0; } + public void llPassTouches(int pass) { } + public string llRequestAgentData(string id, int data) { return ""; } + public string llRequestInventoryData(string name) { return ""; } + public void llSetDamage(double damage) { } + public void llTeleportAgentHome(string agent) { } + public void llModifyLand(int action, int brush) { } + public void llCollisionSound(string impact_sound, double impact_volume) { } + public void llCollisionSprite(string impact_sprite) { } + public string llGetAnimation(string id) { return ""; } + public void llResetScript() { } + public void llMessageLinked(int linknum, int num, string str, string id) { } + public void llPushObject(string target, LSL_Types.Vector3 impulse, LSL_Types.Vector3 ang_impulse, int local) { } + public void llPassCollisions(int pass) { } + public string llGetScriptName() { return ""; } + public int llGetNumberOfSides() { return 0; } + public LSL_Types.Quaternion llAxisAngle2Rot(LSL_Types.Vector3 axis, double angle) { return new LSL_Types.Quaternion(); } + public LSL_Types.Vector3 llRot2Axis(LSL_Types.Quaternion rot) { return new LSL_Types.Vector3(); } + public void llRot2Angle() { } + public double llAcos(double val) { return (double)Math.Acos(val); } + public double llAsin(double val) { return (double)Math.Asin(val); } + public double llAngleBetween(LSL_Types.Quaternion a, LSL_Types.Quaternion b) { return 0; } + public string llGetInventoryKey(string name) { return ""; } + public void llAllowInventoryDrop(int add) { } + public LSL_Types.Vector3 llGetSunDirection() { return new LSL_Types.Vector3(); } + public LSL_Types.Vector3 llGetTextureOffset(int face) { return new LSL_Types.Vector3(); } + public LSL_Types.Vector3 llGetTextureScale(int side) { return new LSL_Types.Vector3(); } + public double llGetTextureRot(int side) { return 0; } + public int llSubStringIndex(string source, string pattern) { return 0; } + public string llGetOwnerKey(string id) { return ""; } + public LSL_Types.Vector3 llGetCenterOfMass() { return new LSL_Types.Vector3(); } + public List llListSort(List src, int stride, int ascending) + { return new List(); } + public int llGetListLength(List src) { return 0; } + public int llList2Integer(List src, int index) { return 0; } + public double llList2double(List src, int index) { return 0; } + public string llList2String(List src, int index) { return ""; } + public string llList2Key(List src, int index) { return ""; } + public LSL_Types.Vector3 llList2Vector(List src, int index) + { return new LSL_Types.Vector3(); } + public LSL_Types.Quaternion llList2Rot(List src, int index) + { return new LSL_Types.Quaternion(); } + public List llList2List(List src, int start, int end) + { return new List(); } + public List llDeleteSubList(List src, int start, int end) + { return new List(); } + public int llGetListEntryType(List src, int index) { return 0; } + public string llList2CSV(List src) { return ""; } + public List llCSV2List(string src) + { return new List(); } + public List llListRandomize(List src, int stride) + { return new List(); } + public List llList2ListStrided(List src, int start, int end, int stride) + { return new List(); } + public LSL_Types.Vector3 llGetRegionCorner() + { return new LSL_Types.Vector3(World.RegionInfo.RegionLocX * 256, World.RegionInfo.RegionLocY * 256, 0); } + public List llListInsertList(List dest, List src, int start) + { return new List(); } + public int llListFindList(List src, List test) { return 0; } + public string llGetObjectName() { return ""; } + public void llSetObjectName(string name) { } + public string llGetDate() { return ""; } + public int llEdgeOfWorld(LSL_Types.Vector3 pos, LSL_Types.Vector3 dir) { return 0; } + public int llGetAgentInfo(string id) { return 0; } + public void llAdjustSoundVolume(double volume) { } + public void llSetSoundQueueing(int queue) { } + public void llSetSoundRadius(double radius) { } + public string llKey2Name(string id) { return ""; } + public void llSetTextureAnim(int mode, int face, int sizex, int sizey, double start, double length, double rate) { } + public void llTriggerSoundLimited(string sound, double volume, LSL_Types.Vector3 top_north_east, LSL_Types.Vector3 bottom_south_west) { } + public void llEjectFromLand(string pest) { } + public void llParseString2List() { } + public int llOverMyLand(string id) { return 0; } + public string llGetLandOwnerAt(LSL_Types.Vector3 pos) { return ""; } + public string llGetNotecardLine(string name, int line) { return ""; } + public LSL_Types.Vector3 llGetAgentSize(string id) { return new LSL_Types.Vector3(); } + public int llSameGroup(string agent) { return 0; } + public void llUnSit(string id) { } + public LSL_Types.Vector3 llGroundSlope(LSL_Types.Vector3 offset) { return new LSL_Types.Vector3(); } + public LSL_Types.Vector3 llGroundNormal(LSL_Types.Vector3 offset) { return new LSL_Types.Vector3(); } + public LSL_Types.Vector3 llGroundContour(LSL_Types.Vector3 offset) { return new LSL_Types.Vector3(); } + public int llGetAttached() { return 0; } + public int llGetFreeMemory() { return 0; } + public string llGetRegionName() { return m_manager.RegionName; } + public double llGetRegionTimeDilation() { return 1.0f; } + public double llGetRegionFPS() { return 10.0f; } + public void llParticleSystem(List rules) { } + public void llGroundRepel(double height, int water, double tau) { } + public void llGiveInventoryList() { } + public void llSetVehicleType(int type) { } + public void llSetVehicledoubleParam(int param, double value) { } + public void llSetVehicleVectorParam(int param, LSL_Types.Vector3 vec) { } + public void llSetVehicleRotationParam(int param, LSL_Types.Quaternion rot) { } + public void llSetVehicleFlags(int flags) { } + public void llRemoveVehicleFlags(int flags) { } + public void llSitTarget(LSL_Types.Vector3 offset, LSL_Types.Quaternion rot) { } + public string llAvatarOnSitTarget() { return ""; } + public void llAddToLandPassList(string avatar, double hours) { } + public void llSetTouchText(string text) + { + } + + public void llSetSitText(string text) + { + } + public void llSetCameraEyeOffset(LSL_Types.Vector3 offset) { } + public void llSetCameraAtOffset(LSL_Types.Vector3 offset) { } + public void llDumpList2String() { } + public void llScriptDanger(LSL_Types.Vector3 pos) { } + public void llDialog(string avatar, string message, List buttons, int chat_channel) { } + public void llVolumeDetect(int detect) { } + public void llResetOtherScript(string name) { } + public int llGetScriptState(string name) { return 0; } + public void llRemoteLoadScript() { } + public void llSetRemoteScriptAccessPin(int pin) { } + public void llRemoteLoadScriptPin(string target, string name, int pin, int running, int start_param) { } + public void llOpenRemoteDataChannel() { } + public string llSendRemoteData(string channel, string dest, int idata, string sdata) { return ""; } + public void llRemoteDataReply(string channel, string message_id, string sdata, int idata) { } + public void llCloseRemoteDataChannel(string channel) { } + public string llMD5String(string src, int nonce) + { + return OpenSim.Framework.Utilities.Util.Md5Hash(src + ":" + nonce.ToString()); + } + public void llSetPrimitiveParams(List rules) { } + public string llStringToBase64(string str) { return ""; } + public string llBase64ToString(string str) { return ""; } + public void llXorBase64Strings() { } + public void llRemoteDataSetRegion() { } + public double llLog10(double val) { return (double)Math.Log10(val); } + public double llLog(double val) { return (double)Math.Log(val); } + public List llGetAnimationList(string id) { return new List(); } + public void llSetParcelMusicURL(string url) { } + + public LSL_Types.Vector3 llGetRootPosition() + { + throw new NotImplementedException("llGetRootPosition"); + //return m_root.AbsolutePosition; + } + + public LSL_Types.Quaternion llGetRootRotation() + { + return new LSL_Types.Quaternion(); + } + + public string llGetObjectDesc() { return ""; } + public void llSetObjectDesc(string desc) { } + public string llGetCreator() { return ""; } + public string llGetTimestamp() { return ""; } + public void llSetLinkAlpha(int linknumber, double alpha, int face) { } + public int llGetNumberOfPrims() { return 0; } + public string llGetNumberOfNotecardLines(string name) { return ""; } + public List llGetBoundingBox(string obj) { return new List(); } + public LSL_Types.Vector3 llGetGeometricCenter() { return new LSL_Types.Vector3(); } + public void llGetPrimitiveParams() { } + public string llIntegerToBase64(int number) { return ""; } + public int llBase64ToInteger(string str) { return 0; } + public double llGetGMTclock() { return 0; } + public string llGetSimulatorHostname() { return ""; } + public void llSetLocalRot(LSL_Types.Quaternion rot) { } + public List llParseStringKeepNulls(string src, List seperators, List spacers) + { return new List(); } + public void llRezAtRoot(string inventory, LSL_Types.Vector3 position, LSL_Types.Vector3 velocity, LSL_Types.Quaternion rot, int param) { } + public int llGetObjectPermMask(int mask) { return 0; } + public void llSetObjectPermMask(int mask, int value) { } + public void llGetInventoryPermMask(string item, int mask) { } + public void llSetInventoryPermMask(string item, int mask, int value) { } + public string llGetInventoryCreator(string item) { return ""; } + public void llOwnerSay(string msg) { } + public void llRequestSimulatorData(string simulator, int data) { } + public void llForceMouselook(int mouselook) { } + public double llGetObjectMass(string id) { return 0; } + public void llListReplaceList() { } + public void llLoadURL(string avatar_id, string message, string url) { } + public void llParcelMediaCommandList(List commandList) { } + public void llParcelMediaQuery() { } + + public int llModPow(int a, int b, int c) + { + Int64 tmp = 0; + Int64 val = Math.DivRem(Convert.ToInt64(Math.Pow(a, b)), c, out tmp); + + return Convert.ToInt32(tmp); + } + + public int llGetInventoryType(string name) { return 0; } + public void llSetPayPrice(int price, List quick_pay_buttons) { } + public LSL_Types.Vector3 llGetCameraPos() { return new LSL_Types.Vector3(); } + public LSL_Types.Quaternion llGetCameraRot() { return new LSL_Types.Quaternion(); } + public void llSetPrimURL() { } + public void llRefreshPrimURL() { } + public string llEscapeURL(string url) { return ""; } + public string llUnescapeURL(string url) { return ""; } + public void llMapDestination(string simname, LSL_Types.Vector3 pos, LSL_Types.Vector3 look_at) { } + public void llAddToLandBanList(string avatar, double hours) { } + public void llRemoveFromLandPassList(string avatar) { } + public void llRemoveFromLandBanList(string avatar) { } + public void llSetCameraParams(List rules) { } + public void llClearCameraParams() { } + public double llListStatistics(int operation, List src) { return 0; } + public int llGetUnixTime() + { + return OpenSim.Framework.Utilities.Util.UnixTimeSinceEpoch(); + } + public int llGetParcelFlags(LSL_Types.Vector3 pos) { return 0; } + public int llGetRegionFlags() { return 0; } + public string llXorBase64StringsCorrect(string str1, string str2) { return ""; } + public void llHTTPRequest() { } + public void llResetLandBanList() { } + public void llResetLandPassList() { } + public int llGetParcelPrimCount(LSL_Types.Vector3 pos, int category, int sim_wide) { return 0; } + public List llGetParcelPrimOwners(LSL_Types.Vector3 pos) { return new List(); } + public int llGetObjectPrimCount(string object_id) { return 0; } + public int llGetParcelMaxPrims(LSL_Types.Vector3 pos, int sim_wide) { return 0; } + public List llGetParcelDetails(LSL_Types.Vector3 pos, List param) { return new List(); } + + + } +} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/EventManager.cs new file mode 100644 index 0000000000..32353ce8d5 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/EventManager.cs @@ -0,0 +1,107 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +/* Original code: Tedd Hansen */ +using System; +using System.Collections.Generic; +using System.Text; +using libsecondlife; +using OpenSim.Framework.Interfaces; +using OpenSim.Region.Environment.Scenes.Scripting; + +namespace OpenSim.Region.ScriptEngine.DotNetEngine +{ + /// + /// Prepares events so they can be directly executed upon a script by EventQueueManager, then queues it. + /// + [Serializable] + class EventManager + { + private ScriptEngine myScriptEngine; + public IScriptHost TEMP_OBJECT_ID; + public EventManager(ScriptEngine _ScriptEngine) + { + myScriptEngine = _ScriptEngine; + // TODO: HOOK EVENTS UP TO SERVER! + //myScriptEngine.m_logger.Verbose("ScriptEngine", "EventManager Start"); + // TODO: ADD SERVER HOOK TO LOAD A SCRIPT THROUGH myScriptEngine.ScriptManager + + // Hook up a test event to our test form + myScriptEngine.Log.Verbose("ScriptEngine", "EventManager Hooking up dummy-event: touch_start"); + // TODO: REPLACE THIS WITH A REAL TOUCH_START EVENT IN SERVER + myScriptEngine.World.EventManager.OnObjectGrab += new OpenSim.Region.Environment.Scenes.EventManager.ObjectGrabDelegate(touch_start); + //myScriptEngine.World.touch_start += new TempWorldInterfaceEventDelegates.touch_start(touch_start); + } + + public void touch_start(uint localID, LLVector3 offsetPos, IClientAPI remoteClient) + { + // Add to queue for all scripts in ObjectID object + //myScriptEngine.m_logger.Verbose("ScriptEngine", "EventManager Event: touch_start"); + myScriptEngine.myEventQueueManager.AddToObjectQueue(TEMP_OBJECT_ID, "touch_start", new object[] { (int)0 }); + } + + + // TODO: Replace placeholders below + // These needs to be hooked up to OpenSim during init of this class + // then queued in EventQueueManager. + // When queued in EventQueueManager they need to be LSL compatible (name and params) + public void state_entry() { } + public void state_exit() { } + //public void touch_start() { } + public void touch() { } + public void touch_end() { } + public void collision_start() { } + public void collision() { } + public void collision_end() { } + public void land_collision_start() { } + public void land_collision() { } + public void land_collision_end() { } + public void timer() { } + public void listen() { } + public void on_rez() { } + public void sensor() { } + public void no_sensor() { } + public void control() { } + public void money() { } + public void email() { } + public void at_target() { } + public void not_at_target() { } + public void at_rot_target() { } + public void not_at_rot_target() { } + public void run_time_permissions() { } + public void changed() { } + public void attach() { } + public void dataserver() { } + public void link_message() { } + public void moving_start() { } + public void moving_end() { } + public void object_rez() { } + public void remote_data() { } + public void http_response() { } + + } +} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueManager.cs new file mode 100644 index 0000000000..c2a4b88696 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/EventQueueManager.cs @@ -0,0 +1,256 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +/* Original code: Tedd Hansen */ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Reflection; +using OpenSim.Region.Environment.Scenes.Scripting; + +namespace OpenSim.Region.ScriptEngine.DotNetEngine +{ + /// + /// EventQueueManager handles event queues + /// Events are queued and executed in separate thread + /// + [Serializable] + class EventQueueManager + { + /// + /// List of threads processing event queue + /// + private List EventQueueThreads = new List(); + private object QueueLock = new object(); // Mutex lock object + /// + /// How many ms to sleep if queue is empty + /// + private int NothingToDoSleepms = 50; + /// + /// How many threads to process queue with + /// + private int NumberOfThreads = 2; + /// + /// Queue containing events waiting to be executed + /// + private Queue EventQueue = new Queue(); + /// + /// Queue item structure + /// + private struct QueueItemStruct + { + public IScriptHost ObjectID; + public string ScriptID; + public string FunctionName; + public object[] param; + } + + /// + /// List of ObjectID locks for mutex processing of script events + /// + private List ObjectLocks = new List(); + private object TryLockLock = new object(); // Mutex lock object + + private ScriptEngine myScriptEngine; + public EventQueueManager(ScriptEngine _ScriptEngine) + { + myScriptEngine = _ScriptEngine; + + // + // Start event queue processing threads (worker threads) + // + for (int ThreadCount = 0; ThreadCount <= NumberOfThreads; ThreadCount++) + { + Thread EventQueueThread = new Thread(EventQueueThreadLoop); + EventQueueThreads.Add(EventQueueThread); + EventQueueThread.IsBackground = true; + EventQueueThread.Name = "EventQueueManagerThread_" + ThreadCount; + EventQueueThread.Start(); + } + } + ~EventQueueManager() + { + + // Kill worker threads + foreach (Thread EventQueueThread in new System.Collections.ArrayList(EventQueueThreads)) + { + if (EventQueueThread != null && EventQueueThread.IsAlive == true) + { + try + { + EventQueueThread.Abort(); + EventQueueThread.Join(); + } + catch (Exception e) + { + myScriptEngine.Log.Verbose("ScriptEngine", "EventQueueManager Exception killing worker thread: " + e.ToString()); + } + } + } + EventQueueThreads.Clear(); + // Todo: Clean up our queues + EventQueue.Clear(); + + } + + /// + /// Queue processing thread loop + /// + private void EventQueueThreadLoop() + { + //myScriptEngine.m_logger.Verbose("ScriptEngine", "EventQueueManager Worker thread spawned"); + try + { + QueueItemStruct BlankQIS = new QueueItemStruct(); + while (true) + { + QueueItemStruct QIS = BlankQIS; + bool GotItem = false; + + if (EventQueue.Count == 0) + { + // Nothing to do? Sleep a bit waiting for something to do + Thread.Sleep(NothingToDoSleepms); + } + else + { + // Something in queue, process + //myScriptEngine.m_logger.Verbose("ScriptEngine", "Processing event for ObjectID: " + QIS.ObjectID + ", ScriptID: " + QIS.ScriptID + ", FunctionName: " + QIS.FunctionName); + + // OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD + lock (QueueLock) + { + GotItem = false; + for (int qc = 0; qc < EventQueue.Count; qc++) + { + // Get queue item + QIS = EventQueue.Dequeue(); + + // Check if object is being processed by someone else + if (TryLock(QIS.ObjectID) == false) + { + // Object is already being processed, requeue it + EventQueue.Enqueue(QIS); + } + else + { + // We have lock on an object and can process it + GotItem = true; + break; + } + } // go through queue + } // lock + + if (GotItem == true) + { + // Execute function + myScriptEngine.myScriptManager.ExecuteEvent(QIS.ObjectID, QIS.ScriptID, QIS.FunctionName, QIS.param); + ReleaseLock(QIS.ObjectID); + } + + } // Something in queue + } // while + } // try + catch (ThreadAbortException tae) + { + myScriptEngine.Log.Verbose("ScriptEngine", "EventQueueManager Worker thread killed: " + tae.Message); + } + } + + /// + /// Try to get a mutex lock on ObjectID + /// + /// + /// + private bool TryLock(IScriptHost ObjectID) + { + lock (TryLockLock) + { + if (ObjectLocks.Contains(ObjectID) == true) + { + return false; + } + else + { + ObjectLocks.Add(ObjectID); + return true; + } + } + } + + /// + /// Release mutex lock on ObjectID + /// + /// + private void ReleaseLock(IScriptHost ObjectID) + { + lock (TryLockLock) + { + if (ObjectLocks.Contains(ObjectID) == true) + { + ObjectLocks.Remove(ObjectID); + } + } + } + + /// + /// Add event to event execution queue + /// + /// + /// Name of the function, will be state + "_event_" + FunctionName + /// Array of parameters to match event mask + public void AddToObjectQueue(IScriptHost ObjectID, string FunctionName, object[] param) + { + // Determine all scripts in Object and add to their queue + //myScriptEngine.m_logger.Verbose("ScriptEngine", "EventQueueManager Adding ObjectID: " + ObjectID + ", FunctionName: " + FunctionName); + + lock (QueueLock) + { + + foreach (string ScriptID in myScriptEngine.myScriptManager.GetScriptKeys(ObjectID)) + { + // Add to each script in that object + // TODO: Some scripts may not subscribe to this event. Should we NOT add it? Does it matter? + + // Create a structure and add data + QueueItemStruct QIS = new QueueItemStruct(); + QIS.ObjectID = ObjectID; + QIS.ScriptID = ScriptID; + QIS.FunctionName = FunctionName; + QIS.param = param; + + // Add it to queue + EventQueue.Enqueue(QIS); + + } + } + + } + + } +} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..aa76b6a691 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.Region.ScriptEngine.DotNetEngine")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OpenSim.Region.ScriptEngine.DotNetEngine")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("2842257e-6fde-4460-9368-4cde57fa9cc4")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptEngine.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptEngine.cs new file mode 100644 index 0000000000..9b8cff0b01 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptEngine.cs @@ -0,0 +1,95 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +/* Original code: Tedd Hansen */ +using System; +using System.Collections.Generic; +using System.Text; +using OpenSim.Framework.Console; +//using OpenSim.Region.Environment.Scenes; +using OpenSim.Region.Environment.Scenes.Scripting; + +namespace OpenSim.Region.ScriptEngine.DotNetEngine +{ + /// + /// This is the root object for ScriptEngine + /// + [Serializable] + public class ScriptEngine : OpenSim.Region.Environment.Scenes.Scripting.ScriptEngineInterface + { + + internal OpenSim.Region.Environment.Scenes.Scene World; + internal EventManager myEventManager; // Handles and queues incoming events from OpenSim + internal EventQueueManager myEventQueueManager; // Executes events + internal ScriptManager myScriptManager; // Load, unload and execute scripts + internal AppDomainManager myAppDomainManager; + + private OpenSim.Framework.Console.LogBase m_log; + + public ScriptEngine() + { + //Common.SendToDebug("ScriptEngine Object Initialized"); + Common.mySE = this; + } + + public LogBase Log + { + get { return m_log; } + } + + public void InitializeEngine(OpenSim.Region.Environment.Scenes.Scene Sceneworld, OpenSim.Framework.Console.LogBase logger) + { + World = Sceneworld; + m_log = logger; + + //m_logger.Status("ScriptEngine", "InitializeEngine"); + + // Create all objects we'll be using + myEventQueueManager = new EventQueueManager(this); + myEventManager = new EventManager(this); + myScriptManager = new ScriptManager(this); + myAppDomainManager = new AppDomainManager(); + + // Should we iterate the region for scripts that needs starting? + // Or can we assume we are loaded before anything else so we can use proper events? + + } + public void Shutdown() + { + // We are shutting down + } + + // !!!FOR DEBUGGING ONLY!!! (for executing script directly from test app) + [Obsolete("!!!FOR DEBUGGING ONLY!!!")] + public void StartScript(string ScriptID, IScriptHost ObjectID) + { + this.myEventManager.TEMP_OBJECT_ID = ObjectID; + Log.Status("ScriptEngine", "DEBUG FUNCTION: StartScript: " + ScriptID); + myScriptManager.StartScript(ScriptID, ObjectID); + } + } +} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs new file mode 100644 index 0000000000..7f787909c1 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs @@ -0,0 +1,271 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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. +* +*/ +/* Original code: Tedd Hansen */ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Reflection; +using System.Runtime.Remoting; +using OpenSim.Region.Environment.Scenes; +using OpenSim.Region.Environment.Scenes.Scripting; +using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler; +using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL; +using OpenSim.Region.ScriptEngine.Common; + +namespace OpenSim.Region.ScriptEngine.DotNetEngine +{ + /// + /// Loads scripts + /// Compiles them if necessary + /// Execute functions for EventQueueManager (Sends them to script on other AppDomain for execution) + /// + [Serializable] + public class ScriptManager + { + + private ScriptEngine m_scriptEngine; + public ScriptManager(ScriptEngine scriptEngine) + { + m_scriptEngine = scriptEngine; + m_scriptEngine.Log.Verbose("ScriptEngine", "ScriptManager Start"); + AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); + } + + private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) + { + + //Console.WriteLine("CurrentDomain_AssemblyResolve: " + args.Name); + return Assembly.GetExecutingAssembly().FullName == args.Name ? Assembly.GetExecutingAssembly() : null; + + } + + + // Object> + // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. + // Instead use RuntimeTypeHandle, RuntimeFieldHandle and RunTimeHandle (IntPtr) instead! + internal Dictionary> Scripts = new Dictionary>(); + public Scene World + { + get + { + return m_scriptEngine.World; + } + } + + + internal Dictionary.KeyCollection GetScriptKeys(IScriptHost ObjectID) + { + if (Scripts.ContainsKey(ObjectID) == false) + return null; + + Dictionary Obj; + Scripts.TryGetValue(ObjectID, out Obj); + + return Obj.Keys; + + } + + internal LSL_BaseClass GetScript(IScriptHost ObjectID, string ScriptID) + { + if (Scripts.ContainsKey(ObjectID) == false) + return null; + + Dictionary Obj; + Scripts.TryGetValue(ObjectID, out Obj); + if (Obj.ContainsKey(ScriptID) == false) + return null; + + // Get script + LSL_BaseClass Script; + Obj.TryGetValue(ScriptID, out Script); + + return Script; + + } + internal void SetScript(IScriptHost ObjectID, string ScriptID, LSL_BaseClass Script) + { + // Create object if it doesn't exist + if (Scripts.ContainsKey(ObjectID) == false) + { + Scripts.Add(ObjectID, new Dictionary()); + } + + // Delete script if it exists + Dictionary Obj; + Scripts.TryGetValue(ObjectID, out Obj); + if (Obj.ContainsKey(ScriptID) == true) + Obj.Remove(ScriptID); + + // Add to object + Obj.Add(ScriptID, Script); + + } + internal void RemoveScript(IScriptHost ObjectID, string ScriptID) + { + // Don't have that object? + if (Scripts.ContainsKey(ObjectID) == false) + return; + + // Delete script if it exists + Dictionary Obj; + Scripts.TryGetValue(ObjectID, out Obj); + if (Obj.ContainsKey(ScriptID) == true) + Obj.Remove(ScriptID); + + } + /// + /// Fetches, loads and hooks up a script to an objects events + /// + /// + /// + public void StartScript(string ScriptID, IScriptHost ObjectID) + { + //IScriptHost root = host.GetRoot(); + m_scriptEngine.Log.Verbose("ScriptEngine", "ScriptManager StartScript: ScriptID: " + ScriptID + ", ObjectID: " + ObjectID); + + // We will initialize and start the script. + // It will be up to the script itself to hook up the correct events. + string FileName = ""; + + try + { + + + // * Fetch script from server + // DEBUG - ScriptID is an actual filename during debug + // (therefore we can also check type by looking at extension) + FileName = ScriptID; + + // * Does script need compile? Send it to LSL compiler first. (TODO: Use (and clean) compiler cache) + //myScriptEngine.m_logger.Verbose("ScriptEngine", "ScriptManager Script extension: " + System.IO.Path.GetExtension(FileName).ToLower()); + switch (System.IO.Path.GetExtension(FileName).ToLower()) + { + case ".txt": + case ".lsl": + case ".cs": + m_scriptEngine.Log.Verbose("ScriptEngine", "ScriptManager Script is CS/LSL, compiling to .Net Assembly"); + // Create a new instance of the compiler (currently we don't want reuse) + OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.Compiler LSLCompiler = new OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.Compiler(); + // Compile + FileName = LSLCompiler.Compile(FileName); + break; + default: + throw new Exception("Unknown script type."); + } + + + + m_scriptEngine.Log.Verbose("ScriptEngine", "Compilation done"); + // * Insert yield into code + FileName = ProcessYield(FileName); + + + //OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSO.LSL_BaseClass Script = LoadAndInitAssembly(FreeAppDomain, FileName); + + //OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.LSL_BaseClass Script = LoadAndInitAssembly(FreeAppDomain, FileName, ObjectID); + long before; + before = GC.GetTotalMemory(true); + LSL_BaseClass Script = m_scriptEngine.myAppDomainManager.LoadScript(FileName); + Console.WriteLine("Script occupies {0} bytes", GC.GetTotalMemory(true) - before); + before = GC.GetTotalMemory(true); + Script = m_scriptEngine.myAppDomainManager.LoadScript(FileName); + Console.WriteLine("Script occupies {0} bytes", GC.GetTotalMemory(true) - before); + //before = GC.GetTotalMemory(true); + //Script = m_scriptEngine.myAppDomainManager.LoadScript(FileName); + //Console.WriteLine("Script occupies {0} bytes", GC.GetTotalMemory(true) - before); + + + // Add it to our temporary active script keeper + //Scripts.Add(FullScriptID, Script); + SetScript(ObjectID, ScriptID, Script); + // We need to give (untrusted) assembly a private instance of BuiltIns + // this private copy will contain Read-Only FullScriptID so that it can bring that on to the server whenever needed. + LSL_BuiltIn_Commands LSLB = new LSL_BuiltIn_Commands(this, ObjectID); + + // Start the script - giving it BuiltIns + Script.Start(LSLB); + + } + catch (Exception e) + { + m_scriptEngine.Log.Error("ScriptEngine", "Exception loading script \"" + FileName + "\": " + e.ToString()); + } + + + } + public void StopScript(string ScriptID, IScriptHost ObjectID) + { + // Stop script + + // Get AppDomain + AppDomain ad = GetScript(ObjectID, ScriptID).Exec.GetAppDomain(); + // Tell script not to accept new requests + GetScript(ObjectID, ScriptID).Exec.StopScript(); + // Remove from internal structure + RemoveScript(ObjectID, ScriptID); + // Tell AppDomain that we have stopped script + m_scriptEngine.myAppDomainManager.StopScript(ad); + } + private string ProcessYield(string FileName) + { + // TODO: Create a new assembly and copy old but insert Yield Code + //return TempDotNetMicroThreadingCodeInjector.TestFix(FileName); + return FileName; + } + + + + /// + /// Execute a LL-event-function in Script + /// + /// Object the script is located in + /// Script ID + /// Name of function + /// Arguments to pass to function + internal void ExecuteEvent(IScriptHost ObjectID, string ScriptID, string FunctionName, object[] args) + { + + // Execute a function in the script + m_scriptEngine.Log.Verbose("ScriptEngine", "Executing Function ObjectID: " + ObjectID + ", ScriptID: " + ScriptID + ", FunctionName: " + FunctionName); + LSL_BaseClass Script = m_scriptEngine.myScriptManager.GetScript(ObjectID, ScriptID); + + // Must be done in correct AppDomain, so leaving it up to the script itself + Script.Exec.ExecuteEvent(FunctionName, args); + + } + + public string RegionName + { + get + { + return World.RegionInfo.RegionName; + } + } + } +} diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/TempDotNetMicroThreadingCodeInjector.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/TempDotNetMicroThreadingCodeInjector.cs new file mode 100644 index 0000000000..64cb7cd118 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/TempDotNetMicroThreadingCodeInjector.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Rail.Transformation; +using Rail.Reflect; +using Rail.Exceptions; +using Rail.MSIL; + +namespace OpenSim.Region.ScriptEngine.DotNetEngine +{ + /// + /// Tedds Sandbox for RAIL/microtrheading. This class is only for testing purposes! + /// Its offspring will be the actual implementation. + /// + class TempDotNetMicroThreadingCodeInjector + { + public static string TestFix(string FileName) + { + string ret = System.IO.Path.GetFileNameWithoutExtension(FileName + "_fixed.dll"); + + Console.WriteLine("Loading: \"" + FileName + "\""); + RAssemblyDef rAssembly = RAssemblyDef.LoadAssembly(FileName); + + + //Get the type of the method to copy from assembly Teste2.exe to assembly Teste.exe + RTypeDef type = (RTypeDef)rAssembly.RModuleDef.GetType("SecondLife.Script"); + + //Get the methods in the type + RMethod[] m = type.GetMethods(); + + //Create a MethodPrologueAdder visitor object with the method to add + //and with the flag that enables local variable creation set to true + MethodPrologueAdder mpa = new MethodPrologueAdder((RMethodDef)m[0], true); + + //Apply the changes to the assembly + rAssembly.Accept(mpa); + + //Save the new assembly + rAssembly.SaveAssembly(ret); + + return ret; + + } + } +} diff --git a/OpenSim/Region/Storage/OpenSim.DataStore.DB4o/DB4oDataStore.cs b/OpenSim/Region/Storage/OpenSim.DataStore.DB4o/DB4oDataStore.cs new file mode 100644 index 0000000000..5212ab17de --- /dev/null +++ b/OpenSim/Region/Storage/OpenSim.DataStore.DB4o/DB4oDataStore.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.Text; + +using OpenSim.Region.Environment.Scenes; +using OpenSim.Region.Environment.LandManagement; +using OpenSim.Region.Environment; +using OpenSim.Region.Interfaces; +using OpenSim.Framework.Console; +using libsecondlife; + +using Db4objects.Db4o; +using Db4objects.Db4o.Query; + +namespace OpenSim.DataStore.DB4oStorage +{ + + public class SceneObjectQuery : Predicate + { + private LLUUID globalIDSearch; + + public SceneObjectQuery(LLUUID find) + { + globalIDSearch = find; + } + + public bool Match(SceneObjectGroup obj) + { + return obj.UUID == globalIDSearch; + } + } + + + public class DB4oDataStore : IRegionDataStore + { + private IObjectContainer db; + + public void Initialise(string dbfile, string dbname) + { + MainLog.Instance.Verbose("DATASTORE", "DB4O - Opening " + dbfile); + db = Db4oFactory.OpenFile(dbfile); + + return; + } + + public void StoreObject(SceneObjectGroup obj) + { + db.Set(obj); + } + + public void RemoveObject(LLUUID obj) + { + IObjectSet result = db.Query(new SceneObjectQuery(obj)); + if (result.Count > 0) + { + SceneObjectGroup item = (SceneObjectGroup)result.Next(); + db.Delete(item); + } + } + + public List LoadObjects() + { + IObjectSet result = db.Get(typeof(SceneObjectGroup)); + List retvals = new List(); + + MainLog.Instance.Verbose("DATASTORE", "DB4O - LoadObjects found " + result.Count.ToString() + " objects"); + + foreach (Object obj in result) + { + retvals.Add((SceneObjectGroup)obj); + } + + return retvals; + } + + public void StoreTerrain(double[,] ter) + { + + } + + public double[,] LoadTerrain() + { + return null; + } + + public void RemoveLandObject(uint id) + { + + } + + public void StoreParcel(Land parcel) + { + + } + + public List LoadLandObjects() + { + return new List(); + } + + public void Shutdown() + { + if (db != null) + { + db.Commit(); + db.Close(); + } + } + } +} diff --git a/OpenSim/Region/Storage/OpenSim.DataStore.DB4o/Properties/AssemblyInfo.cs b/OpenSim/Region/Storage/OpenSim.DataStore.DB4o/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..0d6788b49e --- /dev/null +++ b/OpenSim/Region/Storage/OpenSim.DataStore.DB4o/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.DataStore.DB4o")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OpenSim.DataStore.DB4o")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("7a12de8b-fdd1-48f5-89a9-8dc2dafbeebc")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs b/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs new file mode 100644 index 0000000000..15754a95d6 --- /dev/null +++ b/OpenSim/Region/Storage/OpenSim.DataStore.MonoSqlite/MonoSqliteDataStore.cs @@ -0,0 +1,644 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Xml; +using System.Xml.Serialization; +using System.IO; + +using OpenSim.Region.Environment.Scenes; +using OpenSim.Region.Environment.LandManagement; +using OpenSim.Region.Environment; +using OpenSim.Region.Interfaces; +using OpenSim.Framework.Console; +using OpenSim.Framework.Types; +using OpenSim.Framework.Utilities; +using libsecondlife; + +using System.Data; +using System.Data.SqlTypes; + +using Mono.Data.SqliteClient; + +namespace OpenSim.DataStore.MonoSqliteStorage +{ + + public class MonoSqliteDataStore : IRegionDataStore + { + private const string primSelect = "select * from prims"; + private const string shapeSelect = "select * from primshapes"; + + private DataSet ds; + private SqliteDataAdapter primDa; + private SqliteDataAdapter shapeDa; + + public void Initialise(string dbfile, string dbname) + { + string connectionString = "URI=file:" + dbfile + ",version=3"; + + MainLog.Instance.Verbose("DATASTORE", "Sqlite - connecting: " + dbfile); + SqliteConnection conn = new SqliteConnection(connectionString); + + SqliteCommand primSelectCmd = new SqliteCommand(primSelect, conn); + primDa = new SqliteDataAdapter(primSelectCmd); + // SqliteCommandBuilder primCb = new SqliteCommandBuilder(primDa); + + SqliteCommand shapeSelectCmd = new SqliteCommand(shapeSelect, conn); + shapeDa = new SqliteDataAdapter(shapeSelectCmd); + // SqliteCommandBuilder shapeCb = new SqliteCommandBuilder(shapeDa); + + ds = new DataSet(); + + // We fill the data set, now we've got copies in memory for the information + // TODO: see if the linkage actually holds. + // primDa.FillSchema(ds, SchemaType.Source, "PrimSchema"); + primDa.Fill(ds, "prims"); + shapeDa.Fill(ds, "primshapes"); + ds.AcceptChanges(); + + DataTable prims = ds.Tables["prims"]; + prims.PrimaryKey = new DataColumn[] { prims.Columns["UUID"] }; + setupPrimCommands(primDa, conn); + + // shapeDa.FillSchema(ds, SchemaType.Source, "ShapeSchema"); + DataTable shapes = ds.Tables["primshapes"]; + shapes.PrimaryKey = new DataColumn[] { shapes.Columns["UUID"] }; + setupShapeCommands(shapeDa, conn); + + return; + } + + private SqliteParameter createSqliteParameter(string name, DbType type) + { + SqliteParameter param = new SqliteParameter(); + param.ParameterName = ":" + name; + param.DbType = type; + param.SourceColumn = name; + param.SourceVersion = DataRowVersion.Current; + return param; + } + + private Dictionary createPrimDataDefs() + { + Dictionary data = new Dictionary(); + data.Add("UUID", DbType.String); + data.Add("ParentID", DbType.Int32); + data.Add("CreationDate", DbType.Int32); + data.Add("Name", DbType.String); + data.Add("SceneGroupID", DbType.String); + // various text fields + data.Add("Text", DbType.String); + data.Add("Description", DbType.String); + data.Add("SitName", DbType.String); + data.Add("TouchName", DbType.String); + // permissions + data.Add("CreatorID", DbType.String); + data.Add("OwnerID", DbType.String); + data.Add("GroupID", DbType.String); + data.Add("LastOwnerID", DbType.String); + data.Add("OwnerMask", DbType.Int32); + data.Add("NextOwnerMask", DbType.Int32); + data.Add("GroupMask", DbType.Int32); + data.Add("EveryoneMask", DbType.Int32); + data.Add("BaseMask", DbType.Int32); + // vectors + data.Add("PositionX", DbType.Double); + data.Add("PositionY", DbType.Double); + data.Add("PositionZ", DbType.Double); + data.Add("GroupPositionX", DbType.Double); + data.Add("GroupPositionY", DbType.Double); + data.Add("GroupPositionZ", DbType.Double); + data.Add("VelocityX", DbType.Double); + data.Add("VelocityY", DbType.Double); + data.Add("VelocityZ", DbType.Double); + data.Add("AngularVelocityX", DbType.Double); + data.Add("AngularVelocityY", DbType.Double); + data.Add("AngularVelocityZ", DbType.Double); + data.Add("AccelerationX", DbType.Double); + data.Add("AccelerationY", DbType.Double); + data.Add("AccelerationZ", DbType.Double); + // quaternions + data.Add("RotationX", DbType.Double); + data.Add("RotationY", DbType.Double); + data.Add("RotationZ", DbType.Double); + data.Add("RotationW", DbType.Double); + return data; + } + + private Dictionary createShapeDataDefs() + { + Dictionary data = new Dictionary(); + data.Add("UUID", DbType.String); + // shape is an enum + data.Add("Shape", DbType.Int32); + // vectors + data.Add("ScaleX", DbType.Double); + data.Add("ScaleY", DbType.Double); + data.Add("ScaleZ", DbType.Double); + // paths + data.Add("PCode", DbType.Int32); + data.Add("PathBegin", DbType.Int32); + data.Add("PathEnd", DbType.Int32); + data.Add("PathScaleX", DbType.Int32); + data.Add("PathScaleY", DbType.Int32); + data.Add("PathShearX", DbType.Int32); + data.Add("PathShearY", DbType.Int32); + data.Add("PathSkew", DbType.Int32); + data.Add("PathCurve", DbType.Int32); + data.Add("PathRadiusOffset", DbType.Int32); + data.Add("PathRevolutions", DbType.Int32); + data.Add("PathTaperX", DbType.Int32); + data.Add("PathTaperY", DbType.Int32); + data.Add("PathTwist", DbType.Int32); + data.Add("PathTwistBegin", DbType.Int32); + // profile + data.Add("ProfileBegin", DbType.Int32); + data.Add("ProfileEnd", DbType.Int32); + data.Add("ProfileCurve", DbType.Int32); + data.Add("ProfileHollow", DbType.Int32); + // text TODO: this isn't right, but I'm not sure the right + // way to specify this as a blob atm + data.Add("Texture", DbType.Binary); + return data; + } + + private SqliteCommand createInsertCommand(string table, Dictionary defs) + { + /** + * This is subtle enough to deserve some commentary. + * Instead of doing *lots* and *lots of hardcoded strings + * for database definitions we'll use the fact that + * realistically all insert statements look like "insert + * into A(b, c) values(:b, :c) on the parameterized query + * front. If we just have a list of b, c, etc... we can + * generate these strings instead of typing them out. + */ + string[] cols = new string[defs.Keys.Count]; + defs.Keys.CopyTo(cols, 0); + + string sql = "insert into " + table + "("; + sql += String.Join(", ", cols); + // important, the first ':' needs to be here, the rest get added in the join + sql += ") values (:"; + sql += String.Join(", :", cols); + sql += ")"; + SqliteCommand cmd = new SqliteCommand(sql); + + // this provides the binding for all our parameters, so + // much less code than it used to be + foreach (KeyValuePair kvp in defs) + { + cmd.Parameters.Add(createSqliteParameter(kvp.Key, kvp.Value)); + } + return cmd; + } + + private SqliteCommand createUpdateCommand(string table, string pk, Dictionary defs) + { + string sql = "update " + table + " set "; + string subsql = ""; + foreach (string key in defs.Keys) + { + if (subsql.Length > 0) + { // a map function would rock so much here + subsql += ", "; + } + subsql += key + "= :" + key; + } + sql += subsql; + sql += " where " + pk; + SqliteCommand cmd = new SqliteCommand(sql); + + // this provides the binding for all our parameters, so + // much less code than it used to be + foreach (KeyValuePair kvp in defs) + { + cmd.Parameters.Add(createSqliteParameter(kvp.Key, kvp.Value)); + } + return cmd; + } + + private void setupPrimCommands(SqliteDataAdapter da, SqliteConnection conn) + { + Dictionary primDataDefs = createPrimDataDefs(); + + da.InsertCommand = createInsertCommand("prims", primDataDefs); + da.InsertCommand.Connection = conn; + + da.UpdateCommand = createUpdateCommand("prims", "UUID=:UUID", primDataDefs); + da.UpdateCommand.Connection = conn; + + SqliteCommand delete = new SqliteCommand("delete from prims where UUID = :UUID"); + delete.Parameters.Add(createSqliteParameter("UUID", DbType.String)); + delete.Connection = conn; + da.DeleteCommand = delete; + } + + private void setupShapeCommands(SqliteDataAdapter da, SqliteConnection conn) + { + Dictionary shapeDataDefs = createShapeDataDefs(); + + da.InsertCommand = createInsertCommand("primshapes", shapeDataDefs); + da.InsertCommand.Connection = conn; + + da.UpdateCommand = createUpdateCommand("primshapes", "UUID=:UUID", shapeDataDefs); + da.UpdateCommand.Connection = conn; + + SqliteCommand delete = new SqliteCommand("delete from primshapes where UUID = :UUID"); + delete.Parameters.Add(createSqliteParameter("UUID", DbType.String)); + delete.Connection = conn; + da.DeleteCommand = delete; + } + + private SceneObjectPart buildPrim(DataRow row) + { + // TODO: this doesn't work yet because something more + // interesting has to be done to actually get these values + // back out. Not enough time to figure it out yet. + SceneObjectPart prim = new SceneObjectPart(); + prim.UUID = new LLUUID((String)row["UUID"]); + // explicit conversion of integers is required, which sort + // of sucks. No idea if there is a shortcut here or not. + prim.ParentID = Convert.ToUInt32(row["ParentID"]); + prim.CreationDate = Convert.ToInt32(row["CreationDate"]); + prim.Name = (String)row["Name"]; + // various text fields + prim.Text = (String)row["Text"]; + prim.Description = (String)row["Description"]; + prim.SitName = (String)row["SitName"]; + prim.TouchName = (String)row["TouchName"]; + // permissions + prim.CreatorID = new LLUUID((String)row["CreatorID"]); + prim.OwnerID = new LLUUID((String)row["OwnerID"]); + prim.GroupID = new LLUUID((String)row["GroupID"]); + prim.LastOwnerID = new LLUUID((String)row["LastOwnerID"]); + prim.OwnerMask = Convert.ToUInt32(row["OwnerMask"]); + prim.NextOwnerMask = Convert.ToUInt32(row["NextOwnerMask"]); + prim.GroupMask = Convert.ToUInt32(row["GroupMask"]); + prim.EveryoneMask = Convert.ToUInt32(row["EveryoneMask"]); + prim.BaseMask = Convert.ToUInt32(row["BaseMask"]); + // vectors + prim.OffsetPosition = new LLVector3( + Convert.ToSingle(row["PositionX"]), + Convert.ToSingle(row["PositionY"]), + Convert.ToSingle(row["PositionZ"]) + ); + prim.GroupPosition = new LLVector3( + Convert.ToSingle(row["GroupPositionX"]), + Convert.ToSingle(row["GroupPositionY"]), + Convert.ToSingle(row["GroupPositionZ"]) + ); + prim.Velocity = new LLVector3( + Convert.ToSingle(row["VelocityX"]), + Convert.ToSingle(row["VelocityY"]), + Convert.ToSingle(row["VelocityZ"]) + ); + prim.AngularVelocity = new LLVector3( + Convert.ToSingle(row["AngularVelocityX"]), + Convert.ToSingle(row["AngularVelocityY"]), + Convert.ToSingle(row["AngularVelocityZ"]) + ); + prim.Acceleration = new LLVector3( + Convert.ToSingle(row["AccelerationX"]), + Convert.ToSingle(row["AccelerationY"]), + Convert.ToSingle(row["AccelerationZ"]) + ); + // quaternions + prim.RotationOffset = new LLQuaternion( + Convert.ToSingle(row["RotationX"]), + Convert.ToSingle(row["RotationY"]), + Convert.ToSingle(row["RotationZ"]), + Convert.ToSingle(row["RotationW"]) + ); + + return prim; + } + + private void fillPrimRow(DataRow row, SceneObjectPart prim, LLUUID sceneGroupID) + { + row["UUID"] = prim.UUID; + row["ParentID"] = prim.ParentID; + row["CreationDate"] = prim.CreationDate; + row["Name"] = prim.Name; + row["SceneGroupID"] = sceneGroupID; // the UUID of the root part for this SceneObjectGroup + // various text fields + row["Text"] = prim.Text; + row["Description"] = prim.Description; + row["SitName"] = prim.SitName; + row["TouchName"] = prim.TouchName; + // permissions + row["CreatorID"] = prim.CreatorID; + row["OwnerID"] = prim.OwnerID; + row["GroupID"] = prim.GroupID; + row["LastOwnerID"] = prim.LastOwnerID; + row["OwnerMask"] = prim.OwnerMask; + row["NextOwnerMask"] = prim.NextOwnerMask; + row["GroupMask"] = prim.GroupMask; + row["EveryoneMask"] = prim.EveryoneMask; + row["BaseMask"] = prim.BaseMask; + // vectors + row["PositionX"] = prim.OffsetPosition.X; + row["PositionY"] = prim.OffsetPosition.Y; + row["PositionZ"] = prim.OffsetPosition.Z; + row["GroupPositionX"] = prim.GroupPosition.X; + row["GroupPositionY"] = prim.GroupPosition.Y; + row["GroupPositionZ"] = prim.GroupPosition.Z; + row["VelocityX"] = prim.Velocity.X; + row["VelocityY"] = prim.Velocity.Y; + row["VelocityZ"] = prim.Velocity.Z; + row["AngularVelocityX"] = prim.AngularVelocity.X; + row["AngularVelocityY"] = prim.AngularVelocity.Y; + row["AngularVelocityZ"] = prim.AngularVelocity.Z; + row["AccelerationX"] = prim.Acceleration.X; + row["AccelerationY"] = prim.Acceleration.Y; + row["AccelerationZ"] = prim.Acceleration.Z; + // quaternions + row["RotationX"] = prim.RotationOffset.X; + row["RotationY"] = prim.RotationOffset.Y; + row["RotationZ"] = prim.RotationOffset.Z; + row["RotationW"] = prim.RotationOffset.W; + } + + private PrimitiveBaseShape buildShape(DataRow row) + { + PrimitiveBaseShape s = new PrimitiveBaseShape(); + s.Scale = new LLVector3( + Convert.ToSingle(row["ScaleX"]), + Convert.ToSingle(row["ScaleY"]), + Convert.ToSingle(row["ScaleZ"]) + ); + // paths + s.PCode = Convert.ToByte(row["PCode"]); + s.PathBegin = Convert.ToUInt16(row["PathBegin"]); + s.PathEnd = Convert.ToUInt16(row["PathEnd"]); + s.PathScaleX = Convert.ToByte(row["PathScaleX"]); + s.PathScaleY = Convert.ToByte(row["PathScaleY"]); + s.PathShearX = Convert.ToByte(row["PathShearX"]); + s.PathShearY = Convert.ToByte(row["PathShearY"]); + s.PathSkew = Convert.ToSByte(row["PathSkew"]); + s.PathCurve = Convert.ToByte(row["PathCurve"]); + s.PathRadiusOffset = Convert.ToSByte(row["PathRadiusOffset"]); + s.PathRevolutions = Convert.ToByte(row["PathRevolutions"]); + s.PathTaperX = Convert.ToSByte(row["PathTaperX"]); + s.PathTaperY = Convert.ToSByte(row["PathTaperY"]); + s.PathTwist = Convert.ToSByte(row["PathTwist"]); + s.PathTwistBegin = Convert.ToSByte(row["PathTwistBegin"]); + // profile + s.ProfileBegin = Convert.ToUInt16(row["ProfileBegin"]); + s.ProfileEnd = Convert.ToUInt16(row["ProfileEnd"]); + s.ProfileCurve = Convert.ToByte(row["ProfileCurve"]); + s.ProfileHollow = Convert.ToByte(row["ProfileHollow"]); + // text TODO: this isn't right] = but I'm not sure the right + // way to specify this as a blob atm + // s.TextureEntry = (byte[])row["Texture"]; + + string texture = (string)row["Texture"]; + if (!texture.StartsWith("<")) + { + //here so that we can still work with old format database files (ie from before I added xml serialization) + LLObject.TextureEntry textureEntry = null; + textureEntry = new LLObject.TextureEntry(new LLUUID(texture)); + s.TextureEntry = textureEntry.ToBytes(); + } + else + { + TextureBlock textureEntry = TextureBlock.FromXmlString(texture); + s.TextureEntry = textureEntry.TextureData; + s.ExtraParams = textureEntry.ExtraParams; + } + + return s; + } + + private void fillShapeRow(DataRow row, SceneObjectPart prim) + { + PrimitiveBaseShape s = prim.Shape; + row["UUID"] = prim.UUID; + // shape is an enum + row["Shape"] = 0; + // vectors + row["ScaleX"] = s.Scale.X; + row["ScaleY"] = s.Scale.Y; + row["ScaleZ"] = s.Scale.Z; + // paths + row["PCode"] = s.PCode; + row["PathBegin"] = s.PathBegin; + row["PathEnd"] = s.PathEnd; + row["PathScaleX"] = s.PathScaleX; + row["PathScaleY"] = s.PathScaleY; + row["PathShearX"] = s.PathShearX; + row["PathShearY"] = s.PathShearY; + row["PathSkew"] = s.PathSkew; + row["PathCurve"] = s.PathCurve; + row["PathRadiusOffset"] = s.PathRadiusOffset; + row["PathRevolutions"] = s.PathRevolutions; + row["PathTaperX"] = s.PathTaperX; + row["PathTaperY"] = s.PathTaperY; + row["PathTwist"] = s.PathTwist; + row["PathTwistBegin"] = s.PathTwistBegin; + // profile + row["ProfileBegin"] = s.ProfileBegin; + row["ProfileEnd"] = s.ProfileEnd; + row["ProfileCurve"] = s.ProfileCurve; + row["ProfileHollow"] = s.ProfileHollow; + // text TODO: this isn't right] = but I'm not sure the right + // way to specify this as a blob atm + + // And I couldn't work out how to save binary data either + // seems that the texture colum is being treated as a string in the Datarow + // if you do a .getType() on it, it returns string, while the other columns return correct type + // MW[10-08-07] + // Added following xml hack but not really ideal , also ExtraParams isn't currently part of the database + // am a bit worried about adding it now as some people will have old format databases, so for now including that data in this xml data + // MW[17-08-07] + TextureBlock textureBlock = new TextureBlock(s.TextureEntry); + textureBlock.ExtraParams = s.ExtraParams; + row["Texture"] = textureBlock.ToXMLString(); + } + + private void addPrim(SceneObjectPart prim, LLUUID sceneGroupID) + { + DataTable prims = ds.Tables["prims"]; + DataTable shapes = ds.Tables["primshapes"]; + + DataRow primRow = prims.Rows.Find(prim.UUID); + if (primRow == null) + { + primRow = prims.NewRow(); + fillPrimRow(primRow, prim, sceneGroupID); + prims.Rows.Add(primRow); + } + else + { + fillPrimRow(primRow, prim, sceneGroupID); + } + + DataRow shapeRow = shapes.Rows.Find(prim.UUID); + if (shapeRow == null) + { + shapeRow = shapes.NewRow(); + fillShapeRow(shapeRow, prim); + shapes.Rows.Add(shapeRow); + } + else + { + fillShapeRow(shapeRow, prim); + } + } + + public void StoreObject(SceneObjectGroup obj) + { + foreach (SceneObjectPart prim in obj.Children.Values) + { + addPrim(prim, obj.UUID); + } + + // MainLog.Instance.Verbose("Attempting to do database update...."); + primDa.Update(ds, "prims"); + shapeDa.Update(ds, "primshapes"); + // MainLog.Instance.Verbose("Dump of prims:", ds.GetXml()); + } + + public void RemoveObject(LLUUID obj) + { + DataTable prims = ds.Tables["prims"]; + DataTable shapes = ds.Tables["primshapes"]; + + string selectExp = "SceneGroupID = '" + obj.ToString() + "'"; + DataRow[] primRows = prims.Select(selectExp); + foreach (DataRow row in primRows) + { + LLUUID uuid = new LLUUID((string)row["UUID"]); + DataRow shapeRow = shapes.Rows.Find(uuid); + if (shapeRow != null) + { + shapeRow.Delete(); + } + row.Delete(); + } + + primDa.Update(ds, "prims"); + shapeDa.Update(ds, "primshapes"); + } + + public List LoadObjects() + { + Dictionary createdObjects = new Dictionary(); + List retvals = new List(); + + DataTable prims = ds.Tables["prims"]; + DataTable shapes = ds.Tables["primshapes"]; + + foreach (DataRow primRow in prims.Rows) + { + string uuid = (string)primRow["UUID"]; + string objID = (string)primRow["SceneGroupID"]; + if (uuid == objID) //is new SceneObjectGroup ? + { + SceneObjectGroup group = new SceneObjectGroup(); + SceneObjectPart prim = buildPrim(primRow); + DataRow shapeRow = shapes.Rows.Find(prim.UUID); + if (shapeRow != null) + { + prim.Shape = buildShape(shapeRow); + } + else + { + Console.WriteLine("No shape found for prim in storage, so setting default box shape"); + prim.Shape = BoxShape.Default; + } + group.AddPart(prim); + group.RootPart = prim; + + createdObjects.Add(group.UUID, group); + retvals.Add(group); + } + else + { + SceneObjectPart prim = buildPrim(primRow); + DataRow shapeRow = shapes.Rows.Find(prim.UUID); + if (shapeRow != null) + { + prim.Shape = buildShape(shapeRow); + } + else + { + Console.WriteLine("No shape found for prim in storage, so setting default box shape"); + prim.Shape = BoxShape.Default; + } + createdObjects[new LLUUID(objID)].AddPart(prim); + } + } + + MainLog.Instance.Verbose("DATASTORE", "Sqlite - LoadObjects found " + prims.Rows.Count + " primitives"); + + return retvals; + } + + public void StoreTerrain(double[,] ter) + { + + } + + public double[,] LoadTerrain() + { + return null; + } + + public void RemoveLandObject(uint id) + { + + } + + public void StoreParcel(Land parcel) + { + + } + + public List LoadLandObjects() + { + return new List(); + } + + public void Shutdown() + { + // TODO: DataSet commit + } + + public class TextureBlock + { + public byte[] TextureData; + public byte[] ExtraParams = new byte[1]; + + public TextureBlock(byte[] data) + { + TextureData = data; + } + + public TextureBlock() + { + + } + + public string ToXMLString() + { + StringWriter sw = new StringWriter(); + XmlTextWriter writer = new XmlTextWriter(sw); + XmlSerializer serializer = new XmlSerializer(typeof(TextureBlock)); + serializer.Serialize(writer, this); + return sw.ToString(); + } + + public static TextureBlock FromXmlString(string xmlData) + { + TextureBlock textureEntry = null; + StringReader sr = new StringReader(xmlData); + XmlTextReader reader = new XmlTextReader(sr); + XmlSerializer serializer = new XmlSerializer(typeof(TextureBlock)); + textureEntry = (TextureBlock)serializer.Deserialize(reader); + reader.Close(); + sr.Close(); + return textureEntry; + } + } + } +} diff --git a/OpenSim/Region/Storage/OpenSim.DataStore.NullStorage/NullDataStore.cs b/OpenSim/Region/Storage/OpenSim.DataStore.NullStorage/NullDataStore.cs new file mode 100644 index 0000000000..e0ba653324 --- /dev/null +++ b/OpenSim/Region/Storage/OpenSim.DataStore.NullStorage/NullDataStore.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Text; + +using OpenSim.Region.Environment.Scenes; +using OpenSim.Region.Environment.LandManagement; +using OpenSim.Region.Interfaces; +using OpenSim.Framework.Console; +using libsecondlife; + +namespace OpenSim.DataStore.NullStorage +{ + public class NullDataStore : IRegionDataStore + { + + public void Initialise(string dbfile, string dbname) + { + return; + } + + public void StoreObject(SceneObjectGroup obj) + { + + } + + public void RemoveObject(LLUUID obj) + { + + } + + public List LoadObjects() + { + return new List(); + } + + public void StoreTerrain(double[,] ter) + { + + } + + public double[,] LoadTerrain() + { + return null; + } + + public void RemoveLandObject(uint id) + { + + } + + public void StoreParcel(Land land) + { + + } + + public List LoadLandObjects() + { + return new List(); + } + + public void Shutdown() + { + + } + } +} diff --git a/OpenSim/Region/Storage/OpenSim.DataStore.NullStorage/Properties/AssemblyInfo.cs b/OpenSim/Region/Storage/OpenSim.DataStore.NullStorage/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..c0bd46d2c3 --- /dev/null +++ b/OpenSim/Region/Storage/OpenSim.DataStore.NullStorage/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.DataStore.NullStorage")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OpenSim.DataStore.NullStorage")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("b4a1656d-de22-4080-a970-fd8166acbf16")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/Terrain.BasicTerrain/Properties/AssemblyInfo.cs b/OpenSim/Region/Terrain.BasicTerrain/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..9c721d16fb --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/Properties/AssemblyInfo.cs @@ -0,0 +1,60 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Reflection; +using System.Runtime.InteropServices; +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenSim.Region.Terrain.BasicTerrain")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OpenSim.Region.Terrain.BasicTerrain")] +[assembly: AssemblyCopyright("Copyright © 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("3263f5b5-0a41-4ed5-91a2-9baaaeecc849")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Region/Terrain.BasicTerrain/TerrainEngine.cs b/OpenSim/Region/Terrain.BasicTerrain/TerrainEngine.cs new file mode 100644 index 0000000000..6a8254d335 --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/TerrainEngine.cs @@ -0,0 +1,1172 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Drawing; +using System.Drawing.Imaging; +using System.IO; +using libTerrain; +using OpenJPEGNet; + +namespace OpenSim.Region.Terrain +{ + public class TerrainCommand + { + public virtual bool run(string[] cmdargs, ref string output) + { + return false; + } + + public string args; + public string help; + } + + public class TerrainEngine + { + /// + /// Plugin library for scripts + /// + public FilterHost customFilters = new FilterHost(); + + /// + /// A [normally] 256x256 heightmap + /// + public Channel heightmap; + + /// + /// A copy of heightmap at the last save point (for reverting) + /// + public Channel revertmap; + + /// + /// Water heightmap (needs clientside mods to work) + /// + public Channel watermap; + + /// + /// Max amount the terrain can be raised from the revert parameters + /// + public double maxRaise = 500.0; + + /// + /// Min amount the terrain can be lowered from the revert parameters + /// + public double minLower = 500.0; + + + /// + /// Whether or not the terrain has been modified since it was last saved and sent to the Physics engine. + /// Counts the number of modifications since the last save. (0 = Untainted) + /// + public int tainted; + + int w, h; + + /// + /// Used to determine what offset to use when loading singular heightmaps across multiple sims + /// + private int offsetX; + private int offsetY; + + + /// + /// Generate a new TerrainEngine instance and creates a new heightmap + /// + public TerrainEngine(int X, int Y) + { + w = 256; + h = 256; + heightmap = new Channel(w, h); + revertmap = new Channel(w, h); + watermap = new Channel(w, h); + watermap.Fill(20); + + offsetX = X; + offsetY = Y; + + tainted++; + } + + public bool Tainted() + { + return (tainted != 0); + } + + public bool Tainted(int x, int y) + { + return (heightmap.diff[x / 16, y / 16] != 0); + } + + public void ResetTaint() + { + tainted = 0; + heightmap.diff = new int[w / 16, h / 16]; + } + + /// + /// Checks to make sure the terrain is within baked values +/- maxRaise/minLower + /// + public void CheckHeightValues() + { + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + if ((heightmap.Get(x, y) > revertmap.Get(x, y) + maxRaise)) + { + heightmap.map[x, y] = revertmap.Get(x, y) + maxRaise; + } + if ((heightmap.Get(x, y) > revertmap.Get(x, y) - minLower)) + { + heightmap.map[x, y] = revertmap.Get(x, y) - minLower; + } + } + } + } + + + /// + /// Converts the heightmap to a 65536 value 1D floating point array + /// + /// A float[65536] array containing the heightmap + public float[] GetHeights1D() + { + float[] heights = new float[w * h]; + int i; + + for (i = 0; i < w * h; i++) + { + heights[i] = (float)heightmap.map[i % w, i / w]; + } + + return heights; + } + + /// + /// Converts the heightmap to a 256x256 value 2D floating point array. + /// + /// An array of 256,256 values containing the heightmap + public float[,] GetHeights2D() + { + float[,] heights = new float[w, h]; + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + heights[x, y] = (float)heightmap.map[x, y]; + } + } + return heights; + } + + /// + /// Converts the heightmap to a 256x256 value 2D floating point array. Double precision version. + /// + /// An array of 256,256 values containing the heightmap + public double[,] GetHeights2DD() + { + return heightmap.map; + } + + /// + /// Imports a 1D floating point array into the 2D heightmap array + /// + /// The array to import (must have 65536 members) + public void GetHeights1D(float[] heights) + { + int i; + for (i = 0; i < w * h; i++) + { + heightmap.map[i % w, i / w] = heights[i]; + } + + tainted++; + } + + /// + /// Loads a 2D array of values into the heightmap + /// + /// An array of 256,256 float values + public void SetHeights2D(float[,] heights) + { + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + heightmap.Set(x, y, (double)heights[x, y]); + } + } + SaveRevertMap(); + tainted++; + } + + /// + /// Loads a 2D array of values into the heightmap (Double Precision Version) + /// + /// An array of 256,256 float values + public void SetHeights2D(double[,] heights) + { + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + heightmap.Set(x, y, heights[x, y]); + } + } + SaveRevertMap(); + tainted++; + } + + /// + /// Swaps the two heightmap buffers (the 'revert map' and the heightmap) + /// + public void SwapRevertMaps() + { + Channel backup = heightmap.Copy(); + heightmap = revertmap; + revertmap = backup; + } + + /// + /// Saves the current heightmap into the revertmap + /// + public void SaveRevertMap() + { + revertmap = heightmap.Copy(); + } + + /// + /// Processes a terrain-specific command + /// + /// Commandline arguments (space seperated) + /// Reference that returns error or help text if returning false + /// If the operation was successful (if not, the error is placed into resultText) + public bool RunTerrainCmd(string[] args, ref string resultText, string simName) + { + string command; + if (args.Length > 0) + { + command = args[0]; + } + else + { + command = "help"; + } + + try + { + + switch (command) + { + case "help": + resultText += "terrain regenerate - rebuilds the sims terrain using a default algorithm\n"; + resultText += "terrain hills \n"; + resultText += " type should be spheres, blocks, cones, or squared\n"; + resultText += "terrain voronoi - generates a worley fractal with X points per block"; + resultText += "terrain seed - sets the random seed value to \n"; + resultText += "terrain load - loads a terrain from disk, type can be 'F32', 'F64', 'RAW' or 'IMG'\n"; + resultText += "terrain save - saves a terrain to disk, type can be 'F32', 'F64', 'PNG', 'RAW' or 'HIRAW'\n"; + resultText += "terrain save grdmap - creates a PNG snapshot of the region using a named gradient map\n"; + resultText += "terrain rescale - rescales a terrain to be between and meters high\n"; + resultText += "terrain fill - fills a terrain at the specified height\n"; + resultText += "terrain erode aerobic \n"; + resultText += "terrain erode thermal \n"; + resultText += "terrain erode hydraulic \n"; + resultText += "terrain multiply - multiplies a terrain by \n"; + resultText += "terrain revert - reverts the terrain to the stored original\n"; + resultText += "terrain bake - saves the current terrain into the revert map\n"; + resultText += "terrain csfilter - loads a new filter from the specified .cs file\n"; + resultText += "terrain jsfilter - loads a new filter from the specified .js file\n"; + foreach (KeyValuePair filter in customFilters.filters) + { + resultText += filter.Value.Help(); + } + + return false; + + case "revert": + SwapRevertMaps(); + SaveRevertMap(); + break; + + case "bake": + SaveRevertMap(); + break; + + case "seed": + SetSeed(Convert.ToInt32(args[1])); + break; + + case "erode": + return ConsoleErosion(args, ref resultText); + + case "voronoi": + double[] c = new double[2]; + c[0] = -1; + c[1] = 1; + heightmap.VoronoiDiagram(Convert.ToInt32(args[1]), Convert.ToInt32(args[2]), c); + break; + + case "hills": + return ConsoleHills(args, ref resultText); + + case "regenerate": + HillsGenerator(); + break; + + case "rescale": + SetRange(Convert.ToSingle(args[1]), Convert.ToSingle(args[2])); + break; + + case "fill": + heightmap.Fill(Convert.ToDouble(args[1])); + tainted++; + break; + + case "clip": + heightmap.Clip(Convert.ToDouble(args[1]), Convert.ToDouble(args[2])); + tainted++; + break; + + case "smooth": + heightmap.Smooth(Convert.ToDouble(args[1])); + tainted++; + break; + + case "add": + heightmap += Convert.ToDouble(args[1]); + tainted++; + break; + + case "multiply": + heightmap *= Convert.ToDouble(args[1]); + tainted++; + break; + + case "load": + string filenameL = args[2].Replace("%name%", simName); + filenameL = filenameL.Replace("%x%", this.offsetX.ToString()); + filenameL = filenameL.Replace("%y%", this.offsetY.ToString()); + + switch (args[1].ToLower()) + { + case "f32": + LoadFromFileF32(filenameL); + break; + + case "f64": + LoadFromFileF64(filenameL); + break; + + case "raw": + LoadFromFileSLRAW(filenameL); + break; + + case "img": + heightmap.LoadImage(filenameL); + break; + + default: + resultText = "Unknown image or data format"; + return false; + } + break; + + case "load-tile": + switch (args[1].ToLower()) + { + case "f32": + LoadFromFileF32(args[2], Convert.ToInt32(args[3]), Convert.ToInt32(args[4]), + Convert.ToInt32(args[5]), Convert.ToInt32(args[6])); + break; + case "img": + LoadFromFileIMG(args[2], Convert.ToInt32(args[3]), Convert.ToInt32(args[4]), + Convert.ToInt32(args[5]), Convert.ToInt32(args[6])); + break; + default: + resultText = "Unknown or unsupported image or data format"; + return false; + } + break; + + case "save": + string filename = args[2].Replace("%name%", simName); + filename = filename.Replace("%x%", this.offsetX.ToString()); + filename = filename.Replace("%y%", this.offsetY.ToString()); + + switch (args[1].ToLower()) + { + case "f32": + WriteToFileF32(filename); + break; + + case "f64": + WriteToFileF64(filename); + break; + + case "grdmap": + if (args.Length >= 4) + ExportImage(filename, args[3]); + else + ExportImage(filename, "defaultstripe.png"); + break; + + case "png": + heightmap.SaveImage(filename); + break; + + case "raw": + WriteToFileRAW(filename); + break; + + case "hiraw": + WriteToFileHiRAW(filename); + break; + + default: + resultText = "Unknown image or data format"; + return false; + } + break; + + case "csfilter": + customFilters.LoadFilterCSharp(args[1]); + break; + case "jsfilter": + customFilters.LoadFilterJScript(args[1]); + break; + + default: + // Run any custom registered filters + if (customFilters.filters.ContainsKey(command)) + { + customFilters.filters[command].Filter(heightmap, args); + break; + } + else + { + resultText = "Unknown terrain command"; + return false; + } + } + return true; + } + catch (Exception e) + { + resultText = "Error running terrain command: " + e.ToString(); + return false; + } + } + + private bool ConsoleErosion(string[] args, ref string resultText) + { + double min = heightmap.FindMin(); + double max = heightmap.FindMax(); + + switch (args[1].ToLower()) + { + case "aerobic": + // WindSpeed, PickupMinimum,DropMinimum,Carry,Rounds,Lowest + heightmap.AerobicErosion(Convert.ToDouble(args[2]), Convert.ToDouble(args[3]), Convert.ToDouble(args[4]), Convert.ToDouble(args[5]), Convert.ToInt32(args[6]), Convert.ToBoolean(args[7]), Convert.ToBoolean(args[8])); + break; + case "thermal": + heightmap.ThermalWeathering(Convert.ToDouble(args[2]), Convert.ToInt32(args[3]), Convert.ToDouble(args[4])); + break; + case "hydraulic": + Channel rainMap = new Channel(w, h); + rainMap.Fill(Convert.ToDouble(args[2])); + heightmap.HydraulicErosion(rainMap, Convert.ToDouble(args[3]), Convert.ToDouble(args[4]), Convert.ToInt32(args[5]), Convert.ToInt32(args[6])); + break; + default: + resultText = "Unknown erosion type"; + return false; + } + + heightmap.Normalise(min, max); + + tainted++; + return true; + } + + private bool ConsoleHills(string[] args, ref string resultText) + { + Random RandomClass = new Random(); + SetSeed(RandomClass.Next()); + int count; + double sizeMin; + double sizeRange; + bool island; + bool additive; + bool noisy; + + if (args.GetLength(0) > 2) + { + int.TryParse(args[2].ToString(), out count); + double.TryParse(args[3].ToString(), out sizeMin); + double.TryParse(args[4].ToString(), out sizeRange); + bool.TryParse(args[5].ToString(), out island); + bool.TryParse(args[6].ToString(), out additive); + bool.TryParse(args[7].ToString(), out noisy); + } + else + { + count = 200; + sizeMin = 20; + sizeRange = 40; + island = true; + additive = true; + noisy = false; + } + + switch (args[1].ToLower()) + { + case "blocks": + heightmap.HillsBlocks(count, sizeMin, sizeRange, island, additive, noisy); + break; + case "cones": + heightmap.HillsCones(count, sizeMin, sizeRange, island, additive, noisy); + break; + case "spheres": + heightmap.HillsSpheres(count, sizeMin, sizeRange, island, additive, noisy); + break; + case "squared": + heightmap.HillsSquared(count, sizeMin, sizeRange, island, additive, noisy); + break; + default: + resultText = "Unknown hills type"; + return false; + } + tainted++; + return true; + } + + /// + /// Renormalises the array between min and max + /// + /// Minimum value of the new array + /// Maximum value of the new array + public void SetRange(float min, float max) + { + heightmap.Normalise((double)min, (double)max); + tainted++; + } + + /// + /// Loads a file consisting of 256x256 doubles and imports it as an array into the map. + /// + /// TODO: Move this to libTerrain itself + /// The filename of the double array to import + public void LoadFromFileF64(string filename) + { + FileInfo file = new FileInfo(filename); + FileStream s = file.Open(FileMode.Open, FileAccess.Read); + BinaryReader bs = new BinaryReader(s); + int x, y; + for (y = 0; y < h; y++) + { + for (x = 0; x < h; x++) + { + heightmap.map[x, y] = bs.ReadDouble(); + } + } + + bs.Close(); + s.Close(); + + tainted++; + } + + /// + /// Loads a file consisting of 256x256 floats and imports it as an array into the map. + /// + /// TODO: Move this to libTerrain itself + /// The filename of the float array to import + public void LoadFromFileF32(string filename) + { + FileInfo file = new FileInfo(filename); + FileStream s = file.Open(FileMode.Open, FileAccess.Read); + BinaryReader bs = new BinaryReader(s); + int x, y; + for (y = 0; y < h; y++) + { + for (x = 0; x < w; x++) + { + heightmap.map[x, y] = (double)bs.ReadSingle(); + } + } + + bs.Close(); + s.Close(); + + tainted++; + } + + /// + /// Loads a section of a larger heightmap (F32) + /// + /// File to load + /// Size of the file + /// Size of the file + /// Where do the region coords start for this terrain? + /// Where do the region coords start for this terrain? + public void LoadFromFileF32(string filename, int dimensionX, int dimensionY, int lowerboundX, int lowerboundY) + { + int sectionToLoadX = ((this.offsetX - lowerboundX) * this.w); + int sectionToLoadY = ((this.offsetY - lowerboundY) * this.h); + + double[,] tempMap = new double[dimensionX, dimensionY]; + + FileInfo file = new FileInfo(filename); + FileStream s = file.Open(FileMode.Open, FileAccess.Read); + BinaryReader bs = new BinaryReader(s); + + int x, y; + for (x = 0; x < dimensionX; x++) + { + for (y = 0; y < dimensionY; y++) + { + tempMap[x,y] = (double)bs.ReadSingle(); + } + } + + for (y = 0; y < h; y++) + { + for (x = 0; x < w; x++) + { + heightmap.Set(x, y, tempMap[x + sectionToLoadX, y + sectionToLoadY]); + } + } + + bs.Close(); + s.Close(); + + tainted++; + } + + /// + /// Loads a larger tiled image across a terrain + /// + /// Filename to load from (any generic image format should work) + /// The dimensions of the image + /// The dimensions of the image + /// Where sim coords begin for this patch + /// Where sim coords begin for this patch + public void LoadFromFileIMG(string filename, int dimensionX, int dimensionY, int lowerboundX, int lowerboundY) + { + int sectionToLoadX = ((this.offsetX - lowerboundX) * this.w); + int sectionToLoadY = ((this.offsetY - lowerboundY) * this.h); + + double[,] tempMap = new double[dimensionX, dimensionY]; + + System.Drawing.Bitmap lgrBmp = new Bitmap(filename); + + int x, y; + for (x = 0; x < dimensionX; x++) + { + for (y = 0; y < dimensionY; y++) + { + tempMap[x, y] = (float)lgrBmp.GetPixel(x, y).GetBrightness(); + } + } + + for (y = 0; y < h; y++) + { + for (x = 0; x < w; x++) + { + heightmap.Set(x, y, tempMap[x + sectionToLoadX, y + sectionToLoadY]); + } + } + + tainted++; + } + + /// + /// Loads a file formatted in the SL .RAW Format used on the main grid + /// + /// This file format stinks and is best avoided. + /// A path to the .RAW format + public void LoadFromFileSLRAW(string filename) + { + FileInfo file = new FileInfo(filename); + FileStream s = file.Open(FileMode.Open, FileAccess.Read); + BinaryReader bs = new BinaryReader(s); + int x, y; + for (y = 0; y < h; y++) + { + for (x = 0; x < w; x++) + { + heightmap.map[x, y] = (double)bs.ReadByte() * ((double)bs.ReadByte() / 127.0); + bs.ReadBytes(11); // Advance the stream to next bytes. + } + } + + bs.Close(); + s.Close(); + + tainted++; + } + + /// + /// Writes the current terrain heightmap to disk, in the format of a 65536 entry double[] array. + /// + /// The desired output filename + public void WriteToFileF64(string filename) + { + FileInfo file = new FileInfo(filename); + FileStream s = file.Open(FileMode.CreateNew, FileAccess.Write); + BinaryWriter bs = new BinaryWriter(s); + + int x, y; + for (y = 0; y < h; y++) + { + for (x = 0; x < w; x++) + { + bs.Write(heightmap.Get(x, y)); + } + } + + bs.Close(); + s.Close(); + } + + /// + /// Writes the current terrain heightmap to disk, in the format of a 65536 entry float[] array + /// + /// The desired output filename + public void WriteToFileF32(string filename) + { + FileInfo file = new FileInfo(filename); + FileStream s = file.Open(FileMode.CreateNew, FileAccess.Write); + BinaryWriter bs = new BinaryWriter(s); + + int x, y; + for (y = 0; y < h; y++) + { + for (x = 0; x < w; x++) + { + bs.Write((float)heightmap.Get(x, y)); + } + } + + bs.Close(); + s.Close(); + } + + /// + /// A very fast LL-RAW file output mechanism - lower precision mechanism but wont take 5 minutes to run either. + /// (is also editable in an image application) + /// + /// Filename to write to + public void WriteToFileRAW(string filename) + { + FileInfo file = new FileInfo(filename); + FileStream s = file.Open(FileMode.CreateNew, FileAccess.Write); + BinaryWriter binStream = new BinaryWriter(s); + + int x, y; + + // Used for the 'green' channel. + byte avgMultiplier = (byte)heightmap.Avg(); + byte backupMultiplier = (byte)revertmap.Avg(); + + // Limit the multiplier so it can represent points >64m. + if (avgMultiplier > 196) + avgMultiplier = 196; + if(backupMultiplier > 196) + backupMultiplier = 196; + // Make sure it's at least one to prevent a div by zero + if (avgMultiplier < 1) + avgMultiplier = 1; + if(backupMultiplier < 1) + backupMultiplier = 1; + + for (y = 0; y < h; y++) + { + for (x = 0; x < h; x++) + { + byte red = (byte)(heightmap.Get(x, y) / ((double)avgMultiplier / 128.0)); + byte green = avgMultiplier; + byte blue = (byte)watermap.Get(x, y); + byte alpha1 = 0; // Land Parcels + byte alpha2 = 0; // For Sale Land + byte alpha3 = 0; // Public Edit Object + byte alpha4 = 0; // Public Edit Land + byte alpha5 = 255; // Safe Land + byte alpha6 = 255; // Flying Allowed + byte alpha7 = 255; // Create Landmark + byte alpha8 = 255; // Outside Scripts + byte alpha9 = (byte)(revertmap.Get(x, y) / ((double)backupMultiplier / 128.0)); + byte alpha10 = backupMultiplier; + + binStream.Write(red); + binStream.Write(green); + binStream.Write(blue); + binStream.Write(alpha1); + binStream.Write(alpha2); + binStream.Write(alpha3); + binStream.Write(alpha4); + binStream.Write(alpha5); + binStream.Write(alpha6); + binStream.Write(alpha7); + binStream.Write(alpha8); + binStream.Write(alpha9); + binStream.Write(alpha10); + } + } + binStream.Close(); + s.Close(); + } + + /// + /// Outputs to a LL compatible RAW in the most efficient manner possible + /// + /// Does not calculate the revert map + /// The filename to output to + public void WriteToFileHiRAW(string filename) + { + FileInfo file = new FileInfo(filename); + FileStream s = file.Open(FileMode.CreateNew, FileAccess.Write); + BinaryWriter binStream = new BinaryWriter(s); + + // Generate a smegging big lookup table to speed the operation up (it needs it) + double[] lookupHeightTable = new double[65536]; + int i, j, x, y; + for (i = 0; i < 256; i++) + { + for (j = 0; j < 256; j++) + { + lookupHeightTable[i + (j * 256)] = ((double)i * ((double)j / 127.0)); + } + } + + // Output the calculated raw + for (y = 0; y < h; y++) + { + for (x = 0; x < w; x++) + { + double t = heightmap.Get(x, y); + double min = double.MaxValue; + int index = 0; + + for (i = 0; i < 65536; i++) + { + if (Math.Abs(t - lookupHeightTable[i]) < min) + { + min = Math.Abs(t - lookupHeightTable[i]); + index = i; + } + } + + byte red = (byte)(index & 0xFF); + byte green = (byte)((index >> 8) & 0xFF); + byte blue = (byte)watermap.Get(x, y); + byte alpha1 = 0; // Land Parcels + byte alpha2 = 0; // For Sale Land + byte alpha3 = 0; // Public Edit Object + byte alpha4 = 0; // Public Edit Land + byte alpha5 = 255; // Safe Land + byte alpha6 = 255; // Flying Allowed + byte alpha7 = 255; // Create Landmark + byte alpha8 = 255; // Outside Scripts + byte alpha9 = red; + byte alpha10 = green; + + binStream.Write(red); + binStream.Write(green); + binStream.Write(blue); + binStream.Write(alpha1); + binStream.Write(alpha2); + binStream.Write(alpha3); + binStream.Write(alpha4); + binStream.Write(alpha5); + binStream.Write(alpha6); + binStream.Write(alpha7); + binStream.Write(alpha8); + binStream.Write(alpha9); + binStream.Write(alpha10); + } + } + + binStream.Close(); + s.Close(); + } + + /// + /// Sets the random seed to be used by procedural functions which involve random numbers. + /// + /// The desired seed + public void SetSeed(int val) + { + heightmap.seed = val; + } + + /// + /// Raises land in a sphere around the specified coordinates + /// + /// Center of the sphere on the X axis + /// Center of the sphere on the Y axis + /// The radius of the sphere + /// Scale the height of the sphere by this amount (recommended 0..2) + public void RaiseTerrain(double rx, double ry, double size, double amount) + { + lock (heightmap) + { + heightmap.Raise(rx, ry, size, amount); + } + + tainted++; + } + + /// + /// Lowers the land in a sphere around the specified coordinates + /// + /// The center of the sphere at the X axis + /// The center of the sphere at the Y axis + /// The radius of the sphere in meters + /// Scale the height of the sphere by this amount (recommended 0..2) + public void LowerTerrain(double rx, double ry, double size, double amount) + { + lock (heightmap) + { + heightmap.Lower(rx, ry, size, amount); + } + + tainted++; + } + + /// + /// Flattens the land under the brush of specified coordinates (spherical mask) + /// + /// Center of sphere + /// Center of sphere + /// Radius of the sphere + /// Thickness of the mask (0..2 recommended) + public void FlattenTerrain(double rx, double ry, double size, double amount) + { + lock (heightmap) + { + heightmap.Flatten(rx, ry, size, amount); + } + + tainted++; + } + + /// + /// Creates noise within the specified bounds + /// + /// Center of the bounding sphere + /// Center of the bounding sphere + /// The radius of the sphere + /// Strength of the mask (0..2) recommended + public void NoiseTerrain(double rx, double ry, double size, double amount) + { + lock (heightmap) + { + Channel smoothed = new Channel(); + smoothed.Noise(); + + Channel mask = new Channel(); + mask.Raise(rx, ry, size, amount); + + heightmap.Blend(smoothed, mask); + } + + tainted++; + } + + /// + /// Reverts land within the specified bounds + /// + /// Center of the bounding sphere + /// Center of the bounding sphere + /// The radius of the sphere + /// Strength of the mask (0..2) recommended + public void RevertTerrain(double rx, double ry, double size, double amount) + { + lock (heightmap) + { + Channel mask = new Channel(); + mask.Raise(rx, ry, size, amount); + + heightmap.Blend(revertmap, mask); + } + + tainted++; + } + + /// + /// Smooths land under the brush of specified coordinates (spherical mask) + /// + /// Center of the sphere + /// Center of the sphere + /// Radius of the sphere + /// Thickness of the mask (0..2 recommended) + public void SmoothTerrain(double rx, double ry, double size, double amount) + { + lock (heightmap) + { + Channel smoothed = heightmap.Copy(); + smoothed.Smooth(amount); + + Channel mask = new Channel(); + mask.Raise(rx,ry,size,amount); + + heightmap.Blend(smoothed, mask); + } + + tainted++; + } + + /// + /// Generates a simple set of hills in the shape of an island + /// + public void HillsGenerator() + { + lock (heightmap) + { + heightmap.HillsSpheres(200, 20, 40, true, true, false); + heightmap.Normalise(); + heightmap *= 60.0; // Raise to 60m + } + + tainted++; + } + + /// + /// Wrapper to heightmap.get() + /// + /// X coord + /// Y coord + /// Height at specified coordinates + public double GetHeight(int x, int y) + { + return heightmap.Get(x, y); + } + + /// + /// Multiplies the heightfield by val + /// + /// The heightfield + /// The multiplier + /// + public static TerrainEngine operator *(TerrainEngine terrain, Double val) + { + terrain.heightmap *= val; + terrain.tainted++; + return terrain; + } + + /// + /// Exports the current heightmap to a PNG file + /// + /// The destination filename for the image + /// A 1x*height* image which contains the colour gradient to export with. Must be at least 1x2 pixels, 1x256 or more is ideal. + public void ExportImage(string filename, string gradientmap) + { + try + { + Bitmap gradientmapLd = new Bitmap(gradientmap); + + int pallete = gradientmapLd.Height; + + Bitmap bmp = new Bitmap(heightmap.w, heightmap.h); + Color[] colours = new Color[pallete]; + + for (int i = 0; i < pallete; i++) + { + colours[i] = gradientmapLd.GetPixel(0, i); + } + + Channel copy = heightmap.Copy(); + for (int y = 0; y < copy.h; y++) + { + for (int x = 0; x < copy.w; x++) + { + // 512 is the largest possible height before colours clamp + int colorindex = (int)(Math.Max(Math.Min(1.0, copy.Get(x, y) / 512.0), 0.0) * (pallete - 1)); + bmp.SetPixel(x, y, colours[colorindex]); + } + } + + bmp.Save(filename, ImageFormat.Png); + } + catch (Exception e) + { + Console.WriteLine("Failed generating terrain map: " + e.ToString()); + } + } + + /// + /// Exports the current heightmap in Jpeg2000 format to a byte[] + /// + /// A 1x*height* image which contains the colour gradient to export with. Must be at least 1x2 pixels, 1x256 or more is ideal. + public byte[] ExportJpegImage(string gradientmap) + { + byte[] imageData = null; + try + { + Bitmap gradientmapLd = new Bitmap(gradientmap); + + int pallete = gradientmapLd.Height; + + Bitmap bmp = new Bitmap(heightmap.w, heightmap.h); + Color[] colours = new Color[pallete]; + + for (int i = 0; i < pallete; i++) + { + colours[i] = gradientmapLd.GetPixel(0, i); + } + + Channel copy = heightmap.Copy(); + for (int y = 0; y < copy.h; y++) + { + for (int x = 0; x < copy.w; x++) + { + // 512 is the largest possible height before colours clamp + int colorindex = (int)(Math.Max(Math.Min(1.0, copy.Get(x, copy.h - y) / 512.0), 0.0) * (pallete - 1)); + bmp.SetPixel(x, y, colours[colorindex]); + } + } + + //bmp.Save(filename, System.Drawing.Imaging.ImageFormat.Png); + imageData = OpenJPEG.EncodeFromImage(bmp, true ); + + } + catch (Exception e) + { + Console.WriteLine("Failed generating terrain map: " + e.ToString()); + } + + return imageData; + } + } +} diff --git a/OpenSim/Region/Terrain.BasicTerrain/TerrainFilter.cs b/OpenSim/Region/Terrain.BasicTerrain/TerrainFilter.cs new file mode 100644 index 0000000000..6aec9276c2 --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/TerrainFilter.cs @@ -0,0 +1,125 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.CodeDom.Compiler; +using System.Collections.Generic; +using libTerrain; +using Microsoft.CSharp; +using Microsoft.JScript; + +namespace OpenSim.Region.Terrain +{ + public interface ITerrainFilter + { + void Filter(Channel heightmap, string[] args); + string Register(); + string Help(); + } + + public class TestFilter : ITerrainFilter + { + public void Filter(Channel heightmap, string[] args) + { + Console.WriteLine("Hello world"); + } + + public string Register() + { + return "demofilter"; + } + + public string Help() + { + return "demofilter - Does nothing"; + } + } + + public class FilterHost + { + public Dictionary filters = new Dictionary(); + + private void LoadFilter(CodeDomProvider compiler, string filename) + { + CompilerParameters compilerParams = new CompilerParameters(); + CompilerResults compilerResults; + compilerParams.GenerateExecutable = false; + compilerParams.GenerateInMemory = true; + compilerParams.IncludeDebugInformation = false; + compilerParams.ReferencedAssemblies.Add("OpenSim.Terrain.BasicTerrain.dll"); + compilerParams.ReferencedAssemblies.Add("System.dll"); + + compilerResults = compiler.CompileAssemblyFromFile(compilerParams, filename); + + if (compilerResults.Errors.Count > 0) + { + Console.WriteLine("Compile errors:"); + foreach (CompilerError error in compilerResults.Errors) + { + Console.WriteLine(error.Line.ToString() + ": " + error.ErrorText.ToString()); + } + } + else + { + foreach (Type pluginType in compilerResults.CompiledAssembly.GetExportedTypes()) + { + Type testInterface = pluginType.GetInterface("ITerrainFilter",true); + + if (testInterface != null) + { + ITerrainFilter filter = (ITerrainFilter)compilerResults.CompiledAssembly.CreateInstance(pluginType.ToString()); + + string filterName = filter.Register(); + Console.WriteLine("Plugin: " + filterName + " loaded."); + + if (!filters.ContainsKey(filterName)) + { + filters.Add(filterName, filter); + } + else + { + filters[filterName] = filter; + } + } + } + } + + } + + public void LoadFilterCSharp(string filename) + { + CSharpCodeProvider compiler = new CSharpCodeProvider(); + LoadFilter(compiler, filename); + } + + public void LoadFilterJScript(string filename) + { + JScriptCodeProvider compiler = new JScriptCodeProvider(); + LoadFilter(compiler, filename); + } + } +} diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Bitmap/Bitmap.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Bitmap/Bitmap.cs new file mode 100644 index 0000000000..1ef09fc14b --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Bitmap/Bitmap.cs @@ -0,0 +1,74 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; +using System.Drawing; + +namespace libTerrain +{ + class Raster + { + int w; + int h; + Bitmap bmp; + + public Raster(int width, int height) + { + w = width; + h = height; + bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format24bppRgb); + } + + public Channel ToChannel() + { + Channel chan = new Channel(bmp.Width, bmp.Height); + + int x, y; + for (x = 0; x < bmp.Width; x++) + { + for (y = 0; y < bmp.Height; y++) + { + Color val = bmp.GetPixel(x, y); + chan.map[x, y] = (((double)val.R + (double)val.G + (double)val.B) / 3.0) / 255.0; + } + } + + return chan; + } + + public void DrawText(string txt, string font, double size) + { + Graphics gd = Graphics.FromImage(bmp); + //gd.DrawString(txt, + + + } + } +} diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Channel.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Channel.cs new file mode 100644 index 0000000000..6dfee1fb94 --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Channel.cs @@ -0,0 +1,66 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + + +/* Channel + * A channel is a single heightmap array + * */ + +namespace libTerrain +{ + partial class Channel + { + public double[,] map; + public int[,] diff; + public int w; + public int h; + + public int seed = 1338; // One better than 1337 + + public Channel() + { + w = 256; + h = 256; + map = new double[w, h]; + diff = new int[(int)(w / 16), (int)(h / 16)]; + } + + public Channel(int width, int height) + { + w = width; + h = height; + map = new double[w, h]; + diff = new int[(int)(w / 16), (int)(h / 16)]; + } + + } +} diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Common.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Common.cs new file mode 100644 index 0000000000..1750418d1d --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Common.cs @@ -0,0 +1,277 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace libTerrain +{ + public partial class Channel + { + public int GetWidth() + { + return w; + } + public int GetHeight() + { + return h; + } + + public Channel Copy() + { + Channel x = new Channel(w, h); + x.map = (double[,])this.map.Clone(); + return x; + } + + public void SetDiff() + { + SetDiff(1); + } + + public void SetDiff(int val) + { + for (int x = 0; x < w / 16; x++) + { + for (int y = 0; y < h / 16; y++) + { + diff[x, y] = val; + } + } + } + + public void SetDiff(int x, int y) + { + diff[x / 16, y / 16]++; + } + + public void Set(int x, int y, double val) + { + if (x >= w) + throw new Exception("Bounds error while setting pixel (width)"); + if (y >= h) + throw new Exception("Bounds error while setting pixel (height)"); + if (x < 0) + throw new Exception("Bounds error while setting pixel (width)"); + if (y < 0) + throw new Exception("Bounds error while setting pixel (height)"); + + if (map[x, y] != val) + { + SetDiff(x, y); + + map[x, y] = val; + } + } + + public void SetClip(int x, int y, double val) + { + SetDiff(x, y); + + if (x >= w) + throw new Exception("Bounds error while setting pixel (width)"); + if (y >= h) + throw new Exception("Bounds error while setting pixel (height)"); + if (x < 0) + throw new Exception("Bounds error while setting pixel (width)"); + if (y < 0) + throw new Exception("Bounds error while setting pixel (height)"); + + if (val > 1.0) + val = 1.0; + if (val < 0.0) + val = 0.0; + + map[x, y] = val; + } + + private double GetBilinearInterpolate(double x, double y) + { + if (x > w - 2.0) + x = w - 2.0; + if (y > h - 2.0) + y = h - 2.0; + if (x < 0.0) + x = 0.0; + if (y < 0.0) + y = 0.0; + + int stepSize = 1; + double h00 = Get((int)x, (int)y); + double h10 = Get((int)x + stepSize, (int)y); + double h01 = Get((int)x, (int)y + stepSize); + double h11 = Get((int)x + stepSize, (int)y + stepSize); + double h1 = h00; + double h2 = h10; + double h3 = h01; + double h4 = h11; + double a00 = h1; + double a10 = h2 - h1; + double a01 = h3 - h1; + double a11 = h1 - h2 - h3 + h4; + double partialx = x - (int)x; + double partialz = y - (int)y; + double hi = a00 + (a10 * partialx) + (a01 * partialz) + (a11 * partialx * partialz); + return hi; + } + + public double Get(int x, int y) + { + if (x >= w) + x = w - 1; + if (y >= h) + y = h - 1; + if (x < 0) + x = 0; + if (y < 0) + y = 0; + return map[x, y]; + } + + public void SetWrap(int x, int y, double val) + { + SetDiff(x, y); + + map[x % w, y % h] = val; + } + + public void SetWrapClip(int x, int y, double val) + { + SetDiff(x, y); + + if (val > 1.0) + val = 1.0; + if (val < 0.0) + val = 0.0; + + map[x % w, y % h] = val; + } + + public void Fill(double val) + { + SetDiff(); + + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + map[x, y] = val; + } + } + } + + public void Fill(double min, double max, double val) + { + SetDiff(); + + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + if (map[x, y] >= min && map[x, y] <= max) + map[x, y] = val; + } + } + } + + public double FindMax() + { + int x, y; + double max = double.MinValue; + + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + if (map[x, y] > max) + max = map[x, y]; + } + } + + return max; + } + + public double FindMin() + { + int x, y; + double min = double.MaxValue; + + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + if (map[x, y] < min) + min = map[x, y]; + } + } + + return min; + } + + public double Sum() + { + int x, y; + double sum = 0.0; + + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + sum += map[x, y]; + } + } + + return sum; + } + + public double Avg() + { + return Sum() / (w * h); + } + + public bool ContainsNaN() + { + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + double elm = map[x, y]; + + if (Double.IsNaN(elm)) + return true; + } + } + return false; + } + } +} diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Editing/Flatten.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Editing/Flatten.cs new file mode 100644 index 0000000000..48f02e80f0 --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Editing/Flatten.cs @@ -0,0 +1,149 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace libTerrain +{ + partial class Channel + { + /// + /// Flattens the area underneath rx,ry by moving it to the average of the area. Uses a spherical mask provided by the raise() function. + /// + /// The X coordinate of the terrain mask + /// The Y coordinate of the terrain mask + /// The size of the terrain mask + /// The scale of the terrain mask + public void Flatten(double rx, double ry, double size, double amount) + { + FlattenSlow(rx, ry, size, amount); + } + + private void FlattenSlow(double rx, double ry, double size, double amount) + { + // Generate the mask + Channel temp = new Channel(w, h); + temp.Fill(0); + temp.Raise(rx, ry, size, amount); + temp.Normalise(); + double total_mod = temp.Sum(); + + // Establish the average height under the area + Channel newmap = new Channel(w, h); + newmap.map = (double[,])map.Clone(); + + newmap *= temp; + + double total_terrain = newmap.Sum(); + double avg_height = total_terrain / total_mod; + + // Create a flat terrain using the average height + Channel flat = new Channel(w, h); + flat.Fill(avg_height); + + // Blend the current terrain with the average height terrain + // using the "raised" empty terrain as a mask + Blend(flat, temp); + + } + + private void FlattenFast(double rx, double ry, double size, double amount) + { + int x, y; + double avg = 0; + double div = 0; + + int minX = Math.Max(0, (int)(rx - (size + 1))); + int maxX = Math.Min(w, (int)(rx + (size + 1))); + int minY = Math.Max(0, (int)(ry - (size + 1))); + int maxY = Math.Min(h, (int)(ry + (size + 1))); + + for (x = minX; x < maxX; x++) + { + for (y = minY; y < maxY; y++) + { + double z = size; + z *= z; + z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); + + if (z < 0) + z = 0; + + avg += z * amount; + div += z; + } + } + + double height = avg / div; + + for (x = minX; x < maxX; x++) + { + for (y = minY; y < maxY; y++) + { + double z = size; + z *= z; + z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); + + if (z < 0) + z = 0; + + Set(x, y, Tools.linearInterpolate(map[x, y], height, z)); + } + } + } + + public void Flatten(Channel mask, double amount) + { + // Generate the mask + Channel temp = mask * amount; + temp.Clip(0, 1); // Cut off out-of-bounds values + + double total_mod = temp.Sum(); + + // Establish the average height under the area + Channel map = new Channel(w, h); + map.map = (double[,])this.map.Clone(); + + map *= temp; + + double total_terrain = map.Sum(); + double avg_height = total_terrain / total_mod; + + // Create a flat terrain using the average height + Channel flat = new Channel(w, h); + flat.Fill(avg_height); + + // Blend the current terrain with the average height terrain + // using the "raised" empty terrain as a mask + Blend(flat, temp); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Editing/Raise.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Editing/Raise.cs new file mode 100644 index 0000000000..1d04a4f7a8 --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Editing/Raise.cs @@ -0,0 +1,139 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace libTerrain +{ + partial class Channel + { + /// + /// Raises land around the selection + /// + /// The center the X coordinate of where you wish to raise the land + /// The center the Y coordinate of where you wish to raise the land + /// The radius of the dimple + /// How much impact to add to the terrain (0..2 usually) + public void Raise(double rx, double ry, double size, double amount) + { + RaiseSphere(rx, ry, size, amount); + } + + /// + /// Raises land in a sphere around the selection + /// + /// The center the X coordinate of where you wish to raise the land + /// The center the Y coordinate of where you wish to raise the land + /// The radius of the sphere dimple + /// How much impact to add to the terrain (0..2 usually) + public void RaiseSphere(double rx, double ry, double size, double amount) + { + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + double z = size; + z *= z; + z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); + + if (z < 0) + z = 0; + + Set(x, y, map[x, y] + (z * amount)); + } + } + } + + /// + /// Raises land in a cone around the selection + /// + /// The center the X coordinate of where you wish to raise the land + /// The center the Y coordinate of where you wish to raise the land + /// The radius of the cone + /// How much impact to add to the terrain (0..2 usually) + public void RaiseCone(double rx, double ry, double size, double amount) + { + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + double z = size; + z -= Math.Sqrt(((x - rx) * (x - rx)) + ((y - ry) * (y - ry))); + + if (z < 0) + z = 0; + + Set(x, y, map[x, y] + (z * amount)); + } + } + } + + /// + /// Lowers land in a sphere around the selection + /// + /// The center the X coordinate of where you wish to lower the land + /// The center the Y coordinate of where you wish to lower the land + /// The radius of the sphere dimple + /// How much impact to remove from the terrain (0..2 usually) + public void Lower(double rx, double ry, double size, double amount) + { + LowerSphere(rx, ry, size, amount); + } + + /// + /// Lowers land in a sphere around the selection + /// + /// The center the X coordinate of where you wish to lower the land + /// The center the Y coordinate of where you wish to lower the land + /// The radius of the sphere dimple + /// How much impact to remove from the terrain (0..2 usually) + public void LowerSphere(double rx, double ry, double size, double amount) + { + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + double z = size; + z *= z; + z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); + + if (z < 0) + z = 0; + + Set(x, y, map[x, y] - (z * amount)); + } + } + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/File.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/File.cs new file mode 100644 index 0000000000..c0173c0366 --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/File.cs @@ -0,0 +1,77 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; +using System.Drawing; + +namespace libTerrain +{ + partial class Channel + { + public Channel LoadImage(string filename) + { + SetDiff(); + + Bitmap bit = new Bitmap(filename); + Channel chan = new Channel(bit.Width, bit.Height); + + int x, y; + for (x = 0; x < bit.Width; x++) + { + for (y = 0; y < bit.Height; y++) + { + Color val = bit.GetPixel(x, y); + chan.map[x, y] = (((double)val.R + (double)val.G + (double)val.B) / 3.0) / 255.0; + } + } + + return chan; + } + + public void SaveImage(string filename) + { + Channel outmap = this.Copy(); + outmap.Normalise(); + + Bitmap bit = new Bitmap(w, h, System.Drawing.Imaging.PixelFormat.Format24bppRgb); + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + int val = Math.Min(255, (int)(outmap.map[x,y] * 255)); + Color col = Color.FromArgb(val,val,val); + bit.SetPixel(x, y, col); + } + } + bit.Save(filename); + } + } +} diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Cellular.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Cellular.cs new file mode 100644 index 0000000000..0cec05d3dd --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Cellular.cs @@ -0,0 +1 @@ +/* Needs BSD rewrite */ \ No newline at end of file diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Fracture.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Fracture.cs new file mode 100644 index 0000000000..13dd1bc4c5 --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Fracture.cs @@ -0,0 +1,145 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace libTerrain +{ + partial class Channel + { + /// + /// Produces a set of coordinates defined by an edge point. Eg - 0 = 0,0. 256 = 0,256. 512 = 256,256 + /// Assumes a 256^2 heightmap. This needs fixing for input values of w,h + /// + /// + /// + /// + /// + private int[] RadialEdge256(int val) + { + // Four cases: + // 1. 000..255 return 0,val + // 2. 256..511 return val - 256,255 + // 3. 512..767 return 255, val - 511 + // 4. 768..1023 return val - 768,0 + + int[] ret = new int[2]; + + if (val < 256) + { + ret[0] = 0; + ret[1] = val; + return ret; + } + if (val < 512) + { + ret[0] = (val % 256); + ret[1] = 255; + return ret; + } + if (val < 768) + { + ret[0] = 255; + ret[1] = 255 - (val % 256); + return ret; + } + if (val < 1024) + { + ret[0] = 255 - (val % 256); + ret[1] = 255; + return ret; + } + + throw new Exception("Out of bounds parameter (val)"); + } + + public void Fracture(int number, double scalemin, double scalemax) + { + SetDiff(); + + Random rand = new Random(seed); + + for (int i = 0; i < number; i++) + { + int[] a, b; + + a = RadialEdge256(rand.Next(1023)); // TODO: Broken + b = RadialEdge256(rand.Next(1023)); // TODO: Broken + double z = rand.NextDouble(); + double u = rand.NextDouble(); + double v = rand.NextDouble(); + + for (int x = 0; x < w; x++) + { + for (int y = 0; y < h; y++) + { + double miny = Tools.linearInterpolate(a[1], b[1], (double)x / (double)w); + + if (v >= 0.5) + { + if (u >= 0.5) + { + if (y > miny) + { + map[x, y] += Tools.linearInterpolate(scalemin, scalemax, z); + } + } + else + { + if (y < miny) + { + map[x, y] += Tools.linearInterpolate(scalemin, scalemax, z); + } + } + } + else + { + if (u >= 0.5) + { + if (x > miny) + { + map[x, y] += Tools.linearInterpolate(scalemin, scalemax, z); + } + } + else + { + if (x < miny) + { + map[x, y] += Tools.linearInterpolate(scalemin, scalemax, z); + } + } + } + } + } + } + Normalise(); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Gradient.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Gradient.cs new file mode 100644 index 0000000000..47b7a66bf1 --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Gradient.cs @@ -0,0 +1,66 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace libTerrain +{ + partial class Channel + { + + public void GradientCube() + { + SetDiff(); + + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + map[x, y] = x*y; + } + } + Normalise(); + } + + public void GradientStripe() + { + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + map[x, y] = x; + } + } + Normalise(); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/HillPlanter.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/HillPlanter.cs new file mode 100644 index 0000000000..5a697b1e17 --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/HillPlanter.cs @@ -0,0 +1,283 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace libTerrain +{ + partial class Channel + { + /// + /// Generates a series of spheres which are then either max()'d or added together. Inspired by suggestion from jh. + /// + /// 3-Clause BSD Licensed + /// The number of hills to generate + /// The minimum size of each hill + /// The maximum size of each hill + /// Whether to bias hills towards the center of the map + /// Whether to add hills together or to pick the largest value + /// Generates hill-shaped noise instead of consistent hills + public void HillsSpheres(int number, double scale_min, double scale_range, bool island, bool additive, bool noisy) + { + SetDiff(); + + Random random = new Random(seed); + + int x, y; + int i; + + for (i = 0; i < number; i++) + { + double rx = Math.Min(255.0, random.NextDouble() * w); + double ry = Math.Min(255.0, random.NextDouble() * h); + double rand = random.NextDouble(); + + if (island) + { + // Move everything towards the center + rx -= w / 2; + rx /= 2; + rx += w / 2; + + ry -= h / 2; + ry /= 2; + ry += h / 2; + } + + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + if (noisy) + rand = random.NextDouble(); + + double z = (scale_min + (scale_range * rand)); + z *= z; + z -= ((x - rx) * (x - rx)) + ((y - ry) * (y - ry)); + + if (z < 0) + z = 0; + + if (additive) + { + map[x, y] += z; + } + else + { + map[x, y] = Math.Max(map[x, y], z); + } + } + } + } + + Normalise(); + } + + /// + /// Generates a series of cones which are then either max()'d or added together. Inspired by suggestion from jh. + /// + /// 3-Clause BSD Licensed + /// The number of hills to generate + /// The minimum size of each hill + /// The maximum size of each hill + /// Whether to bias hills towards the center of the map + /// Whether to add hills together or to pick the largest value + /// Generates hill-shaped noise instead of consistent hills + public void HillsCones(int number, double scale_min, double scale_range, bool island, bool additive, bool noisy) + { + SetDiff(); + + Random random = new Random(seed); + + int x, y; + int i; + + for (i = 0; i < number; i++) + { + double rx = Math.Min(255.0, random.NextDouble() * w); + double ry = Math.Min(255.0, random.NextDouble() * h); + double rand = random.NextDouble(); + + if (island) + { + // Move everything towards the center + rx -= w / 2; + rx /= 2; + rx += w / 2; + + ry -= h / 2; + ry /= 2; + ry += h / 2; + } + + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + if (noisy) + rand = random.NextDouble(); + + double z = (scale_min + (scale_range * rand)); + z -= Math.Sqrt(((x - rx) * (x - rx)) + ((y - ry) * (y - ry))); + + if (z < 0) + z = 0; + + if (additive) + { + map[x, y] += z; + } + else + { + map[x, y] = Math.Max(map[x, y], z); + } + } + } + } + + Normalise(); + } + + public void HillsBlocks(int number, double scale_min, double scale_range, bool island, bool additive, bool noisy) + { + SetDiff(); + + Random random = new Random(seed); + + int x, y; + int i; + + for (i = 0; i < number; i++) + { + double rx = Math.Min(255.0, random.NextDouble() * w); + double ry = Math.Min(255.0, random.NextDouble() * h); + double rand = random.NextDouble(); + + if (island) + { + // Move everything towards the center + rx -= w / 2; + rx /= 2; + rx += w / 2; + + ry -= h / 2; + ry /= 2; + ry += h / 2; + } + + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + if (noisy) + rand = random.NextDouble(); + + double z = (scale_min + (scale_range * rand)); + z -= Math.Abs(x-rx) + Math.Abs(y-ry); + //z -= Math.Sqrt(((x - rx) * (x - rx)) + ((y - ry) * (y - ry))); + + if (z < 0) + z = 0; + + if (additive) + { + map[x, y] += z; + } + else + { + map[x, y] = Math.Max(map[x, y], z); + } + } + } + } + + Normalise(); + } + + public void HillsSquared(int number, double scale_min, double scale_range, bool island, bool additive, bool noisy) + { + SetDiff(); + + Random random = new Random(seed); + + int x, y; + int i; + + for (i = 0; i < number; i++) + { + double rx = Math.Min(255.0, random.NextDouble() * w); + double ry = Math.Min(255.0, random.NextDouble() * h); + double rand = random.NextDouble(); + + if (island) + { + // Move everything towards the center + rx -= w / 2; + rx /= 2; + rx += w / 2; + + ry -= h / 2; + ry /= 2; + ry += h / 2; + } + + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + if (noisy) + rand = random.NextDouble(); + + double z = (scale_min + (scale_range * rand)); + z *= z * z * z; + double dx = Math.Abs(x - rx); + double dy = Math.Abs(y - ry); + z -= (dx * dx * dx * dx) + (dy * dy * dy * dy); + + if (z < 0) + z = 0; + + if (additive) + { + map[x, y] += z; + } + else + { + map[x, y] = Math.Max(map[x, y], z); + } + } + } + } + + Normalise(); + } + + } +} diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Midpoint.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Midpoint.cs new file mode 100644 index 0000000000..0cec05d3dd --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Midpoint.cs @@ -0,0 +1 @@ +/* Needs BSD rewrite */ \ No newline at end of file diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Mountain.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Mountain.cs new file mode 100644 index 0000000000..0cec05d3dd --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Mountain.cs @@ -0,0 +1 @@ +/* Needs BSD rewrite */ \ No newline at end of file diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Noise.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Noise.cs new file mode 100644 index 0000000000..3cefcfee22 --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Noise.cs @@ -0,0 +1,56 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace libTerrain +{ + partial class Channel + { + /// + /// Fills a channel with 0..1 noise + /// + /// 3-Clause BSD Licensed + public void Noise() + { + SetDiff(); + + Random rand = new Random(seed); + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + map[x, y] = rand.NextDouble(); + } + } + } + } +} diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Spiral.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Spiral.cs new file mode 100644 index 0000000000..80abfe5b2e --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Spiral.cs @@ -0,0 +1,156 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace libTerrain +{ + partial class Channel + { + private double[] CoordinatesToPolar(int x, int y) + { + double theta = Math.Atan2(x - (w / 2), y - (h / 2)); + double rx = (double)x - ((double)w / 2); + double ry = (double)y - ((double)h / 2); + double r = Math.Sqrt((rx * rx) + (ry * ry)); + + double[] coords = new double[2]; + coords[0] = r; + coords[1] = theta; + return coords; + } + + public int[] PolarToCoordinates(double r, double theta) { + double nx; + double ny; + + nx = (double)r * Math.Cos(theta); + ny = (double)r * Math.Sin(theta); + + nx += w / 2; + ny += h / 2; + + if (nx >= w) + nx = w - 1; + + if (ny >= h) + ny = h - 1; + + if (nx < 0) + nx = 0; + + if (ny < 0) + ny = 0; + + int[] coords = new int[2]; + coords[0] = (int)nx; + coords[1] = (int)ny; + return coords; + } + + public void Polar() + { + SetDiff(); + + Channel n = this.Copy(); + + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + double[] coords = CoordinatesToPolar(x,y); + + coords[0] += w / 2.0; + coords[1] += h / 2.0; + + map[x, y] = n.map[(int)coords[0] % n.w, (int)coords[1] % n.h]; + } + } + } + + public void SpiralPlanter(int steps, double incAngle, double incRadius, double offsetRadius, double offsetAngle) + { + SetDiff(); + + int i; + double r = offsetRadius; + double theta = offsetAngle; + for (i = 0; i < steps; i++) + { + r += incRadius; + theta += incAngle; + + int[] coords = PolarToCoordinates(r,theta); + Raise(coords[0], coords[1], 20, 1); + } + } + + public void SpiralCells(int steps, double incAngle, double incRadius, double offsetRadius, double offsetAngle, double[] c) + { + SetDiff(); + + List points = new List(); + + int i; + double r = offsetRadius; + double theta = offsetAngle; + for (i = 0; i < steps; i++) + { + r += incRadius; + theta += incAngle; + + int[] coords = PolarToCoordinates(r, theta); + points.Add(new Point2D(coords[0],coords[1])); + } + + VoronoiDiagram(points, c); + } + + public void Spiral(double wid, double hig, double offset) + { + SetDiff(); + + int x, y, z; + z = 0; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + z++; + double dx = Math.Abs((w / 2) - x); + double dy = Math.Abs((h / 2) - y); + map[x, y] += Math.Sin(dx / wid) + Math.Cos(dy / hig); + } + } + Normalise(); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Voronoi.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Voronoi.cs new file mode 100644 index 0000000000..eb8f7baa5c --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Voronoi.cs @@ -0,0 +1,214 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace libTerrain +{ + partial class Channel + { + /// + /// Generates a Voronoi diagram (sort of a stained glass effect) which will fill the entire channel + /// + /// 3-Clause BSD Licensed + /// The number of generator points in each block + /// A multiple of the channel width and height which will have voronoi points generated in it. + /// This is to ensure a more even distribution of the points than pure random allocation. + /// The Voronoi diagram type. Usually an array with values consisting of [-1,1]. Experiment with the chain, you can have as many values as you like. + public void VoronoiDiagram(int pointsPerBlock, int blockSize, double[] c) + { + SetDiff(); + + List points = new List(); + Random generator = new Random(seed); + + // Generate the emitter points + int x, y, i; + for (x = -blockSize; x < w + blockSize; x += blockSize) + { + for (y = -blockSize; y < h + blockSize; y += blockSize) + { + for (i = 0; i < pointsPerBlock; i++) + { + double pX = x + (generator.NextDouble() * (double)blockSize); + double pY = y + (generator.NextDouble() * (double)blockSize); + + points.Add(new Point2D(pX, pY)); + } + } + } + + double[] distances = new double[points.Count]; + + // Calculate the distance each pixel is from an emitter + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + for (i = 0; i < points.Count; i++) + { + double dx, dy; + dx = Math.Abs((double)x - points[i].x); + dy = Math.Abs((double)y - points[i].y); + + distances[i] = (dx * dx + dy * dy); + } + + Array.Sort(distances); + + double f = 0.0; + + // Multiply the distances with their 'c' counterpart + // ordering the distances descending + for (i = 0; i < c.Length; i++) + { + if (i >= points.Count) + break; + + f += c[i] * distances[i]; + } + + map[x, y] = f; + } + } + + // Normalise the result + Normalise(); + } + + public void VoronoiDiagram(List points, double[] c) + { + SetDiff(); + + Random generator = new Random(seed); + int x, y, i; + double[] distances = new double[points.Count]; + + // Calculate the distance each pixel is from an emitter + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + for (i = 0; i < points.Count; i++) + { + double dx, dy; + dx = Math.Abs((double)x - points[i].x); + dy = Math.Abs((double)y - points[i].y); + + distances[i] = (dx * dx + dy * dy); + } + + Array.Sort(distances); + + double f = 0.0; + + // Multiply the distances with their 'c' counterpart + // ordering the distances descending + for (i = 0; i < c.Length; i++) + { + if (i >= points.Count) + break; + + f += c[i] * distances[i]; + } + + map[x, y] = f; + } + } + + // Normalise the result + Normalise(); + } + + public void VoroflatDiagram(int pointsPerBlock, int blockSize) + { + SetDiff(); + + List points = new List(); + Random generator = new Random(seed); + + // Generate the emitter points + int x, y, i; + for (x = -blockSize; x < w + blockSize; x += blockSize) + { + for (y = -blockSize; y < h + blockSize; y += blockSize) + { + for (i = 0; i < pointsPerBlock; i++) + { + double pX = x + (generator.NextDouble() * (double)blockSize); + double pY = y + (generator.NextDouble() * (double)blockSize); + + points.Add(new Point2D(pX, pY)); + } + } + } + + double[] distances = new double[points.Count]; + + // Calculate the distance each pixel is from an emitter + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + for (i = 0; i < points.Count; i++) + { + double dx, dy; + dx = Math.Abs((double)x - points[i].x); + dy = Math.Abs((double)y - points[i].y); + + distances[i] = (dx * dx + dy * dy); + } + + //Array.Sort(distances); + + double f = 0.0; + + double min = double.MaxValue; + for (int j = 0; j < distances.Length;j++ ) + { + if (distances[j] < min) + { + min = distances[j]; + f = j; + } + } + + // Multiply the distances with their 'c' counterpart + // ordering the distances descending + + map[x, y] = f; + } + } + + // Normalise the result + Normalise(); + } + } +} diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Worms.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Worms.cs new file mode 100644 index 0000000000..ce36daf2b8 --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Worms.cs @@ -0,0 +1,74 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace libTerrain +{ + partial class Channel + { + /// + /// Generates 'number' of worms which navigate randomly around the landscape creating terrain as they go. + /// + /// The number of worms which will traverse the map + /// The number of steps each worm will traverse + /// The maximum distance each worm will move each step + /// The size of the area around the worm modified + /// Do worms start in the middle, or randomly? + public void Worms(int number, int rounds, double movement, double size, bool centerspawn) + { + SetDiff(); + + Random random = new Random(seed); + int i, j; + + for (i = 0; i < number; i++) + { + double rx, ry; + if (centerspawn) + { + rx = w / 2.0; + ry = h / 2.0; + } + else + { + rx = random.NextDouble() * (w - 1); + ry = random.NextDouble() * (h - 1); + } + for (j = 0; j < rounds; j++) + { + rx += (random.NextDouble() * movement) - (movement / 2.0); + ry += (random.NextDouble() * movement) - (movement / 2.0); + Raise(rx, ry, size, 1.0); + } + } + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Grid.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Grid.cs new file mode 100644 index 0000000000..af62fd5e86 --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Grid.cs @@ -0,0 +1,363 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace libTerrain +{ + partial class Channel + { + public Channel Normalise() + { + SetDiff(); + + double max = FindMax(); + double min = FindMin(); + + int x, y; + + if (max != min) + { + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + map[x, y] = (map[x, y] - min) * (1.0 / (max - min)); + } + } + } + else + { + this.Fill(0.5); + } + + return this; + } + + public Channel Normalise(double minv, double maxv) + { + SetDiff(); + + if (minv == maxv) + { + Fill(minv); + return this; + } + + double max = FindMax(); + double min = FindMin(); + + int x, y; + + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + if (min != max) + { + double val = (map[x, y] - min) * (1.0 / max - min); + val *= maxv - minv; + val += minv; + + map[x, y] = val; + } + else + { + map[x, y] = 0.5; + } + } + } + + return this; + } + + public Channel Clip() + { + int x, y; + + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + SetClip(x, y, map[x, y]); + } + } + + return this; + } + + public Channel Clip(double min, double max) + { + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + double val = map[x, y]; + if (val > max) val = max; + if (val < min) val = min; + + Set(x, y, val); + } + } + return this; + } + + public Channel Crop(int x1, int y1, int x2, int y2) + { + int width = x1 - x2 + 1; + int height = y1 - y2 + 1; + Channel chan = new Channel(width, height); + + int x, y; + int nx, ny; + + nx = 0; + for (x = x1; x < x2; x++) + { + ny = 0; + for (y = y1; y < y2; y++) + { + chan.map[nx, ny] = map[x, y]; + + ny++; + } + nx++; + } + + return this; + } + + public Channel AddClip(Channel other) + { + SetDiff(); + + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + map[x, y] = other.map[x, y]; + if (map[x, y] > 1) + map[x, y] = 1; + if (map[x, y] < 0) + map[x, y] = 0; + } + } + return this; + } + + public void Smooth(double amount) + { + SetDiff(); + + double area = amount; + double step = amount / 4.0; + + double[,] manipulate = new double[w, h]; + int x, y; + double n, l; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + double average = 0.0; + int avgsteps = 0; + + for (n = 0.0 - area; n < area; n += step) + { + for (l = 0.0 - area; l < area; l += step) + { + avgsteps++; + average += GetBilinearInterpolate(x + n, y + l); + } + } + + manipulate[x, y] = average / avgsteps; + } + } + map = manipulate; + } + + public void Pertubation(double amount) + { + SetDiff(); + + // Simple pertubation filter + double[,] manipulated = new double[w, h]; + Random generator = new Random(seed); // Seeds FTW! + //double amount = 8.0; + + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + double offset_x = (double)x + (generator.NextDouble() * amount) - (amount / 2.0); + double offset_y = (double)y + (generator.NextDouble() * amount) - (amount / 2.0); + double p = GetBilinearInterpolate(offset_x, offset_y); + manipulated[x, y] = p; + } + } + map = manipulated; + } + + public void PertubationMask(Channel mask) + { + // Simple pertubation filter + double[,] manipulated = new double[w, h]; + Random generator = new Random(seed); // Seeds FTW! + //double amount = 8.0; + + double amount; + + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + amount = mask.map[x, y]; + double offset_x = (double)x + (generator.NextDouble() * amount) - (amount / 2.0); + double offset_y = (double)y + (generator.NextDouble() * amount) - (amount / 2.0); + + if (offset_x > w) + offset_x = w - 1; + if (offset_y > h) + offset_y = h - 1; + if (offset_y < 0) + offset_y = 0; + if (offset_x < 0) + offset_x = 0; + + double p = GetBilinearInterpolate(offset_x, offset_y); + manipulated[x, y] = p; + SetDiff(x, y); + } + } + map = manipulated; + } + + public void Distort(Channel mask, double str) + { + // Simple pertubation filter + double[,] manipulated = new double[w, h]; + + double amount; + + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + amount = mask.map[x, y]; + double offset_x = (double)x + (amount * str) - (0.5 * str); + double offset_y = (double)y + (amount * str) - (0.5 * str); + + if (offset_x > w) + offset_x = w - 1; + if (offset_y > h) + offset_y = h - 1; + if (offset_y < 0) + offset_y = 0; + if (offset_x < 0) + offset_x = 0; + + double p = GetBilinearInterpolate(offset_x, offset_y); + manipulated[x, y] = p; + SetDiff(x, y); + } + } + map = manipulated; + + } + + public void Distort(Channel mask, Channel mask2, double str) + { + // Simple pertubation filter + double[,] manipulated = new double[w, h]; + + double amountX; + double amountY; + + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + amountX = mask.map[x, y]; + amountY = mask2.map[x, y]; + double offset_x = (double)x + (amountX * str) - (0.5 * str); + double offset_y = (double)y + (amountY * str) - (0.5 * str); + + if (offset_x > w) + offset_x = w - 1; + if (offset_y > h) + offset_y = h - 1; + if (offset_y < 0) + offset_y = 0; + if (offset_x < 0) + offset_x = 0; + + double p = GetBilinearInterpolate(offset_x, offset_y); + manipulated[x, y] = p; + SetDiff(x, y); + } + } + map = manipulated; + + } + + public Channel Blend(Channel other, double amount) + { + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + Set(x, y, Tools.linearInterpolate(map[x, y], other.map[x, y], amount)); + } + } + return this; + } + + public Channel Blend(Channel other, Channel amount) + { + int x, y; + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + Set(x, y, Tools.linearInterpolate(map[x, y], other.map[x, y], amount.map[x, y])); + } + } + return this; + } + } +} diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/AerobicErosion.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/AerobicErosion.cs new file mode 100644 index 0000000000..589d360203 --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/AerobicErosion.cs @@ -0,0 +1,213 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace libTerrain +{ + partial class Channel + { + // Ideas for Aerobic erosion + // + // Unlike thermal (gravity) and hydraulic (water suspension) + // aerobic erosion should displace mass by moving sediment + // in "hops". The length of the hop being dictated by the + // presence of sharp cliffs and wind speed. + + // The ability to pickup sediment is defined by the total + // surface area, such that: + // 0 0 0 + // 0 1 0 + // 0 0 0 + // Would be the best possible value for sediment to be + // picked up (total difference = 8) and flatter land + // will erode less quickly. + + // Suspended particles assist the erosion process by hitting + // the surface and chiselling additional particles off faster + // than alone. + + // Particles are deposited when one of two conditions is met + // First: + // When particles hit a wall - such that the + // wind direction points at a difference >= the + // deposition mininum talus. + // Second: + // When wind speed is lowered to below the minimum + // required for transit. An idea for this is to + // use the navier-stokes algorithms for simulating + // pressure across the terrain. + + /// + /// An experimental erosion algorithm developed by Adam. Moves sediment by factoring the surface area of each height point. + /// + /// 0..1 The speed of the wind + /// The minimum angle at which rock is eroded 0..1 (recommended: <= 0.30) + /// The minimum angle at which rock is dropped 0..1 (recommended: >= 0.00) + /// The percentage of rock which can be picked up to pickup 0..1 + /// The number of erosion rounds (recommended: 25+) + /// Drop sediment at the lowest point? + public void AerobicErosion(double windspeed, double pickupTalusMinimum, double dropTalusMinimum, double carry, int rounds, bool lowest, bool usingFluidDynamics) + { + bool debugImages = false; + + Channel wind = new Channel(w, h) ; + Channel sediment = new Channel(w, h); + int x, y, i, j; + + this.Normalise(); + + wind = this.Copy(); + wind.Noise(); + + if (debugImages) + wind.SaveImage("testimg/wind_start.png"); + + if (usingFluidDynamics) + { + wind.navierStokes(20, 0.1, 0.0, 0.0); + } + else + { + wind.Pertubation(30); + } + + if (debugImages) + wind.SaveImage("testimg/wind_begin.png"); + + for (i = 0; i < rounds; i++) + { + // Convert some rocks to sand + for (x = 1; x < w - 1; x++) + { + for (y = 1; y < h - 1; y++) + { + double me = Get(x, y); + double surfacearea = 0.3; // Everything will erode even if it's flat. Just slower. + + for (j = 0; j < 9; j++) + { + int[] coords = Neighbours(NeighbourSystem.Moore, j); + double target = Get(x + coords[0], y + coords[1]); + + surfacearea += Math.Abs(target - me); + } + + double amount = surfacearea * wind.map[x, y] * carry; + + if (amount < 0) + amount = 0; + + if (surfacearea > pickupTalusMinimum) + { + Set(x, y, map[x, y] - amount); + sediment.map[x, y] += amount; + } + } + } + + if (usingFluidDynamics) + { + sediment.navierStokes(7, 0.1, 0.0, 0.1); + + Channel noiseChan = new Channel(w, h); + noiseChan.Noise(); + wind.Blend(noiseChan, 0.01); + + wind.navierStokes(10, 0.1, 0.01, 0.01); + + sediment.Distort(wind, windspeed); + } + else + { + wind.Pertubation(15); // Can do better later + wind.seed++; + sediment.Pertubation(10); // Sediment is blown around a bit + sediment.seed++; + } + + if (debugImages) + wind.SaveImage("testimg/wind_" + i.ToString() + ".png"); + + // Convert some sand to rock + for (x = 1; x < w - 1; x++) + { + for (y = 1; y < h - 1; y++) + { + double me = Get(x, y); + double surfacearea = 0.01; // Flat land does not get deposition + double min = double.MaxValue; + int[] minside = new int[2]; + + for (j = 0; j < 9; j++) + { + int[] coords = Neighbours(NeighbourSystem.Moore, j); + double target = Get(x + coords[0], y + coords[1]); + + surfacearea += Math.Abs(target - me); + + if (target < min && lowest) + { + minside = (int[])coords.Clone(); + min = target; + } + } + + double amount = surfacearea * (1.0 - wind.map[x, y]) * carry; + + if (amount < 0) + amount = 0; + + if (surfacearea > dropTalusMinimum) + { + Set(x + minside[0], y + minside[1], map[x + minside[0], y + minside[1]] + amount); + sediment.map[x, y] -= amount; + } + } + } + + if (debugImages) + sediment.SaveImage("testimg/sediment_" + i.ToString() + ".png"); + + wind.Normalise(); + wind *= windspeed; + + this.Normalise(); + } + + Channel myself = this; + myself += sediment; + myself.Normalise(); + + if (debugImages) + this.SaveImage("testimg/output.png"); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/HydraulicErosion.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/HydraulicErosion.cs new file mode 100644 index 0000000000..36da77cb1d --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/HydraulicErosion.cs @@ -0,0 +1,146 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace libTerrain +{ + partial class Channel + { + public void HydraulicErosion(Channel rain, double evaporation, double solubility, int frequency, int rounds) + { + SetDiff(); + + Channel water = new Channel(w, h); + Channel sediment = new Channel(w, h); + Channel terrain = this; + Channel waterFlow = new Channel(w, h); + + NeighbourSystem type = NeighbourSystem.Moore; + int NEIGHBOUR_ME = 4; + + int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5; + + for (int i = 0; i < rounds; i++) + { + water += rain; + + sediment = terrain * water; + terrain -= sediment; + + for (int x = 1; x < w - 1; x++) + { + for (int y = 1; y < h - 1; y++) + { + double[] heights = new double[NEIGHBOUR_MAX]; + double[] diffs = new double[NEIGHBOUR_MAX]; + + double heightCenter = map[x, y]; + + for (int j = 0; j < NEIGHBOUR_MAX; j++) + { + if (j != NEIGHBOUR_ME) + { + int[] coords = Neighbours(type, j); + coords[0] += x; + coords[1] += y; + + heights[j] = map[coords[0], coords[1]] + water.map[coords[0], coords[1]] + sediment.map[coords[0], coords[1]]; + diffs[j] = heightCenter - heights[j]; + } + } + + double totalHeight = 0; + double totalHeightDiff = 0; + int totalCellsCounted = 1; + + for (int j = 0; j < NEIGHBOUR_MAX; j++) + { + if (j != NEIGHBOUR_ME) + { + if (diffs[j] > 0) + { + totalHeight += heights[j]; + totalHeightDiff += diffs[j]; + totalCellsCounted++; + } + } + } + + if (totalCellsCounted == 1) + continue; + + double averageHeight = totalHeight / totalCellsCounted; + double waterAmount = Math.Min(water.map[x, y], heightCenter - averageHeight); + + // TODO: Check this. + waterFlow.map[x, y] += waterFlow.map[x, y] - waterAmount; + + double totalInverseDiff = waterAmount / totalHeightDiff; + + for (int j = 0; j < NEIGHBOUR_MAX; j++) + { + if (j != NEIGHBOUR_ME) + { + int[] coords = Neighbours(type, j); + coords[0] += x; + coords[1] += y; + + if (diffs[j] > 0) + { + waterFlow.SetWrap(coords[0], coords[1], waterFlow.map[coords[0], coords[1]] + diffs[j] * totalInverseDiff); + } + } + } + } + } + + water += waterFlow; + waterFlow.Fill(0); + + water *= evaporation; + + for (int x = 0; x < w; x++) + { + for (int y = 0; y < h; y++) + { + double deposition = sediment.map[x, y] - water.map[x, y] * solubility; + if (deposition > 0) + { + sediment.map[x, y] -= deposition; + terrain.map[x, y] += deposition; + } + } + } + + } + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/NavierStokes.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/NavierStokes.cs new file mode 100644 index 0000000000..8a111ed7ef --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/NavierStokes.cs @@ -0,0 +1,307 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace libTerrain +{ + partial class Channel + { + // Navier Stokes Algorithms ported from + // "Real-Time Fluid Dynamics for Games" by Jos Stam. + // presented at GDC 2003. + + // Poorly ported from C++. (I gave up making it properly native somewhere after nsSetBnd) + + private static int nsIX(int i, int j, int N) + { + return ((i) + (N + 2) * (j)); + } + + private static void nsSwap(ref double x0, ref double x) + { + double tmp = x0; + x0 = x; + x = tmp; + } + + private static void nsSwap(ref double[] x0, ref double[] x) + { + double[] tmp = x0; + x0 = x; + x = tmp; + } + + private void nsAddSource(int N, ref double[] x, ref double[] s, double dt) + { + int i; + int size = (N + 2) * (N + 2); + for (i = 0; i < size; i++) + { + x[i] += dt * s[i]; + } + } + + private void nsSetBnd(int N, int b, ref double[] x) + { + int i; + for (i = 0; i <= N; i++) + { + x[nsIX(0, i, N)] = b == 1 ? -x[nsIX(1, i, N)] : x[nsIX(1, i, N)]; + x[nsIX(0, N + 1, N)] = b == 1 ? -x[nsIX(N, i, N)] : x[nsIX(N, i, N)]; + x[nsIX(i, 0, N)] = b == 2 ? -x[nsIX(i, 1, N)] : x[nsIX(i, 1, N)]; + x[nsIX(i, N + 1, N)] = b == 2 ? -x[nsIX(i, N, N)] : x[nsIX(i, N, N)]; + } + x[nsIX(0, 0, N)] = 0.5f * (x[nsIX(1, 0, N)] + x[nsIX(0, 1, N)]); + x[nsIX(0, N + 1, N)] = 0.5f * (x[nsIX(1, N + 1, N)] + x[nsIX(0, N, N)]); + x[nsIX(N + 1, 0, N)] = 0.5f * (x[nsIX(N, 0, N)] + x[nsIX(N + 1, 1, N)]); + x[nsIX(N + 1, N + 1, N)] = 0.5f * (x[nsIX(N, N + 1, N)] + x[nsIX(N + 1, N, N)]); + } + + private void nsLinSolve(int N, int b, ref double[] x, ref double[] x0, double a, double c) + { + int i, j; + for (i = 1; i <= N; i++) + { + for (j = 1; j <= N; j++) + { + x[nsIX(i, j, N)] = (x0[nsIX(i, j, N)] + a * + (x[nsIX(i - 1, j, N)] + + x[nsIX(i + 1, j, N)] + + x[nsIX(i, j - 1, N)] + x[nsIX(i, j + 1, N)]) + ) / c; + } + } + + nsSetBnd(N, b, ref x); + } + + private void nsDiffuse(int N, int b, ref double[] x, ref double[] x0, double diff, double dt) + { + double a = dt * diff * N * N; + nsLinSolve(N, b, ref x, ref x0, a, 1 + 4 * a); + } + + private void nsAdvect(int N, int b, ref double[] d, ref double[] d0, ref double[] u, ref double[] v, double dt) + { + int i, j, i0, j0, i1, j1; + double x, y, s0, t0, s1, t1, dt0; + + dt0 = dt * N; + + for (i = 1; i <= N; i++) + { + for (j = 1; j <= N; j++) + { + x = i - dt0 * u[nsIX(i, j, N)]; + y = j - dt0 * v[nsIX(i, j, N)]; + + if (x < 0.5) + x = 0.5; + if (x > N + 0.5) + x = N + 0.5; + i0 = (int)x; + i1 = i0 + 1; + + if (y < 0.5) + y = 0.5; + if (y > N + 0.5) + y = N + 0.5; + j0 = (int)y; + j1 = j0 + 1; + + s1 = x - i0; + s0 = 1 - s1; + t1 = y - j0; + t0 = 1 - t1; + + d[nsIX(i, j, N)] = s0 * (t0 * d0[nsIX(i0, j0, N)] + t1 * d0[nsIX(i0, j1, N)]) + + s1 * (t0 * d0[nsIX(i1, j0, N)] + t1 * d0[nsIX(i1, j1, N)]); + } + } + + nsSetBnd(N, b, ref d); + } + + public void nsProject(int N, ref double[] u, ref double[] v, ref double[] p, ref double[] div) + { + int i, j; + + for (i = 1; i <= N; i++) + { + for (j = 1; j <= N; j++) + { + div[nsIX(i, j, N)] = -0.5 * (u[nsIX(i + 1, j, N)] - u[nsIX(i - 1, j, N)] + v[nsIX(i, j + 1, N)] - v[nsIX(i, j - 1, N)]) / N; + p[nsIX(i, j, N)] = 0; + } + } + + nsSetBnd(N, 0, ref div); + nsSetBnd(N, 0, ref p); + + nsLinSolve(N, 0, ref p, ref div, 1, 4); + + for (i = 1; i <= N; i++) + { + for (j = 1; j <= N; j++) + { + u[nsIX(i, j, N)] -= 0.5 * N * (p[nsIX(i + 1, j, N)] - p[nsIX(i - 1, j, N)]); + v[nsIX(i, j, N)] -= 0.5 * N * (p[nsIX(i, j + 1, N)] - p[nsIX(i, j - 1, N)]); + } + } + + nsSetBnd(N, 1, ref u); + nsSetBnd(N, 2, ref v); + } + + private void nsDensStep(int N, ref double[] x, ref double[] x0, ref double[] u, ref double[] v, double diff, double dt) + { + nsAddSource(N, ref x, ref x0, dt); + nsSwap(ref x0, ref x); + nsDiffuse(N, 0, ref x, ref x0, diff, dt); + nsSwap(ref x0, ref x); + nsAdvect(N, 0, ref x, ref x0, ref u, ref v, dt); + } + + private void nsVelStep(int N, ref double[] u, ref double[] v, ref double[] u0, ref double[] v0, double visc, double dt) + { + nsAddSource(N, ref u, ref u0, dt); + nsAddSource(N, ref v, ref v0, dt); + nsSwap(ref u0, ref u); + nsDiffuse(N, 1, ref u, ref u0, visc, dt); + nsSwap(ref v0, ref v); + nsDiffuse(N, 2, ref v, ref v0, visc, dt); + nsProject(N, ref u, ref v, ref u0, ref v0); + nsSwap(ref u0, ref u); + nsSwap(ref v0, ref v); + nsAdvect(N, 1, ref u, ref u0, ref u0, ref v0, dt); + nsAdvect(N, 2, ref v, ref v0, ref u0, ref v0, dt); + nsProject(N, ref u, ref v, ref u0, ref v0); + } + + private void nsBufferToDoubles(ref double[] dens, int N, ref double[,] doubles) + { + int i; + int j; + + for (i = 1; i <= N; i++) + { + for (j = 1; j <= N; j++) + { + doubles[i - 1, j - 1] = dens[nsIX(i, j, N)]; + } + } + } + + private void nsDoublesToBuffer(double[,] doubles, int N, ref double[] dens) + { + int i; + int j; + + for (i = 1; i <= N; i++) + { + for (j = 1; j <= N; j++) + { + dens[nsIX(i, j, N)] = doubles[i - 1, j - 1]; + } + } + } + + private void nsSimulate(int N, int rounds, double dt, double diff, double visc) + { + int size = (N * 2) * (N * 2); + + double[] u = new double[size]; // Force, X axis + double[] v = new double[size]; // Force, Y axis + double[] u_prev = new double[size]; + double[] v_prev = new double[size]; + double[] dens = new double[size]; + double[] dens_prev = new double[size]; + + nsDoublesToBuffer(this.map, N, ref dens); + nsDoublesToBuffer(this.map, N, ref dens_prev); + + for (int i = 0; i < rounds; i++) + { + u_prev = u; + v_prev = v; + dens_prev = dens; + + nsVelStep(N, ref u, ref v, ref u_prev, ref v_prev, visc, dt); + nsDensStep(N, ref dens, ref dens_prev, ref u, ref v, diff, dt); + } + + nsBufferToDoubles(ref dens, N, ref this.map); + } + + /// + /// Performs computational fluid dynamics on a channel + /// + /// The number of steps to perform (Recommended: 20) + /// Delta Time - The time between steps (Recommended: 0.1) + /// Fluid diffusion rate (Recommended: 0.0) + /// Fluid viscosity (Recommended: 0.0) + public void navierStokes(int rounds, double dt, double diff, double visc) + { + nsSimulate(this.h, rounds, dt, diff, visc); + } + + public void navierStokes(int rounds, double dt, double diff, double visc, ref double[,] uret, ref double[,] vret) + { + int N = this.h; + + int size = (N * 2) * (N * 2); + + double[] u = new double[size]; // Force, X axis + double[] v = new double[size]; // Force, Y axis + double[] u_prev = new double[size]; + double[] v_prev = new double[size]; + double[] dens = new double[size]; + double[] dens_prev = new double[size]; + + nsDoublesToBuffer(this.map, N, ref dens); + nsDoublesToBuffer(this.map, N, ref dens_prev); + + for (int i = 0; i < rounds; i++) + { + u_prev = u; + v_prev = v; + dens_prev = dens; + + nsVelStep(N, ref u, ref v, ref u_prev, ref v_prev, visc, dt); + nsDensStep(N, ref dens, ref dens_prev, ref u, ref v, diff, dt); + } + + nsBufferToDoubles(ref u, N, ref uret); + nsBufferToDoubles(ref v, N, ref vret); + nsBufferToDoubles(ref dens, N, ref this.map); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/ThermalWeathering.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/ThermalWeathering.cs new file mode 100644 index 0000000000..07c7d66b15 --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/ThermalWeathering.cs @@ -0,0 +1,112 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace libTerrain +{ + partial class Channel + { + /// + /// A thermal weathering implementation based on Musgrave's original 1989 algorithm. This is Adam's custom implementation which may differ slightly from the original. + /// + /// The rock angle (represented as a dy/dx ratio) at which point it will be succeptible to breakage + /// The number of erosion rounds + /// The amount of rock to carry each round + public Channel ThermalWeathering(double talus, int rounds, double c) + { + SetDiff(); + + double[,] lastFrame; + double[,] thisFrame; + + lastFrame = (double[,])map.Clone(); + thisFrame = (double[,])map.Clone(); + + NeighbourSystem type = NeighbourSystem.Moore; // Using moore neighbourhood (twice as computationally expensive) + int NEIGHBOUR_ME = 4; // I am always 4 in both systems. + + int NEIGHBOUR_MAX = type == NeighbourSystem.Moore ? 9 : 5; + + int frames = rounds; // Number of thermal erosion iterations to run + int i, j; + int x, y; + + for (i = 0; i < frames; i++) + { + for (x = 0; x < w; x++) + { + for (y = 0; y < h; y++) + { + for (j = 0; j < NEIGHBOUR_MAX; j++) + { + if (j != NEIGHBOUR_ME) + { + int[] coords = Neighbours(type, j); + + coords[0] += x; + coords[1] += y; + + if (coords[0] > w - 1) + coords[0] = w - 1; + if (coords[1] > h - 1) + coords[1] = h - 1; + if (coords[0] < 0) + coords[0] = 0; + if (coords[1] < 0) + coords[1] = 0; + + double heightF = thisFrame[x, y]; + double target = thisFrame[coords[0], coords[1]]; + + if (target > heightF + talus) + { + double calc = c * ((target - heightF) - talus); + heightF += calc; + target -= calc; + } + + thisFrame[x, y] = heightF; + thisFrame[coords[0], coords[1]] = target; + + } + } + } + } + lastFrame = (double[,])thisFrame.Clone(); + } + + map = thisFrame; + + Normalise(); // Just to guaruntee a smooth 0..1 value + return this; + } + } +} diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Neighbours.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Neighbours.cs new file mode 100644 index 0000000000..6dc2e30857 --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Neighbours.cs @@ -0,0 +1,141 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace libTerrain +{ + partial class Channel + { + enum NeighbourSystem + { + Moore, + VonNeumann + }; + + private int[] Neighbours(NeighbourSystem type, int index) + { + int[] coord = new int[2]; + + index++; + + switch (type) + { + case NeighbourSystem.Moore: + switch (index) + { + case 1: + coord[0] = -1; + coord[1] = -1; + break; + + case 2: + coord[0] = -0; + coord[1] = -1; + break; + + case 3: + coord[0] = +1; + coord[1] = -1; + break; + + case 4: + coord[0] = -1; + coord[1] = -0; + break; + + case 5: + coord[0] = -0; + coord[1] = -0; + break; + + case 6: + coord[0] = +1; + coord[1] = -0; + break; + + case 7: + coord[0] = -1; + coord[1] = +1; + break; + + case 8: + coord[0] = -0; + coord[1] = +1; + break; + + case 9: + coord[0] = +1; + coord[1] = +1; + break; + + default: + break; + } + break; + + case NeighbourSystem.VonNeumann: + switch (index) + { + case 1: + coord[0] = 0; + coord[1] = -1; + break; + + case 2: + coord[0] = -1; + coord[1] = 0; + break; + + case 3: + coord[0] = +1; + coord[1] = 0; + break; + + case 4: + coord[0] = 0; + coord[1] = +1; + break; + + case 5: + coord[0] = -0; + coord[1] = -0; + break; + + default: + break; + } + break; + } + + return coord; + } + } +} diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Operators.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Operators.cs new file mode 100644 index 0000000000..3199ddc4b8 --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Operators.cs @@ -0,0 +1,243 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace libTerrain +{ + partial class Channel + { + /* Operator combination of channel datatypes */ + + public static Channel operator +(Channel A, Channel B) + { + if (A.h != B.h) + throw new Exception("Cannot add heightmaps, of different height."); + if (A.w != B.w) + throw new Exception("Cannot add heightmaps, of different width."); + + int x, y; + + for (x = 0; x < A.w; x++) + { + for (y = 0; y < A.h; y++) + { + if (B.map[x, y] != 0) + A.SetDiff(x, y); + + A.map[x, y] += B.map[x, y]; + } + } + + return A; + } + + public static Channel operator *(Channel A, Channel B) + { + if (A.h != B.h) + throw new Exception("Cannot multiply heightmaps, of different height."); + if (A.w != B.w) + throw new Exception("Cannot multiply heightmaps, of different width."); + + int x, y; + + for (x = 0; x < A.w; x++) + { + for (y = 0; y < A.h; y++) + { + A.map[x, y] *= B.map[x, y]; + } + } + + A.SetDiff(); + + return A; + } + + public static Channel operator -(Channel A, Channel B) + { + if (A.h != B.h) + throw new Exception("Cannot subtract heightmaps, of different height."); + if (A.w != B.w) + throw new Exception("Cannot subtract heightmaps, of different width."); + + int x, y; + + for (x = 0; x < A.w; x++) + { + for (y = 0; y < A.h; y++) + { + if (B.map[x, y] != 0) + A.SetDiff(x, y); + A.map[x, y] -= B.map[x, y]; + } + } + + return A; + } + + public static Channel operator /(Channel A, Channel B) + { + if (A.h != B.h) + throw new Exception("Cannot divide heightmaps, of different height."); + if (A.w != B.w) + throw new Exception("Cannot divide heightmaps, of different width."); + + int x, y; + + for (x = 0; x < A.w; x++) + { + for (y = 0; y < A.h; y++) + { + A.map[x, y] /= B.map[x, y]; + } + } + + A.SetDiff(); + + return A; + } + + public static Channel operator ^(Channel A, Channel B) + { + if (A.h != B.h) + throw new Exception("Cannot divide heightmaps, of different height."); + if (A.w != B.w) + throw new Exception("Cannot divide heightmaps, of different width."); + + int x, y; + + for (x = 0; x < A.w; x++) + { + for (y = 0; y < A.h; y++) + { + A.map[x, y] = Math.Pow(A.map[x,y],B.map[x, y]); + } + } + + A.SetDiff(); + + return A; + } + + + /* Operator combination of channel and double datatypes */ + + public static Channel operator +(Channel A, double B) + { + int x, y; + + for (x = 0; x < A.w; x++) + { + for (y = 0; y < A.h; y++) + { + A.map[x, y] += B; + } + } + + if (B != 0) + A.SetDiff(); + + return A; + } + + public static Channel operator -(Channel A, double B) + { + int x, y; + + for (x = 0; x < A.w; x++) + { + for (y = 0; y < A.h; y++) + { + A.map[x, y] -= B; + } + } + + if (B != 0) + A.SetDiff(); + + return A; + } + + public static Channel operator *(Channel A, double B) + { + int x, y; + + for (x = 0; x < A.w; x++) + { + for (y = 0; y < A.h; y++) + { + A.map[x, y] *= B; + } + } + + if (B != 1) + A.SetDiff(); + + return A; + } + + public static Channel operator /(Channel A, double B) + { + int x, y; + + for (x = 0; x < A.w; x++) + { + for (y = 0; y < A.h; y++) + { + A.map[x, y] /= B; + } + } + + if (B != 1) + A.SetDiff(); + + return A; + } + + public static Channel operator ^(Channel A, double B) + { + int x, y; + + for (x = 0; x < A.w; x++) + { + for (y = 0; y < A.h; y++) + { + A.map[x, y] = Math.Pow(A.map[x,y],B); + } + } + + A.SetDiff(); + + return A; + } + + } +} diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Tools/Point2D.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Tools/Point2D.cs new file mode 100644 index 0000000000..69c1148b7a --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Tools/Point2D.cs @@ -0,0 +1,49 @@ +/* +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 libTerrain 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 COPYRIGHT HOLDERS AND CONTRIBUTORS +"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 COPYRIGHT +OWNER OR 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.Text; + +namespace libTerrain +{ + public class Point2D + { + public double x; + public double y; + + public Point2D(double X, double Y) + { + x = X; + y = Y; + } + } +} diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Tools/Tools.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Tools/Tools.cs new file mode 100644 index 0000000000..3f7ab6831f --- /dev/null +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Tools/Tools.cs @@ -0,0 +1,60 @@ +/* +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 libTerrain 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 COPYRIGHT HOLDERS AND CONTRIBUTORS +"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 COPYRIGHT +OWNER OR 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.Text; + +namespace libTerrain +{ + class Tools + { + public static double linearInterpolate(double a, double b, double amount) + { + return a + ((b - a) * amount); + } + public static double exponentialInterpolate(double a, double b, double amount) + { + a = Math.Pow(a, amount); + b = Math.Pow(b - a, 1.0 - amount); + return a+b; + } + public static int powerOf2Log2(int n) { + for (int i = 0; i < 31; i++) { + if ((n & 1) == 1) { + return i; + } + n >>= 1; + } + return 0; + } + } +} diff --git a/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Form1.Designer.cs b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Form1.Designer.cs new file mode 100644 index 0000000000..f6e52cf876 --- /dev/null +++ b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Form1.Designer.cs @@ -0,0 +1,83 @@ +namespace LaunchSLClient +{ + partial class Form1 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.comboBox1 = new System.Windows.Forms.ComboBox(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.SuspendLayout(); + // + // comboBox1 + // + this.comboBox1.FormattingEnabled = true; + this.comboBox1.Items.AddRange(new object[] { + "Local Sandbox", + "Local Grid Server", + "DeepGrid - www.deepgrid.com", + "OSGrid - www.osgrid.org", + "Linden Labs - www.secondlife.com"}); + this.comboBox1.Location = new System.Drawing.Point(37, 83); + this.comboBox1.Name = "comboBox1"; + this.comboBox1.Size = new System.Drawing.Size(348, 21); + this.comboBox1.TabIndex = 0; + this.comboBox1.Text = "Choose from list"; + this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged); + // + // textBox1 + // + this.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.textBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.textBox1.Location = new System.Drawing.Point(37, 32); + this.textBox1.Name = "textBox1"; + this.textBox1.ReadOnly = true; + this.textBox1.Size = new System.Drawing.Size(292, 19); + this.textBox1.TabIndex = 1; + this.textBox1.Text = "Choose from one of the following:"; + // + // Form1 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(501, 339); + this.Controls.Add(this.textBox1); + this.Controls.Add(this.comboBox1); + this.Name = "Form1"; + this.Text = "OpenSim Client Launcher"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.ComboBox comboBox1; + private System.Windows.Forms.TextBox textBox1; + + } +} + diff --git a/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Form1.cs b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Form1.cs new file mode 100644 index 0000000000..497661d090 --- /dev/null +++ b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Form1.cs @@ -0,0 +1,194 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.IO; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.Drawing; +using System.Text; +using System.Text.RegularExpressions; +using System.Windows.Forms; +using Microsoft.Win32; + +namespace LaunchSLClient +{ + public partial class Form1 : Form + { + string gridUrl = ""; + string sandboxUrl = ""; + string deepGridUrl = "http://user.deepgrid.com:8002/"; + string osGridUrl = "http://www.osgrid.org:8002/"; + string runUrl = ""; + string runLine = ""; + Object exeFlags; + Object exePath; + + + public Form1() + { + InitializeComponent(); + ArrayList menuItems=new ArrayList(); + menuItems.Add("Please select one:"); + string sandboxHostName = ""; + string sandboxPort = ""; + Object simPath = null; + FileInfo defaultFile; + StreamReader stream; + + + // get executable path from registry + // + RegistryKey regKey; + RegistryKey exeKey; + regKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Linden Research, Inc.\SecondLife"); + if (regKey == null) + { + throw new LauncherException("Can't find Second Life. Are you sure it is installed?", "LauncherException.Form1"); + } + Object exe = regKey.GetValue("Exe"); + exeFlags = regKey.GetValue("Flags"); + exePath = regKey.GetValue(""); + runLine = exePath.ToString() + "\\" + exe.ToString(); + Registry.LocalMachine.Flush(); + Registry.LocalMachine.Close(); + + // find opensim directory + // + exeKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\OpenSim\OpenSim"); + if (exeKey != null) + { + + simPath = exeKey.GetValue("Path"); + + // build sandbox URL from Regions\default.xml + // this is highly dependant on a standard default.xml + // + Directory.SetCurrentDirectory(simPath.ToString()); //this should be set to wherever we decide to put the binaries + string text; + Regex myRegex = new Regex(".*internal_ip_port=\\\"(?.*?)\\\".*external_host_name=\\\"(?.*?)\\\".*"); + if (File.Exists(@"Regions\default.xml")) + { + defaultFile = new FileInfo(@"Regions\default.xml"); + stream = defaultFile.OpenText(); + do + { + text = stream.ReadLine(); + if (text == null) + { + break; + } + MatchCollection theMatches = myRegex.Matches(text); + foreach (Match theMatch in theMatches) + { + if (theMatch.Length != 0) + { + sandboxHostName = theMatch.Groups["name"].ToString(); + sandboxPort = theMatch.Groups["port"].ToString(); + } + } + } while (text != null); + stream.Close(); + sandboxUrl = "http:\\" + sandboxHostName + ":" + sandboxPort; + menuItems.Add("Local Sandbox"); + } + else + { + MessageBox.Show("No OpenSim config files found. Please run OpenSim and finish configuration to run a local sim. Showing public grids only", "No OpenSim"); + } + + + //build local grid URL from network_servers_information.xml + // this is highly dependant on a standard default.xml + // + myRegex = new Regex(".*UserServerURL=\\\"(?.*?)\\\".*"); + if (File.Exists(@"network_servers_information.xml")) + { + defaultFile = new FileInfo(@"network_servers_information.xml"); + + + stream = defaultFile.OpenText(); + do + { + text = stream.ReadLine(); + if (text == null) + { + break; + } + MatchCollection theMatches = myRegex.Matches(text); + foreach (Match theMatch in theMatches) + { + if (theMatch.Length != 0) + { + gridUrl = theMatch.Groups["url"].ToString(); + } + } + } while (text != null); + stream.Close(); + if (gridUrl != null) + { + menuItems.Add("Local Grid Server"); + } + } + } + else + { + MessageBox.Show("No OpenSim installed. Showing public grids only", "No OpenSim"); + } + menuItems.Add("DeepGrid - www.deepgrid.com"); + menuItems.Add("OSGrid - www.osgrid.org"); + menuItems.Add("Linden Labs - www.secondlife.com"); + comboBox1.DataSource=menuItems; + } + + private void radioButton1_CheckedChanged(object sender, EventArgs e) + { + + } + + private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) + { + if (comboBox1.Text == "Please select one:") { return; } + if (comboBox1.Text == "Local Sandbox") { runUrl=" - loginuri " + sandboxUrl;} + if (comboBox1.Text == "Local Grid Server") { runUrl = " - loginuri " + gridUrl; } + if (comboBox1.Text == "DeepGrid - www.deepgrid.com") { runUrl = " - loginuri " + deepGridUrl; } + if (comboBox1.Text == "OSGrid - www.osgrid.org") { runUrl = " - loginuri " + osGridUrl; } + if (comboBox1.Text == "Linden Labs - www.secondlife.com") { runUrl = ""; } + System.Diagnostics.Process proc = new System.Diagnostics.Process(); + proc.StartInfo.FileName = runLine; + proc.StartInfo.Arguments = exeFlags.ToString() + " " + runUrl; + proc.StartInfo.UseShellExecute = false; + proc.StartInfo.RedirectStandardOutput = false; + proc.StartInfo.WorkingDirectory = exePath.ToString(); + proc.Start(); + proc.WaitForExit(); + } + } +} \ No newline at end of file diff --git a/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Form1.resx b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Form1.resx new file mode 100644 index 0000000000..ff31a6db56 --- /dev/null +++ b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Form1.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/OpenSim/Tools/LaunchSLClient/LaunchSLClient/LaunchSLClient.csproj b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/LaunchSLClient.csproj new file mode 100644 index 0000000000..bc70f11c55 --- /dev/null +++ b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/LaunchSLClient.csproj @@ -0,0 +1,79 @@ + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {50FD2DCD-2E2D-413C-8260-D9CD22405895} + WinExe + Properties + LaunchSLClient + LaunchSLClient + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + Form + + + Form1.cs + + + + + + Designer + Form1.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + \ No newline at end of file diff --git a/OpenSim/Tools/LaunchSLClient/LaunchSLClient/LauncherException.cs b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/LauncherException.cs new file mode 100644 index 0000000000..7a2e861452 --- /dev/null +++ b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/LauncherException.cs @@ -0,0 +1,53 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Text; + +namespace LaunchSLClient +{ + class LauncherException : ApplicationException + { + + private const string CUSTOMMESSAGE = "The SL Client Launcher has failed with the following error: "; + + private LauncherException() { } + + public LauncherException(string errorMesssage, string source) + : base (CUSTOMMESSAGE + errorMesssage) + { + base.Source = source; + } + + public LauncherException(string errorMessage, string source, Exception innerException) + : base(CUSTOMMESSAGE + errorMessage, innerException) + { + base.Source = source; + } + } +} diff --git a/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Program.cs b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Program.cs new file mode 100644 index 0000000000..ba652a99be --- /dev/null +++ b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Program.cs @@ -0,0 +1,57 @@ +/* +* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.Windows.Forms; + + +namespace LaunchSLClient +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + + try + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new Form1()); + } + catch (Exception ex) + { + // Handles all unhandled errors + MessageBox.Show(ex.Message,"Unhandled Error"); + } + } + } +} \ No newline at end of file diff --git a/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Properties/AssemblyInfo.cs b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..4bd2cea179 --- /dev/null +++ b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("LaunchSLClient")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Home")] +[assembly: AssemblyProduct("LaunchSLClient")] +[assembly: AssemblyCopyright("Copyright © Home 2007")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("b08c6904-e6cc-4d9c-8d24-feb0464b1648")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Properties/Resources.Designer.cs b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Properties/Resources.Designer.cs new file mode 100644 index 0000000000..f9dfcc0f98 --- /dev/null +++ b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Properties/Resources.Designer.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.832 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace LaunchSLClient.Properties +{ + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources + { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() + { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager + { + get + { + if ((resourceMan == null)) + { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("LaunchSLClient.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture + { + get + { + return resourceCulture; + } + set + { + resourceCulture = value; + } + } + } +} diff --git a/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Properties/Resources.resx b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Properties/Resources.resx new file mode 100644 index 0000000000..ffecec851a --- /dev/null +++ b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Properties/Settings.Designer.cs b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Properties/Settings.Designer.cs new file mode 100644 index 0000000000..72c3ced2e9 --- /dev/null +++ b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Properties/Settings.Designer.cs @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.832 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace LaunchSLClient.Properties +{ + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase + { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default + { + get + { + return defaultInstance; + } + } + } +} diff --git a/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Properties/Settings.settings b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Properties/Settings.settings new file mode 100644 index 0000000000..abf36c5d3d --- /dev/null +++ b/OpenSim/Tools/LaunchSLClient/LaunchSLClient/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Prebuild/README b/Prebuild/README new file mode 100644 index 0000000000..eca6be17e2 --- /dev/null +++ b/Prebuild/README @@ -0,0 +1,230 @@ +Prebuild Instructions + +Prebuild is an XML-driven pre-build tool allowing developers to easily generate project or make files for major IDE's and .NET development tools including: Visual Studio 2005, Visual Studio 2003, Visual Studio 2002, SharpDevelop, SharpDevelop2, MonoDevelop, and NAnt. + +_________________________________________________________________________________ +Overview + +Prebuild can be either be run from the command line to generate the project and make files or you can execute the included batch (*.bat) and Unix Shell script (*.sh) files. +The Prebuild file + +_________________________________________________________________________________ +The currently supported developement tools and their associated batch and shell script files. + +Visual Studio .NET 2005 (VS2005.bat) +Visual Studio .NET 2003 (VS2003.bat) +Visual Studio .NET 2002 (VS2002.bat) +SharpDevelop (SharpDevelop.bat) - http://www.icsharpcode.net/OpenSource/SD/ +SharpDevelop2 (SharpDevelop.bat) - http://www.icsharpcode.net/OpenSource/SD/ +MonoDevelop (MonoDevelop.sh) - http://www.monodevelop.com/ +NAnt (nant.sh and nant.bat) - http://nant.sourceforge.net/ +Autotools (autotools.bat and autotools.sh) http://www.gnu.org. Only partial support + +Notes: +A Unix Shell script is provided for MonoDevelop, as this is more appropriate than a windows batch file. +Visual Studio .NET 2005 and the Visual Express IDE's can import solutions from older versions of Visual Studio .NET. +Makefiles are not currently supported. + +_________________________________________________________________________________ +Command Line Syntax: + +Example: +>Prebuild /target vs2003 + +This will generate the project files for Visual Studio.NET 2003 and place the redirect the log to a file named PrebuildLog.txt in the parent directory + + +The syntax structure is as below, where commandParameter is optional depending on the command and you can provide several option-value pairs. +Note: The '>' signified the command line, do not actually enter this manually + +>Prebuild /