diff --git a/AgentManager.cs b/AgentManager.cs new file mode 100644 index 0000000000..56d51a8509 --- /dev/null +++ b/AgentManager.cs @@ -0,0 +1,62 @@ +/* +* Copyright (c) OpenSim project, http://sim.opensecondlife.org/ +* +* 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 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 ``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 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 OpenSimLite +{ + /// + /// Manages Agent details. + /// + public class AgentManager + { + public AgentManager() + { + } + + public AgentName GetAgentName(LLUUID AgentID) + { + AgentName name = new AgentName(); + return(name); + } + } + + public struct AgentName + { + public string First; + public string Last; + } + + public class AgentProfile + { + public AgentProfile() + { + + } + } +} diff --git a/AssemblyInfo.cs b/AssemblyInfo.cs new file mode 100644 index 0000000000..88d8e1022e --- /dev/null +++ b/AssemblyInfo.cs @@ -0,0 +1,31 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +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("OpenSimLite")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("OpenSim project")] +[assembly: AssemblyProduct("OpenSimLite")] +[assembly: AssemblyCopyright("(c) OpenSim project")] +[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("0.2.*")] diff --git a/AssetManager.cs b/AssetManager.cs new file mode 100644 index 0000000000..81071901b8 --- /dev/null +++ b/AssetManager.cs @@ -0,0 +1,136 @@ +/* +* Copyright (c) OpenSim project, http://sim.opensecondlife.org/ +* +* 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 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 ``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 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; + +namespace OpenSimLite +{ + /// + /// Manages local cache of assets and their sending to viewers. + /// + public class AssetManager + { + public Dictionary Assets; + public Dictionary Textures; + private AssetServer _assetServer; + + /// + /// + /// + public AssetManager(AssetServer assetServer) + { + _assetServer=assetServer; + } + + /// + /// + /// + private void RunAssetManager() + { + + } + + /// + /// + /// + private void ProcessAssetQueue() + { + + } + + /// + /// + /// + private void ProcessTextureQueue() + { + + } + + #region Assets + /// + /// + /// + /// + /// + public void AddAssetRequest(NetworkInfo userInfo, TransferRequestPacket transferRequest) + { + LLUUID RequestID = new LLUUID(transferRequest.TransferInfo.Params, 0); + //check to see if asset is in local cache, if not we need to request it from asset server. + } + + #endregion + + #region Textures + /// + /// + /// + /// + /// + public void AddTextureRequest(NetworkInfo userInfo, LLUUID imageID) + { + //check to see if texture is in local cache, if not request from asset server + } + #endregion + + } + + public class AssetBase + { + public byte[] Data; + public LLUUID FullID; + public sbyte Type; + public sbyte InvType; + public string Name; + public string Description; + public string Filename; + + public AssetBase() + { + + } + } + + //needed? + public class TextureImage + { + public TextureImage() + { + + } + } + + public class AssetInfo + { + public AssetInfo() + { + + } + } +} diff --git a/AssetServer.cs b/AssetServer.cs new file mode 100644 index 0000000000..89b55f12bc --- /dev/null +++ b/AssetServer.cs @@ -0,0 +1,50 @@ +/* +* Copyright (c) OpenSim project, http://sim.opensecondlife.org/ +* +* 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 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 ``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 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 OpenSimLite +{ + /// + /// Handles connection to Asset Server. + /// + public class AssetServer + { + public AssetServer() + { + } + + private void Initialise() + { + if(Globals.Instance.LocalRunning) + { + //we are running not connected to a grid, so use local database + + } + } + } +} diff --git a/ClientConnection.cs b/ClientConnection.cs new file mode 100644 index 0000000000..70ebea690f --- /dev/null +++ b/ClientConnection.cs @@ -0,0 +1,167 @@ +/* +* Copyright (c) OpenSim project, http://sim.opensecondlife.org/ +* +* 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 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 ``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 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 libsecondlife; +using libsecondlife.Packets; + +namespace OpenSimLite +{ + /// + /// Hanldes a single clients connection. Runs in own thread. + /// + public class ClientConnection : CircuitConnection + { + public static GridManager Grid; + public static SceneGraph Scene; + + private Thread _mthread; + + public ClientConnection() + { + } + + public override void Start() + { + _mthread = new Thread(new ThreadStart(RunClientRead)); + _mthread.Start(); + } + + private void RunClientRead() + { + try + { + for(;;) + { + Packet packet = null; + packet=this.InQueue.Dequeue(); + switch(packet.Type) + { + case PacketType.UseCircuitCode: + //should be a new user joining + Console.WriteLine("new agent"); + break; + case PacketType.CompleteAgentMovement: + //Agent completing movement to region + Grid.SendRegionData(this.NetInfo); + break; + case PacketType.RegionHandshakeReply: + Console.WriteLine("RegionHandshake reply"); + Scene.SendTerrainData(this.NetInfo); + break; + default: + break; + } + } + } + catch (Exception e) + { + Console.WriteLine(e.Message); + } + } + } + + public class CircuitConnection + { + public BlockingQueue InQueue; + public NetworkInfo NetInfo; + + public CircuitConnection() + { + InQueue = new BlockingQueue(); + } + + public virtual void Start() + { + + } + } + + public class BlockingQueue< T > + { + private Queue< T > _queue = new Queue< T >(); + 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(); + } + } + } + + public class NonBlockingQueue< T > + { + private Queue< T > _queue = new Queue< T >(); + private object _queueSync = new object(); + + public void Enqueue(T value) + { + lock(_queueSync) + { + _queue.Enqueue(value); + } + } + + public T Dequeue() + { + T rValue = default(T); + lock(_queueSync) + { + if( _queue.Count > 0) + { + rValue = _queue.Dequeue(); + } + } + return rValue; + } + + public int Count + { + get + { + return(_queue.Count); + } + } + } + +} diff --git a/Controller.cs b/Controller.cs new file mode 100644 index 0000000000..608e2dd5e7 --- /dev/null +++ b/Controller.cs @@ -0,0 +1,97 @@ +/* +* +Copyright (c) OpenSim project, http://sim.opensecondlife.org/ +* +* 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 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 ``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 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; + +namespace OpenSimLite +{ + class Controller + { + private Server _viewerServer; + private BackboneServers _backboneServers; + private LoginServer _loginServer; + private GridManager _gridManager; + private AgentManager _agentManager; + private SceneGraph _scene; + + public static void Main(string[] args) + { + Controller c = new Controller(); + while( true ) + System.Threading.Thread.Sleep( 1000 ); + } + + public Controller() + { + _viewerServer = new Server(); + _backboneServers = new BackboneServers(); + _agentManager = new AgentManager(); + _gridManager = new GridManager(_viewerServer, _agentManager); + _scene = new SceneGraph(_viewerServer); + ClientConnection.Grid = _gridManager; + ClientConnection.Scene = _scene; + _viewerServer.Startup(); + + if(Globals.Instance.StartLoginServer) + { + _loginServer = new LoginServer(); + _loginServer.Startup(); + } + + } + + private void Initialise() + { + LoadSettings(); + + } + + private void LoadSettings() + { + + } + + } + + public class BackboneServers + { + public GridServer GridServer; + public UserServer UserServer; + public AssetServer AssetServer; + + public BackboneServers() + { + this.GridServer = new GridServer(); + this.UserServer = new UserServer(); + this.AssetServer = new AssetServer(); + } + } +} diff --git a/Globals.cs b/Globals.cs new file mode 100644 index 0000000000..331917e7d3 --- /dev/null +++ b/Globals.cs @@ -0,0 +1,85 @@ +/* +* Copyright (c) OpenSim project, http://sim.opensecondlife.org/ +* +* 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 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 ``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 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; + +namespace OpenSimLite +{ + /// + /// Description of Globals. + /// + public sealed class Globals + { + private static Globals instance = new Globals(); + private GridManager _grid; + + public static Globals Instance + { + get + { + return instance; + } + } + + public GridManager Grid + { + set + { + _grid = value; + } + } + + public bool LocalRunning = true; + public string SimIPAddress = "127.0.0.1"; + public int SimPort = 50000; + public string RegionName = "Test Sandbox\0"; + public ulong RegionHandle = 1096213093147648; + + public bool StartLoginServer = true; + public ushort LoginServerPort = 8080; + public List IncomingLogins = new List(); + + /// + /// + /// + private Globals() + { + } + + /// + /// + /// + /// + /// + public LLUUID RequestUUID(byte type) + { + return(_grid.RequestUUID(type)); + } + } +} diff --git a/GridManager.cs b/GridManager.cs new file mode 100644 index 0000000000..31c10473cd --- /dev/null +++ b/GridManager.cs @@ -0,0 +1,432 @@ +/* +* Copyright (c) OpenSim project, http://sim.opensecondlife.org/ +* +* 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 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 ``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 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 libsecondlife; +using libsecondlife.Packets; +using System.Collections.Generic; + +namespace OpenSimLite +{ + + /// + /// Description of GridManager. + /// + public class GridManager + { + + private Server _server; + private System.Text.Encoding _enc = System.Text.Encoding.ASCII; + private AgentManager _agentManager; + private libsecondlife.Packets.RegionHandshakePacket _regionPacket; + + public Dictionary Grid; + + /// + /// + /// + /// + /// + public GridManager(Server server, AgentManager agentManager) + { + Grid = new Dictionary(); + _server = server; + _agentManager = agentManager; + LoadGrid(); + InitialiseRegionHandshake(); + } + + + /// + /// + /// + /// + /// + public LLUUID RequestUUID(byte type) + { + //get next UUID in block for requested type; + return(LLUUID.Zero); + } + + public void InitialiseRegionHandshake() + { + _regionPacket = new RegionHandshakePacket(); + _regionPacket.RegionInfo.BillableFactor = 0; + _regionPacket.RegionInfo.IsEstateManager = false; + _regionPacket.RegionInfo.TerrainHeightRange00 = 60; + _regionPacket.RegionInfo.TerrainHeightRange01 = 60; + _regionPacket.RegionInfo.TerrainHeightRange10 = 60; + _regionPacket.RegionInfo.TerrainHeightRange11 = 60; + _regionPacket.RegionInfo.TerrainStartHeight00 = 20; + _regionPacket.RegionInfo.TerrainStartHeight01 = 20; + _regionPacket.RegionInfo.TerrainStartHeight10 = 20; + _regionPacket.RegionInfo.TerrainStartHeight11 = 20; + _regionPacket.RegionInfo.SimAccess = 13; + _regionPacket.RegionInfo.WaterHeight = 5; + _regionPacket.RegionInfo.RegionFlags = 72458694; + _regionPacket.RegionInfo.SimName = _enc.GetBytes( Globals.Instance.RegionName); + _regionPacket.RegionInfo.SimOwner = new LLUUID("00000000-0000-0000-0000-000000000000"); + _regionPacket.RegionInfo.TerrainBase0 = new LLUUID("b8d3965a-ad78-bf43-699b-bff8eca6c975"); + _regionPacket.RegionInfo.TerrainBase1 = new LLUUID("abb783e6-3e93-26c0-248a-247666855da3"); + _regionPacket.RegionInfo.TerrainBase2 = new LLUUID("179cdabd-398a-9b6b-1391-4dc333ba321f"); + _regionPacket.RegionInfo.TerrainBase3 = new LLUUID("beb169c7-11ea-fff2-efe5-0f24dc881df2"); + _regionPacket.RegionInfo.TerrainDetail0 = new LLUUID("00000000-0000-0000-0000-000000000000"); + _regionPacket.RegionInfo.TerrainDetail1 = new LLUUID("00000000-0000-0000-0000-000000000000"); + _regionPacket.RegionInfo.TerrainDetail2 = new LLUUID("00000000-0000-0000-0000-000000000000"); + _regionPacket.RegionInfo.TerrainDetail3 = new LLUUID("00000000-0000-0000-0000-000000000000"); + _regionPacket.RegionInfo.CacheID = LLUUID.Zero; // new LLUUID("545ec0a5-5751-1026-8a0b-216e38a7ab37"); + + } + + public void SendRegionData(NetworkInfo userInfo) + { + _server.SendPacket(_regionPacket,true, userInfo); + + //inform client of join comlete + libsecondlife.Packets.AgentMovementCompletePacket mov = new AgentMovementCompletePacket(); + mov.AgentData.SessionID = userInfo.User.SessionID; + mov.AgentData.AgentID = userInfo.User.AgentID; + mov.Data.RegionHandle = Globals.Instance.RegionHandle; + mov.Data.Timestamp = 1169838966; + mov.Data.Position = new LLVector3(100f, 100f, 22f); + mov.Data.LookAt = new LLVector3(0.99f, 0.042f, 0); + _server.SendPacket(mov, true, userInfo); + } + + /// + /// + /// + /// + public void RequestMapLayer(NetworkInfo userInfo) + { + //send a layer covering the 800,800 - 1200,1200 area + MapLayerReplyPacket MapReply = new MapLayerReplyPacket(); + MapReply.AgentData.AgentID = userInfo.User.AgentID; + MapReply.AgentData.Flags = 0; + MapReply.LayerData = new MapLayerReplyPacket.LayerDataBlock[1]; + MapReply.LayerData[0] = new MapLayerReplyPacket.LayerDataBlock(); + MapReply.LayerData[0].Bottom = 800; + MapReply.LayerData[0].Left = 800; + MapReply.LayerData[0].Top = 1200; + MapReply.LayerData[0].Right = 1200; + MapReply.LayerData[0].ImageID = new LLUUID("00000000-0000-0000-7007-000000000006"); + _server.SendPacket(MapReply, true, userInfo); + } + + /// + /// + /// + /// + /// + /// + /// + /// + public void RequestMapBlock(NetworkInfo userInfo, int minX, int minY,int maxX,int maxY) + { + foreach (KeyValuePair regionPair in this.Grid) + { + //check Region is inside the requested area + RegionInfo Region = regionPair.Value; + if(((Region.X > minX) && (Region.X < maxX)) && ((Region.Y > minY) && (Region.Y < maxY))) + { + MapBlockReplyPacket MapReply = new MapBlockReplyPacket(); + MapReply.AgentData.AgentID = userInfo.User.AgentID; + MapReply.AgentData.Flags = 0; + MapReply.Data = new MapBlockReplyPacket.DataBlock[1]; + MapReply.Data[0] = new MapBlockReplyPacket.DataBlock(); + MapReply.Data[0].MapImageID = Region.ImageID; + MapReply.Data[0].X = Region.X; + MapReply.Data[0].Y = Region.Y; + MapReply.Data[0].WaterHeight = Region.WaterHeight; + MapReply.Data[0].Name = _enc.GetBytes( Region.Name); + MapReply.Data[0].RegionFlags = 72458694; + MapReply.Data[0].Access = 13; + MapReply.Data[0].Agents = 1; + _server.SendPacket(MapReply, true, userInfo); + } + } + + } + + /// + /// + /// + /// + /// + public void RequestTeleport(NetworkInfo userInfo, TeleportLocationRequestPacket request) + { + if(Grid.ContainsKey(request.Info.RegionHandle)) + { + RegionInfo Region = Grid[request.Info.RegionHandle]; + libsecondlife.Packets.TeleportStartPacket TeleportStart = new TeleportStartPacket(); + TeleportStart.Info.TeleportFlags = 16; + _server.SendPacket(TeleportStart, true, userInfo); + + libsecondlife.Packets.TeleportFinishPacket Teleport = new TeleportFinishPacket(); + Teleport.Info.AgentID = userInfo.User.AgentID; + Teleport.Info.RegionHandle = request.Info.RegionHandle; + Teleport.Info.SimAccess = 13; + Teleport.Info.SeedCapability = new byte[0]; + + System.Net.IPAddress oIP = System.Net.IPAddress.Parse(Region.IPAddress.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 = Region.IPAddress.Port; + Teleport.Info.LocationID = 4; + Teleport.Info.TeleportFlags = 1 << 4;; + _server.SendPacket(Teleport, true, userInfo); + + //this._agentManager.RemoveAgent(userInfo); + } + + } + + /// + /// + /// + private void LoadGrid() + { + //should connect to a space server to see what grids there are + //but for now we read static xml files + ulong CurrentHandle = 0; + bool Login = true; + + XmlDocument doc = new XmlDocument(); + + try { + doc.Load(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Grid.ini" )); + } + catch ( Exception e) + { + Console.WriteLine(e.Message); + return; + } + + try + { + XmlNode root = doc.FirstChild; + if (root.Name != "Root") + throw new Exception("Error: Invalid File. Missing "); + + XmlNode nodes = root.FirstChild; + if (nodes.Name != "Grid") + throw new Exception("Error: Invalid File. first child should be "); + + if (nodes.HasChildNodes) { + foreach( XmlNode xmlnc in nodes.ChildNodes) + { + if(xmlnc.Name == "Region") + { + string xmlAttri; + RegionInfo Region = new RegionInfo(); + if(xmlnc.Attributes["Name"] != null) + { + xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("Name")).Value; + Region.Name = xmlAttri+" \0"; + } + if(xmlnc.Attributes["ImageID"] != null) + { + xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("ImageID")).Value; + Region.ImageID = new LLUUID(xmlAttri); + } + if(xmlnc.Attributes["IP_Address"] != null) + { + xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("IP_Address")).Value; + Region.IPAddress.Address = xmlAttri; + } + if(xmlnc.Attributes["IP_Port"] != null) + { + xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("IP_Port")).Value; + Region.IPAddress.Port = Convert.ToUInt16(xmlAttri); + } + if(xmlnc.Attributes["Location_X"] != null) + { + xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("Location_X")).Value; + Region.X = Convert.ToUInt16(xmlAttri); + } + if(xmlnc.Attributes["Location_Y"] != null) + { + xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("Location_Y")).Value; + Region.Y = Convert.ToUInt16(xmlAttri); + } + + this.Grid.Add(Region.Handle, Region); + + } + if(xmlnc.Name == "CurrentRegion") + { + + string xmlAttri; + uint Rx = 0, Ry = 0; + if(xmlnc.Attributes["RegionHandle"] != null) + { + xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("RegionHandle")).Value; + CurrentHandle = Convert.ToUInt64(xmlAttri); + + } + else + { + if(xmlnc.Attributes["Region_X"] != null) + { + xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("Region_X")).Value; + Rx = Convert.ToUInt32(xmlAttri); + } + if(xmlnc.Attributes["Region_Y"] != null) + { + xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("Region_Y")).Value; + Ry = Convert.ToUInt32(xmlAttri); + } + } + if(xmlnc.Attributes["LoginServer"] != null) + { + xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("LoginServer")).Value; + Login = Convert.ToBoolean(xmlAttri); + + } + if(CurrentHandle == 0) + { + //no RegionHandle set + //so check for Region X and Y + if((Rx > 0) && (Ry > 0)) + { + CurrentHandle = Helpers.UIntsToLong((Rx*256), (Ry*256)); + } + else + { + //seems to be no Region location set + // so set default + CurrentHandle = 1096213093147648; + } + } + } + } + + //finished loading grid, now set Globals to current region + if(CurrentHandle != 0) + { + if(Grid.ContainsKey(CurrentHandle)) + { + RegionInfo Region = Grid[CurrentHandle]; + Globals.Instance.RegionHandle = Region.Handle; + Globals.Instance.RegionName = Region.Name; + Globals.Instance.SimPort = Region.IPAddress.Port; + Globals.Instance.StartLoginServer = Login; + } + } + + } + } + catch ( Exception e) + { + Console.WriteLine(e.Message); + return; + } + } + } + + public class RegionInfo + { + public RegionIP IPAddress; + public string Name; + private ushort _x; + private ushort _y; + private ulong _handle; + public LLUUID ImageID; + public uint Flags; + public byte WaterHeight; + + public ushort X + { + get + { + return(_x); + } + set + { + _x = value; + Handle = Helpers.UIntsToLong((((uint)_x)*256), (((uint)_y)*256)); + } + } + public ushort Y + { + get + { + return(_y); + } + set + { + _y = value; + Handle = Helpers.UIntsToLong((((uint)_x)*256), (((uint)_y)*256)); + } + } + public ulong Handle + { + get + { + if(_handle > 0) + { + return(_handle); + } + else + { + //should never be called but just incase + return(Helpers.UIntsToLong((((uint)_x)*256), (((uint)_y)*256))); + } + } + set + { + _handle = value; + } + + } + + public RegionInfo() + { + this.IPAddress = new RegionIP(); + } + } + + public class RegionIP + { + public string Address; + public ushort Port; + + public RegionIP() + { + + } + + } + +} diff --git a/GridServer.cs b/GridServer.cs new file mode 100644 index 0000000000..87a3b25ec3 --- /dev/null +++ b/GridServer.cs @@ -0,0 +1,42 @@ +/* +* Copyright (c) OpenSim project, http://sim.opensecondlife.org/ +* +* 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 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 ``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 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 OpenSimLite +{ + /// + /// Handles connection to Grid Servers. + /// also Sim to Sim connections? + /// + public class GridServer + { + public GridServer() + { + } + } +} diff --git a/InstantMessaging.cs b/InstantMessaging.cs new file mode 100644 index 0000000000..da40d86625 --- /dev/null +++ b/InstantMessaging.cs @@ -0,0 +1,41 @@ +/* +* Copyright (c) OpenSim project, http://sim.opensecondlife.org/ +* +* 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 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 ``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 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 OpenSimLite +{ + /// + /// Description of InstantMessaging. + /// + public class InstantMessaging + { + public InstantMessaging() + { + } + } +} diff --git a/InventoryManager.cs b/InventoryManager.cs new file mode 100644 index 0000000000..c6aedb605a --- /dev/null +++ b/InventoryManager.cs @@ -0,0 +1,105 @@ +/* +* Copyright (c) OpenSim project, http://sim.opensecondlife.org/ +* +* 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 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 ``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 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; + +namespace OpenSimLite +{ + /// + /// Local cache of Inventories + /// + public class InventoryManager + { + private List _agentsInventory; + private List _serverRequests; //list of requests made to user server. + + public InventoryManager() + { + _agentsInventory = new List(); + _serverRequests = new List(); + } + } + + public class AgentInventory + { + //Holds the local copy of Inventory info for a agent + public List Folders; + public int LastCached; //time this was last stored/compared to user server + public LLUUID AgentID; + + public AgentInventory() + { + Folders = new List(); + } + } + + public class InventoryFolder + { + public List Items; + //public List Subfolders; + public LLUUID FolderID; + public LLUUID OwnerID; + public LLUUID ParentID; + public string Name; + public byte Type; + + 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 class UserServerRequest + { + public UserServerRequest() + { + + } + } +} diff --git a/LoginServer.cs b/LoginServer.cs new file mode 100644 index 0000000000..b49e5077d8 --- /dev/null +++ b/LoginServer.cs @@ -0,0 +1,250 @@ +/* +* Copyright (c) OpenSim project, http://sim.opensecondlife.org/ +* +* 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 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 ``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 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; +using System; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Collections; +using System.Xml; +using libsecondlife; + +namespace OpenSimLite +{ + /// + /// When running in local (default) mode , handles client logins. + /// + public class LoginServer + { + public LoginServer() + { + + } + private Logon _login; + private ushort _loginPort = Globals.Instance.LoginServerPort; + public IPAddress clientAddress = IPAddress.Loopback; + public IPAddress remoteAddress = IPAddress.Any; + private Socket loginServer; + private Random RandomClass = new Random(); + private int NumClients; + private string _defaultResponse; + + // InitializeLoginProxy: initialize the login proxy + private void InitializeLoginProxy() { + loginServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + loginServer.Bind(new IPEndPoint(remoteAddress, _loginPort)); + loginServer.Listen(1); + + //read in default response string + StreamReader SR; + string lines; + SR=File.OpenText("new-login.dat"); + + lines=SR.ReadLine(); + + while(lines != "end-mfile") + { + _defaultResponse += lines; + lines = SR.ReadLine(); + } + SR.Close(); + } + + public void Startup() + { + this.InitializeLoginProxy(); + Thread runLoginProxy = new Thread(new ThreadStart(RunLoginProxy)); + runLoginProxy.IsBackground = true; + runLoginProxy.Start(); + } + + private void RunLoginProxy() + { + Console.WriteLine("Starting Login Sever"); + try + { + for (;;) + { + Socket client = loginServer.Accept(); + IPEndPoint clientEndPoint = (IPEndPoint)client.RemoteEndPoint; + + + NetworkStream networkStream = new NetworkStream(client); + StreamReader networkReader = new StreamReader(networkStream); + StreamWriter networkWriter = new StreamWriter(networkStream); + + try + { + ProxyLogin(networkReader, networkWriter); + } + catch (Exception e) + { + Console.WriteLine(e.Message); + } + + networkWriter.Close(); + networkReader.Close(); + networkStream.Close(); + + client.Close(); + + // send any packets queued for injection + + } + } + catch (Exception e) + { + Console.WriteLine(e.Message); + Console.WriteLine(e.StackTrace); + } + } + + // ProxyLogin: proxy a login request + private void ProxyLogin(StreamReader reader, StreamWriter writer) { lock(this) { + string line; + int contentLength = 0; + + // read HTTP header + do + { + // read one line of the header + line = reader.ReadLine(); + + // check for premature EOF + if (line == null) + throw new Exception("EOF in client HTTP header"); + + // look for Content-Length + Match match = (new Regex(@"Content-Length: (\d+)$")).Match(line); + if (match.Success) + contentLength = Convert.ToInt32(match.Groups[1].Captures[0].ToString()); + } while (line != ""); + + // read the HTTP body into a buffer + this._login = new Logon(); + char[] content = new char[contentLength]; + reader.Read(content, 0, contentLength); + //System.Text.Encoding enc = System.Text.Encoding.ASCII; + XmlRpcRequest request = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(new String(content)); + Hashtable requestData = (Hashtable)request.Params[0]; + + string first; + string last; + LLUUID Agent; + LLUUID Session; + + //get login name + if(requestData.Contains("first")) + { + first = (string)requestData["first"]; + } + else + { + first = "test"; + } + if(requestData.Contains("last")) + { + last = (string)requestData["last"]; + } + else + { + last = "User"+NumClients.ToString(); + } + NumClients++; + + //create a agent and session LLUUID + int AgentRand = this.RandomClass.Next(1,9999); + Agent = new LLUUID("99998888-4000-"+AgentRand.ToString("0000")+"-8ec1-0b1d5cd6aead"); + int SessionRand = this.RandomClass.Next(1,999); + Session = new LLUUID("aaaabbbb-5000-"+SessionRand.ToString("0000")+"-8664-58f53e442797"); + + + XmlRpcResponse response =(XmlRpcResponse)(new XmlRpcResponseDeserializer()).Deserialize(this._defaultResponse); + Hashtable responseData = (Hashtable)response.Value; + + responseData["sim_port"] = Globals.Instance.SimPort; + responseData["sim_ip"] = Globals.Instance.SimIPAddress; + responseData["agent_id"] = Agent.ToStringHyphenated(); + responseData["session_id"] = Session.ToStringHyphenated(); + ArrayList InventoryList = (ArrayList) responseData["inventory-skeleton"]; + Hashtable Inventory1 = (Hashtable)InventoryList[0]; + Hashtable Inventory2 = (Hashtable)InventoryList[1]; + LLUUID BaseFolderID = LLUUID.Random(); + LLUUID InventoryFolderID = LLUUID.Random(); + Inventory2["name"] = "Base"; + Inventory2["folder_id"] = BaseFolderID.ToStringHyphenated(); + Inventory2["type_default"] =6; + Inventory1["folder_id"] = InventoryFolderID.ToStringHyphenated(); + + ArrayList InventoryRoot = (ArrayList) responseData["inventory-root"]; + Hashtable Inventoryroot = (Hashtable)InventoryRoot[0]; + Inventoryroot["folder_id"] = InventoryFolderID.ToStringHyphenated(); + + + //copy data to login object + _login.First = first; + _login.Last = last; + _login.Agent = Agent; + _login.Session = Session; + _login.BaseFolder = BaseFolderID; + _login.InventoryFolder = InventoryFolderID; + + lock(Globals.Instance.IncomingLogins) + { + Globals.Instance.IncomingLogins.Add(_login); + } + + // forward the XML-RPC response to the client + writer.WriteLine("HTTP/1.0 200 OK"); + writer.WriteLine("Content-type: text/xml"); + writer.WriteLine(); + + XmlTextWriter responseWriter = new XmlTextWriter(writer); + XmlRpcResponseSerializer.Singleton.Serialize(responseWriter, response); + responseWriter.Close(); + } + } + } + + public class Logon + { + public string First = "Test"; + public string Last = "User"; + public LLUUID Agent; + public LLUUID Session; + public LLUUID InventoryFolder; + public LLUUID BaseFolder; + public Logon() + { + + } + } +} diff --git a/OpenSimLite.csproj b/OpenSimLite.csproj new file mode 100644 index 0000000000..0150eb933f --- /dev/null +++ b/OpenSimLite.csproj @@ -0,0 +1,56 @@ + + + Exe + OpenSimLite + OpenSimLite + Debug + AnyCPU + {782CCAFD-7313-4638-ADAC-53703DF24DF0} + + + bin\Debug\ + False + DEBUG;TRACE + True + Full + True + + + bin\Release\ + True + TRACE + False + None + False + + + + + + + bin\Debug\libsecondlife.dll + False + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OpenSimLite.sln b/OpenSimLite.sln new file mode 100644 index 0000000000..9b6d19a5ca --- /dev/null +++ b/OpenSimLite.sln @@ -0,0 +1,17 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# SharpDevelop 2.1.0.2017 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSimLite", "OpenSimLite.csproj", "{782CCAFD-7313-4638-ADAC-53703DF24DF0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {782CCAFD-7313-4638-ADAC-53703DF24DF0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {782CCAFD-7313-4638-ADAC-53703DF24DF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {782CCAFD-7313-4638-ADAC-53703DF24DF0}.Release|Any CPU.Build.0 = Release|Any CPU + {782CCAFD-7313-4638-ADAC-53703DF24DF0}.Release|Any CPU.ActiveCfg = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/PhysicsManager.cs b/PhysicsManager.cs new file mode 100644 index 0000000000..62e2016bd0 --- /dev/null +++ b/PhysicsManager.cs @@ -0,0 +1,44 @@ +/* +* Copyright (c) OpenSim project, http://sim.opensecondlife.org/ +* +* 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 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 ``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 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 OpenSimLite +{ + /// + /// Description of PhysicsManager. + /// + public class PhysicsManager + { + private SceneGraph _sceneGraph; + + public PhysicsManager(SceneGraph sceneGraph) + { + _sceneGraph=sceneGraph; + } + } +} diff --git a/PrimManager.cs b/PrimManager.cs new file mode 100644 index 0000000000..27a77de8ef --- /dev/null +++ b/PrimManager.cs @@ -0,0 +1,41 @@ +/* +* Copyright (c) OpenSim project, http://sim.opensecondlife.org/ +* +* 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 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 ``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 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 OpenSimLite +{ + /// + /// Manages and provides local cache of Prims. + /// + public class PrimManager + { + public PrimManager() + { + } + } +} diff --git a/SceneGraph.cs b/SceneGraph.cs new file mode 100644 index 0000000000..66f8bb696c --- /dev/null +++ b/SceneGraph.cs @@ -0,0 +1,378 @@ +/* +* Copyright (c) OpenSim project, http://sim.opensecondlife.org/ +* +* 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 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 ``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 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.Threading; +using libsecondlife; +using libsecondlife.Packets; + +namespace OpenSimLite +{ + /// + /// Manages prim and avatar sim positions and movements and updating clients + /// + public class SceneGraph + { + public Node RootNode; + public Terrain Terrain; + private PhysicsManager _physics; + private Server _server; + private System.Text.Encoding _enc = System.Text.Encoding.ASCII; + private libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock _avatarTemplate; + + public NonBlockingQueue Commands; + + #region Thread Sync + //public object CommandsSync = new object(); + private object _sendTerrainSync = new object(); + #endregion + + public SceneGraph(Server server) + { + _server = server; + RootNode = new Node(); + _physics = new PhysicsManager(this); + Commands = new NonBlockingQueue(); + Terrain = new Terrain(); + + //testing + this.SetupTemplate("objectupate168.dat"); + } + + public void Update() + { + + } + + #region send terrain data + /// + /// + /// + /// + public void SendTerrainData(NetworkInfo userInfo) + { + lock(this._sendTerrainSync) + { + string data_path = System.AppDomain.CurrentDomain.BaseDirectory + @"\layer_data\"; + + //send layerdata + LayerDataPacket layerpack = new LayerDataPacket(); + layerpack.LayerID.Type = 76; + this.SendLayerData(userInfo, layerpack, data_path+@"layerdata0.dat"); + Console.WriteLine("Sent terrain data"); + this.SendAvatarData(userInfo); + } + } + + /// + /// + /// + /// + /// + /// + private void SendLayerData(NetworkInfo userInfo, LayerDataPacket layer, string fileName) + { + FileInfo fInfo = new FileInfo(fileName); + long numBytes = fInfo.Length; + FileStream fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read); + BinaryReader br = new BinaryReader(fStream); + byte [] data1 = br.ReadBytes((int)numBytes); + br.Close(); + fStream.Close(); + layer.LayerData.Data = data1; + _server.SendPacket(layer, true, userInfo); + + } + #endregion + + #region testing + //test only + private void SendAvatarData(NetworkInfo userInfo) + { + ObjectUpdatePacket objupdate = new ObjectUpdatePacket(); + objupdate.RegionData.RegionHandle = Globals.Instance.RegionHandle; + objupdate.RegionData.TimeDilation = 64096; + objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1]; + + objupdate.ObjectData[0] = _avatarTemplate; + //give this avatar object a local id and assign the user a name + objupdate.ObjectData[0].ID = 8880000;// + this._localNumber; + userInfo.User.AvatarLocalID = objupdate.ObjectData[0].ID; + //User_info.name="Test"+this.local_numer+" User"; + //this.GetAgent(userInfo.UserAgentID).Started = true; + objupdate.ObjectData[0].FullID = userInfo.User.AgentID; + objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + userInfo.User.FirstName + "\nLastName STRING RW SV " + userInfo.User.LastName + " \0"); + //userInfo.User.FullName = "FirstName STRING RW SV " + userInfo.first_name + "\nLastName STRING RW SV " + userInfo.last_name + " \0"; + + libsecondlife.LLVector3 pos2 = new LLVector3(100f, 100.0f, 22.0f); + byte[] pb = pos2.GetBytes(); + Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length); + + //this._localNumber++; + _server.SendPacket(objupdate, true, userInfo); + } + + //test only + private void SetupTemplate(string name) + { + + int i = 0; + FileInfo fInfo = new FileInfo(name); + long numBytes = fInfo.Length; + FileStream fStream = new FileStream(name, FileMode.Open, FileAccess.Read); + BinaryReader br = new BinaryReader(fStream); + byte [] data1 = br.ReadBytes((int)numBytes); + br.Close(); + fStream.Close(); + + libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock objdata = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i); + + System.Text.Encoding enc = System.Text.Encoding.ASCII; + libsecondlife.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"); + libsecondlife.LLVector3 pos2 = new LLVector3(13.981f,100.0f,20.0f); + //objdata.FullID=user.AgentID; + byte[] pb = pos.GetBytes(); + Array.Copy(pb, 0, objdata.ObjectData, 16, pb.Length); + + _avatarTemplate = objdata; + + } + #endregion + + } + + //any need for separate nodes and sceneobjects? + //do we need multiple objects in the same node? + public class Node + { + private List _children; + private List _attached; + + public List ChildNodes + { + get + { + return(_children); + } + } + + public List AttachedObjexts + { + get + { + return(_attached); + } + } + + public Node() + { + _children = new List(); + _attached = new List(); + } + + /// + /// + /// + /// + /// + public SceneObject GetAttachedObject(int index) + { + if(_attached.Count > index) + { + return(_attached[index]); + } + else + { + return(null); + } + } + + /// + /// + /// + /// + public void AttachObject(SceneObject sceneObject) + { + _attached.Add(sceneObject); + } + + /// + /// + /// + /// + public void RemoveObject(SceneObject sceneObject) + { + _attached.Remove(sceneObject); + } + + /// + /// + /// + /// + /// + public int HasAttachedObject(SceneObject sceneObject) + { + int rValue = -1; + for(int i = 0; i < this._attached.Count; i++) + { + if(sceneObject == this._attached[i]) + { + rValue = i; + } + } + return(rValue); + } + + /// + /// + /// + /// + /// + public Node GetChild(int index) + { + if(_children.Count > index) + { + return(_children[index]); + } + else + { + return(null); + } + } + + /// + /// + /// + /// + public void AddChild(Node node) + { + _children.Add(node); + } + + /// + /// + /// + /// + public void RemoveChild(Node node) + { + _children.Remove(node); + } + } + + public class SceneObject + { + public byte SceneType; + + public SceneObject() + { + + } + } + + public class Terrain + { + public List Vertices; + public List Faces; + + public Terrain() + { + Vertices = new List(); + Faces = new List(); + } + + public LLVector3 CastRay() + { + return(new LLVector3(0,0,0)); + } + } + + public class Face + { + public int V1; + public int V2; + public int V3; + + public Face() + { + + } + } + + public class UpdateCommand + { + public byte CommandType; + public SceneObject SObject; + public LLVector3 Position; + public LLVector3 Velocity; + public LLQuaternion Rotation; + + public UpdateCommand() + { + + } + } + + public class UpdateSender + { + public BlockingQueue SendList; + private Thread mthread; + + public UpdateSender() + { + SendList = new BlockingQueue(); + } + + public void Startup() + { + mthread = new Thread(new System.Threading.ThreadStart(RunSender)); + mthread.Start(); + } + + private void RunSender() + { + + } + } + + public class SendInfo + { + public Packet Packet; + public bool Incr; + public NetworkInfo NetInfo; + + public SendInfo() + { + + } + } +} + diff --git a/ScriptManager.cs b/ScriptManager.cs new file mode 100644 index 0000000000..656fdd2de7 --- /dev/null +++ b/ScriptManager.cs @@ -0,0 +1,53 @@ +/* +* Copyright (c) OpenSim project, http://sim.opensecondlife.org/ +* +* 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 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 ``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 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 OpenSimLite +{ + /// + /// Description of ScriptManager. + /// + public class ScriptManager + { + public ScriptManager() + { + } + } + + public interface ScriptPlugin + { + ScriptObject ICompileScript(string script); + bool IStart(); + } + + public interface ScriptObject + { + void on_rez(int number); + void touch(int number); + } +} diff --git a/UserServer.cs b/UserServer.cs new file mode 100644 index 0000000000..f272ed2991 --- /dev/null +++ b/UserServer.cs @@ -0,0 +1,51 @@ +/* +* Copyright (c) OpenSim project, http://sim.opensecondlife.org/ +* +* 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 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 ``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 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 OpenSimLite +{ + /// + /// Handles connection to User Servers + /// + /// + public class UserServer + { + public UserServer() + { + } + + private void Initialise() + { + if(Globals.Instance.LocalRunning) + { + //we are running not connected to a grid, so use local database + + } + } + } +} diff --git a/ViewerServer.cs b/ViewerServer.cs new file mode 100644 index 0000000000..d39f459b84 --- /dev/null +++ b/ViewerServer.cs @@ -0,0 +1,670 @@ +/* +* Copyright (c) OpenSim project, http://sim.opensecondlife.org/ +* +* 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 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 ``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 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 System.Collections; +using libsecondlife.Packets; +using libsecondlife.AssetSystem; +using System.Net; +using System.Net.Sockets; +using System.Timers; + +namespace OpenSimLite +{ + /// + /// Manages Viewer connections + /// + /*public class ViewerServer + { + public ViewerServer() + { + } + } + + public class ViewerNetInfo + { + public ViewerNetInfo() + { + + } + }*/ + + //for now though, we will use a slightly adapted version of the server + // class from version 0.1 + public class Server + { + /// A public reference to the client that this Simulator object + /// is attached to + //public SecondLife Client; + + /// The Region class that this Simulator wraps + // public Region Region; + + /// + /// Used internally to track sim disconnections, do not modify this + /// variable + /// + public bool DisconnectCandidate = false; + + /// + /// The ID number associated with this particular connection to the + /// simulator, used to emulate TCP connections. This is used + /// internally for packets that have a CircuitCode field + /// + public uint CircuitCode + { + get { return circuitCode; } + set { circuitCode = value; } + } + + /// + /// The IP address and port of the server + /// + public IPEndPoint IPEndPoint + { + get { return ipEndPoint; } + } + + /// + /// A boolean representing whether there is a working connection to the + /// simulator or not + /// + public bool Connected + { + get { return connected; } + } + + private uint Sequence = 0; + private object SequenceLock = new object(); + private byte[] RecvBuffer = new byte[4096]; + private byte[] ZeroBuffer = new byte[8192]; + private byte[] ZeroOutBuffer = new byte[4096]; + private Socket Connection = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + private AsyncCallback ReceivedData; + private bool connected = false; + private uint circuitCode; + private IPEndPoint ipEndPoint; + private EndPoint endPoint; + private IPEndPoint ipeSender; + private EndPoint epSender; + private System.Timers.Timer AckTimer; + private Server_Settings Settings=new Server_Settings(); + public ArrayList User_agents=new ArrayList(); + + /// + /// + /// + public Server() + { + + } + + /// + /// + /// + public void Startup() + { + AckTimer = new System.Timers.Timer(Settings.NETWORK_TICK_LENGTH); + AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed); + + // Initialize the callback for receiving a new packet + ReceivedData = new AsyncCallback(this.OnReceivedData); + + // Client.Log("Connecting to " + ip.ToString() + ":" + port, Helpers.LogLevel.Info); + + try + { + // Create an endpoint that we will be communicating with (need it in two + // types due to .NET weirdness) + // ipEndPoint = new IPEndPoint(ip, port); + ipEndPoint = new IPEndPoint(IPAddress.Any, Globals.Instance.SimPort); + endPoint = (EndPoint)ipEndPoint; + + // Associate this simulator's socket with the given ip/port and start listening + Connection.Bind(endPoint); + ipeSender = new IPEndPoint(IPAddress.Any, 0); + //The epSender identifies the incoming clients + epSender = (EndPoint) ipeSender; + Connection.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); + + // Start the ACK timer + AckTimer.Start(); + } + catch (Exception e) + { + + System.Console.WriteLine(e.Message); + } + } + + /// + /// Disconnect a Simulator + /// + public void Disconnect() + { + if (connected) + { + connected = false; + AckTimer.Stop(); + + // Send the CloseCircuit notice + CloseCircuitPacket close = new CloseCircuitPacket(); + + if (Connection.Connected) + { + try + { + // Connection.Send(close.ToBytes()); + } + catch (SocketException) + { + // There's a high probability of this failing if the network is + // disconnecting, so don't even bother logging the error + } + } + + try + { + // Shut the socket communication down + // Connection.Shutdown(SocketShutdown.Both); + } + catch (SocketException) + { + } + } + } + + /// + /// Sends a packet + /// + /// Packet to be sent + /// Increment sequence number? + public void SendPacket(Packet packet, bool incrementSequence, NetworkInfo User_info) + { + byte[] buffer; + int bytes; + + if (!connected && packet.Type != PacketType.UseCircuitCode) + { + // Client.Log("Trying to send a " + packet.Type.ToString() + " packet when the socket is closed", + // Helpers.LogLevel.Info); + + return; + } + + if (packet.Header.AckList.Length > 0) + { + // Scrub any appended ACKs since all of the ACK handling is done here + packet.Header.AckList = new uint[0]; + } + packet.Header.AppendedAcks = false; + + // Keep track of when this packet was sent out + packet.TickCount = Environment.TickCount; + + if (incrementSequence) + { + // Set the sequence number + lock (SequenceLock) + { + if (Sequence > Settings.MAX_SEQUENCE) + Sequence = 1; + else + Sequence++; + packet.Header.Sequence = Sequence; + } + + if (packet.Header.Reliable) + { + lock (User_info.NeedAck) + { + if (!User_info.NeedAck.ContainsKey(packet.Header.Sequence)) + { + User_info.NeedAck.Add(packet.Header.Sequence, packet); + } + 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 (!packet.Header.Resent) + { + // Append any ACKs that need to be sent out to this packet + lock (User_info.PendingAcks) + { + if (User_info.PendingAcks.Count > 0 && User_info.PendingAcks.Count < Settings.MAX_APPENDED_ACKS && + packet.Type != PacketType.PacketAck && + packet.Type != PacketType.LogoutRequest) + { + packet.Header.AckList = new uint[User_info.PendingAcks.Count]; + int i = 0; + + foreach (uint ack in User_info.PendingAcks.Values) + { + packet.Header.AckList[i] = ack; + i++; + } + + User_info.PendingAcks.Clear(); + packet.Header.AppendedAcks = true; + } + } + } + } + } + + // Serialize the packet + buffer = packet.ToBytes(); + bytes = buffer.Length; + + try + { + // Zerocode if needed + if (packet.Header.Zerocoded) + { + lock (ZeroOutBuffer) + { + bytes = Helpers.ZeroEncode(buffer, bytes, ZeroOutBuffer); + Connection.SendTo(ZeroOutBuffer, bytes, SocketFlags.None,User_info.endpoint); + } + } + else + { + + Connection.SendTo(buffer, bytes, SocketFlags.None,User_info.endpoint); + } + } + catch (SocketException) + { + //Client.Log("Tried to send a " + packet.Type.ToString() + " on a closed socket", + // Helpers.LogLevel.Warning); + + Disconnect(); + } + } + + /// + /// Send a raw byte array payload as a packet + /// + /// The packet payload + /// Whether the second, third, and fourth bytes + /// should be modified to the current stream sequence number + /// + /// Returns Simulator Name as a String + /// + /// + public override string ToString() + { + return( " (" + ipEndPoint.ToString() + ")"); + } + + /// + /// Sends out pending acknowledgements + /// + private void SendAcks(NetworkInfo User_info) + { + lock (User_info.PendingAcks) + { + if (connected && User_info.PendingAcks.Count > 0) + { + if (User_info.PendingAcks.Count > 250) + { + // FIXME: Handle the odd case where we have too many pending ACKs queued up + //Client.Log("Too many ACKs queued up!", Helpers.LogLevel.Error); + return; + } + + int i = 0; + PacketAckPacket acks = new PacketAckPacket(); + acks.Packets = new PacketAckPacket.PacketsBlock[User_info.PendingAcks.Count]; + + foreach (uint ack in User_info.PendingAcks.Values) + { + acks.Packets[i] = new PacketAckPacket.PacketsBlock(); + acks.Packets[i].ID = ack; + i++; + } + + acks.Header.Reliable = false; + SendPacket(acks, true,User_info); + + User_info.PendingAcks.Clear(); + } + } + } + /// + /// Resend unacknowledged packets + /// + private void ResendUnacked(NetworkInfo User_info) + { + if (connected) + { + int now = Environment.TickCount; + + lock (User_info.NeedAck) + { + foreach (Packet packet in User_info.NeedAck.Values) + { + if (now - packet.TickCount > Settings.RESEND_TIMEOUT) + { + // Client.Log("Resending " + packet.Type.ToString() + " packet, " + + // (now - packet.TickCount) + "ms have passed", Helpers.LogLevel.Info); + + packet.Header.Resent = true; + SendPacket(packet, false,User_info); + } + } + } + } + } + /// + /// Callback handler for incomming data + /// + /// + private void OnReceivedData(IAsyncResult result) + { + + ipeSender = new IPEndPoint(IPAddress.Any, 0); + epSender = (EndPoint)ipeSender; + Packet packet = null; + int numBytes; + + // If we're receiving data the sim connection is open + connected = true; + + // Update the disconnect flag so this sim doesn't time out + DisconnectCandidate = false; + NetworkInfo User_info=null; + + lock (RecvBuffer) + { + // Retrieve the incoming packet + try + { + numBytes = Connection.EndReceiveFrom(result, ref epSender); + + //find user_agent_info + + int packetEnd = numBytes - 1; + packet = Packet.BuildPacket(RecvBuffer, ref packetEnd, ZeroBuffer); + + + //should check if login/useconnection packet first + if (packet.Type == PacketType.UseCircuitCode) + { + //new connection + UseCircuitCodePacket cir_pack=(UseCircuitCodePacket)packet; + NetworkInfo new_user=new NetworkInfo(); + new_user.CircuitCode=cir_pack.CircuitCode.Code; + new_user.User.AgentID=cir_pack.CircuitCode.ID; + new_user.User.SessionID=cir_pack.CircuitCode.SessionID; + new_user.endpoint=epSender; + new_user.Inbox = new Queue(Settings.INBOX_SIZE); + new_user.Connection = new ClientConnection(); + new_user.Connection.NetInfo = new_user; + new_user.Connection.Start(); + + //this.CallbackObject.NewUserCallback(new_user); + this.User_agents.Add(new_user); + + } + + NetworkInfo temp_agent=null; + IPEndPoint send_ip=(IPEndPoint)epSender; + // this.callback_object.error("incoming: address is "+send_ip.Address +"port number is: "+send_ip.Port.ToString()); + + for(int ii=0; ii Settings.MAX_PENDING_ACKS) + { + SendAcks(User_info); + } + + // Check if we already received this packet + if (User_info.Inbox.Contains(packet.Header.Sequence)) + { + //Client.Log("Received a duplicate " + packet.Type.ToString() + ", sequence=" + + // packet.Header.Sequence + ", resent=" + ((packet.Header.Resent) ? "Yes" : "No") + + // ", Inbox.Count=" + Inbox.Count + ", NeedAck.Count=" + NeedAck.Count, + // Helpers.LogLevel.Info); + + // Send an ACK for this packet immediately + //SendAck(packet.Header.Sequence); + + // TESTING: Try just queuing up ACKs for resent packets instead of immediately triggering an ACK + lock (User_info.PendingAcks) + { + uint sequence = (uint)packet.Header.Sequence; + if (!User_info.PendingAcks.ContainsKey(sequence)) { User_info.PendingAcks[sequence] = sequence; } + } + + // Avoid firing a callback twice for the same packet + // this.callback_object.error("avoiding callback"); + return; + } + else + { + lock (User_info.PendingAcks) + { + uint sequence = (uint)packet.Header.Sequence; + if (!User_info.PendingAcks.ContainsKey(sequence)) { User_info.PendingAcks[sequence] = sequence; } + } + } + } + + // Add this packet to our inbox + lock (User_info.Inbox) + { + while (User_info.Inbox.Count >= Settings.INBOX_SIZE) + { + User_info.Inbox.Dequeue(); + } + User_info.Inbox.Enqueue(packet.Header.Sequence); + } + + // Handle appended ACKs + if (packet.Header.AppendedAcks) + { + lock (User_info.NeedAck) + { + foreach (uint ack in packet.Header.AckList) + { + User_info.NeedAck.Remove(ack); + } + } + } + + // Handle PacketAck packets + if (packet.Type == PacketType.PacketAck) + { + PacketAckPacket ackPacket = (PacketAckPacket)packet; + + lock (User_info.NeedAck) + { + foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets) + { + User_info.NeedAck.Remove(block.ID); + } + } + } + + //if it is a ping check send return + if( ( packet.Type == PacketType.StartPingCheck ) ) { + //reply to pingcheck + libsecondlife.Packets.StartPingCheckPacket startPing = (libsecondlife.Packets.StartPingCheckPacket)packet; + libsecondlife.Packets.CompletePingCheckPacket endPing = new CompletePingCheckPacket(); + endPing.PingID.PingID = startPing.PingID.PingID; + SendPacket(endPing, true, User_info ); + } + else if(packet.Type != PacketType.PacketAck) + { + User_info.Connection.InQueue.Enqueue(packet); + } + + } + + private void AckTimer_Elapsed(object sender, ElapsedEventArgs ea) + { + if (connected) + { + + //TODO for each user_agent_info + for(int i=0; iMillisecond interval between ticks, where all ACKs are + /// sent out and the age of unACKed packets is checked + public readonly int NETWORK_TICK_LENGTH = 500; + /// The maximum value of a packet sequence number. After that + /// we assume the sequence number just rolls over? Or maybe the + /// protocol isn't able to sustain a connection past that + public readonly int MAX_SEQUENCE = 0xFFFFFF; + /// Number of milliseconds before a teleport attempt will time + /// out + public readonly int TELEPORT_TIMEOUT = 18 * 1000; + /// Number of milliseconds before NetworkManager.Logout() will time out + public int LOGOUT_TIMEOUT = 5 * 1000; + /// Number of milliseconds for xml-rpc to timeout + public int LOGIN_TIMEOUT = 30 * 1000; + /// The maximum size of the sequence number inbox, used to + /// check for resent and/or duplicate packets + public int INBOX_SIZE = 100; + /// Milliseconds before a packet is assumed lost and resent + public int RESEND_TIMEOUT = 4000; + /// Milliseconds before the connection to a simulator is + /// assumed lost + public int SIMULATOR_TIMEOUT = 15000; + /// Maximum number of queued ACKs to be sent before SendAcks() + /// is forced + public int MAX_PENDING_ACKS = 10; + /// Maximum number of ACKs to append to a packet + public int MAX_APPENDED_ACKS = 10; + /// Cost of uploading an asset + + public Server_Settings() + { + + } + } + + public class NetworkInfo + { + public EndPoint endpoint; + public uint CircuitCode; + public CircuitConnection Connection; //should be taken out? + public UserInfo User; + + public Dictionary NeedAck = new Dictionary(); + // Sequence numbers of packets we've received from the simulator + public Queue Inbox; + // ACKs that are queued up to be sent to the simulator + public Dictionary PendingAcks = new Dictionary(); + + public NetworkInfo() + { + this.User = new UserInfo(); + } + } + + public class UserInfo + { + public LLUUID AgentID; + public LLUUID SessionID; + public string FullName; + public uint AvatarLocalID; + public string FirstName; + public string LastName; + + public UserInfo() + { + + } + } +} + + diff --git a/bin/Debug/Grid.ini b/bin/Debug/Grid.ini new file mode 100644 index 0000000000..def549dfe1 --- /dev/null +++ b/bin/Debug/Grid.ini @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/bin/Debug/OpenSimLite.pdb b/bin/Debug/OpenSimLite.pdb new file mode 100644 index 0000000000..6b0fed10c6 Binary files /dev/null and b/bin/Debug/OpenSimLite.pdb differ diff --git a/bin/Debug/layer_data/layerdata0.dat b/bin/Debug/layer_data/layerdata0.dat new file mode 100644 index 0000000000..71916ec756 Binary files /dev/null and b/bin/Debug/layer_data/layerdata0.dat differ diff --git a/bin/Debug/libsecondlife.dll b/bin/Debug/libsecondlife.dll new file mode 100644 index 0000000000..ac65b32391 Binary files /dev/null and b/bin/Debug/libsecondlife.dll differ diff --git a/bin/Debug/new-login.dat b/bin/Debug/new-login.dat new file mode 100644 index 0000000000..57ab1ffa0f --- /dev/null +++ b/bin/Debug/new-login.dat @@ -0,0 +1,2 @@ +messageWelcome to OpenSimsession_id99998888-8520-4f52-8ec1-0b1d5cd6aeadinventory-skel-libsim_port50000agent_accessMevent_notificationsstart_locationlastglobal-texturessun_texture_idcce0f112-878f-4586-a2e2-a8f104bba271cloud_texture_idfc4b9f0b-d008-45c6-96a4-01dd947ac621moon_texture_idd07f6eed-b96a-47cd-b51d-400ad4a1c428seconds_since_epoch1169908672first_name"Test"circuit_code50633318event_categorieslogin-flagsstipend_since_loginNever_logged_inYgenderedYdaylight_savingsNseed_capabilityhome{'region_handle':[r258560, r259840], 'position':[r41.6589, r100.8374, r22.5072], 'look_at':[r-0.57343, r-0.819255,r0]}secure_session_id71810f75-7437-49fb-8963-02b8fd1b95bflast_nameUserui-configallow_first_lifeYclassified_categoriescategory_nameShoppingcategory_id1category_nameLand Rentalcategory_id2category_nameProperty Rentalcategory_id3category_nameSpecial Attractioncategory_id4category_nameNew Productscategory_id5category_nameEmploymentcategory_id6category_nameWantedcategory_id7category_nameServicecategory_id8category_namePersonalcategory_id9region_x255232inventory-skeletonnameMy Inventoryparent_id00000000-0000-0000-0000-000000000000version4type_default8folder_idf798e114-c10f-409b-a90d-a11577ff1de8nameTexturesparent_idf798e114-c10f-409b-a90d-a11577ff1de8version1type_default0folder_idfc8b4059-30bb-43a8-a042-46f5b431ad82sim_ip127.0.0.1region_y254976gesturesinventory-lib-ownerinventory-rootfolder_idf798e114-c10f-409b-a90d-a11577ff1de8logintruelook_at[r0.99949799999999999756,r0.03166859999999999814,r0]agent_idaaaabbbb-8932-0271-8664-58f53e442797inventory-lib-rootinitial-outfitfolder_nameNightclub Femalegenderfemale +end-mfile \ No newline at end of file diff --git a/bin/Debug/objectupate168.dat b/bin/Debug/objectupate168.dat new file mode 100644 index 0000000000..c13c2c7ede Binary files /dev/null and b/bin/Debug/objectupate168.dat differ