OpenSimMain.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. /*
  2. Copyright (c) OpenSim project, http://osgrid.org/
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the <organization> nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Text;
  29. using System.IO;
  30. using System.Threading;
  31. using System.Net;
  32. using System.Net.Sockets;
  33. using System.Timers;
  34. using System.Reflection;
  35. using System.Collections;
  36. using System.Collections.Generic;
  37. using libsecondlife;
  38. using libsecondlife.Packets;
  39. using OpenSim.world;
  40. using OpenSim.Framework.Interfaces;
  41. using OpenSim.UserServer;
  42. using OpenSim.Assets;
  43. using OpenSim.CAPS;
  44. using OpenSim.Framework.Console;
  45. using OpenSim.Physics.Manager;
  46. using Nwc.XmlRpc;
  47. using OpenSim.Servers;
  48. namespace OpenSim
  49. {
  50. public class OpenSimMain : OpenSimNetworkHandler, conscmd_callback
  51. {
  52. private PhysicsManager physManager;
  53. private World LocalWorld;
  54. private Grid GridServers;
  55. private SimConfig Cfg;
  56. private BaseHttpServer HttpServer;
  57. private AssetCache AssetCache;
  58. private InventoryCache InventoryCache;
  59. //public Dictionary<EndPoint, SimClient> ClientThreads = new Dictionary<EndPoint, SimClient>();
  60. private Dictionary<uint, SimClient> ClientThreads = new Dictionary<uint, SimClient>();
  61. private Dictionary<EndPoint, uint> clientCircuits = new Dictionary<EndPoint, uint>();
  62. private DateTime startuptime;
  63. public Socket Server;
  64. private IPEndPoint ServerIncoming;
  65. private byte[] RecvBuffer = new byte[4096];
  66. private byte[] ZeroBuffer = new byte[8192];
  67. private IPEndPoint ipeSender;
  68. private EndPoint epSender;
  69. private AsyncCallback ReceivedData;
  70. private System.Timers.Timer timer1 = new System.Timers.Timer();
  71. private string ConfigDll = "OpenSim.Config.SimConfigDb4o.dll";
  72. public string m_physicsEngine;
  73. public bool m_sandbox = false;
  74. public bool m_loginserver;
  75. protected ConsoleBase m_console;
  76. public OpenSimMain(bool sandBoxMode, bool startLoginServer, string physicsEngine)
  77. {
  78. m_sandbox = sandBoxMode;
  79. m_loginserver = startLoginServer;
  80. m_physicsEngine = physicsEngine;
  81. m_console = new ConsoleBase("region-console.log", "Region", this);
  82. OpenSim.Framework.Console.MainConsole.Instance = m_console;
  83. }
  84. public virtual void StartUp()
  85. {
  86. GridServers = new Grid();
  87. if (m_sandbox)
  88. {
  89. GridServers.AssetDll = "OpenSim.GridInterfaces.Local.dll";
  90. GridServers.GridDll = "OpenSim.GridInterfaces.Local.dll";
  91. m_console.WriteLine("Starting in Sandbox mode");
  92. }
  93. else
  94. {
  95. GridServers.AssetDll = "OpenSim.GridInterfaces.Remote.dll";
  96. GridServers.GridDll = "OpenSim.GridInterfaces.Remote.dll";
  97. m_console.WriteLine("Starting in Grid mode");
  98. }
  99. GridServers.Initialise();
  100. startuptime = DateTime.Now;
  101. AssetCache = new AssetCache(GridServers.AssetServer);
  102. InventoryCache = new InventoryCache();
  103. // We check our local database first, then the grid for config options
  104. m_console.WriteLine("Main.cs:Startup() - Loading configuration");
  105. Cfg = this.LoadConfigDll(this.ConfigDll);
  106. Cfg.InitConfig(this.m_sandbox);
  107. m_console.WriteLine("Main.cs:Startup() - Contacting gridserver");
  108. Cfg.LoadFromGrid();
  109. m_console.WriteLine("Main.cs:Startup() - We are " + Cfg.RegionName + " at " + Cfg.RegionLocX.ToString() + "," + Cfg.RegionLocY.ToString());
  110. m_console.WriteLine("Initialising world");
  111. LocalWorld = new World(ClientThreads, Cfg.RegionHandle, Cfg.RegionName, Cfg);
  112. LocalWorld.LandMap = Cfg.LoadWorld();
  113. this.physManager = new OpenSim.Physics.Manager.PhysicsManager();
  114. this.physManager.LoadPlugins();
  115. m_console.WriteLine("Main.cs:Startup() - Starting up messaging system");
  116. LocalWorld.PhysScene = this.physManager.GetPhysicsScene(this.m_physicsEngine); //should be reading from the config file what physics engine to use
  117. LocalWorld.PhysScene.SetTerrain(LocalWorld.LandMap);
  118. GridServers.AssetServer.SetServerInfo(Cfg.AssetURL, Cfg.AssetSendKey);
  119. IGridServer gridServer = GridServers.GridServer;
  120. gridServer.SetServerInfo(Cfg.GridURL, Cfg.GridSendKey, Cfg.GridRecvKey);
  121. LocalWorld.LoadStorageDLL("OpenSim.Storage.LocalStorageDb4o.dll"); //all these dll names shouldn't be hard coded.
  122. LocalWorld.LoadPrimsFromStorage();
  123. if (m_sandbox)
  124. {
  125. AssetCache.LoadDefaultTextureSet();
  126. }
  127. m_console.WriteLine("Main.cs:Startup() - Starting CAPS HTTP server");
  128. HttpServer = new BaseHttpServer( Cfg.IPListenPort );
  129. if (gridServer.GetName() == "Remote")
  130. {
  131. HttpServer.AddXmlRPCHandler("expect_user",
  132. delegate(XmlRpcRequest request)
  133. {
  134. Hashtable requestData = (Hashtable)request.Params[0];
  135. AgentCircuitData agent_data = new AgentCircuitData();
  136. agent_data.SessionID = new LLUUID((string)requestData["session_id"]);
  137. agent_data.SecureSessionID = new LLUUID((string)requestData["secure_session_id"]);
  138. agent_data.firstname = (string)requestData["firstname"];
  139. agent_data.lastname = (string)requestData["lastname"];
  140. agent_data.AgentID = new LLUUID((string)requestData["agent_id"]);
  141. agent_data.circuitcode = Convert.ToUInt32(requestData["circuit_code"]);
  142. ((RemoteGridBase)gridServer).agentcircuits.Add((uint)agent_data.circuitcode, agent_data);
  143. return new XmlRpcResponse();
  144. });
  145. }
  146. HttpServer.AddRestHandler("Admin", new AdminWebFront("Admin", LocalWorld));
  147. HttpServer.Start();
  148. if (m_loginserver && m_sandbox)
  149. {
  150. LoginServer loginServer = new LoginServer(gridServer, Cfg.IPListenAddr, Cfg.IPListenPort);
  151. loginServer.Startup();
  152. if (loginServer.userAccounts)
  153. {
  154. // Actually, this is never tru as of now, but if it were, we'd do something like
  155. HttpServer.AddXmlRPCHandler("login_to_simulator", loginServer.LocalUserManager.XmlRpcLoginMethod);
  156. }
  157. else
  158. {
  159. HttpServer.AddXmlRPCHandler("login_to_simulator", loginServer.XmlRpcLoginMethod);
  160. }
  161. }
  162. MainServerListener();
  163. timer1.Enabled = true;
  164. timer1.Interval = 100;
  165. timer1.Elapsed += new ElapsedEventHandler(this.Timer1Tick);
  166. }
  167. private SimConfig LoadConfigDll(string dllName)
  168. {
  169. Assembly pluginAssembly = Assembly.LoadFrom(dllName);
  170. SimConfig config = null;
  171. foreach (Type pluginType in pluginAssembly.GetTypes())
  172. {
  173. if (pluginType.IsPublic)
  174. {
  175. if (!pluginType.IsAbstract)
  176. {
  177. Type typeInterface = pluginType.GetInterface("ISimConfig", true);
  178. if (typeInterface != null)
  179. {
  180. ISimConfig plug = (ISimConfig)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
  181. config = plug.GetConfigObject();
  182. break;
  183. }
  184. typeInterface = null;
  185. }
  186. }
  187. }
  188. pluginAssembly = null;
  189. return config;
  190. }
  191. private void OnReceivedData(IAsyncResult result)
  192. {
  193. ipeSender = new IPEndPoint(IPAddress.Any, 0);
  194. epSender = (EndPoint)ipeSender;
  195. Packet packet = null;
  196. int numBytes = Server.EndReceiveFrom(result, ref epSender);
  197. int packetEnd = numBytes - 1;
  198. packet = Packet.BuildPacket(RecvBuffer, ref packetEnd, ZeroBuffer);
  199. // This is either a new client or a packet to send to an old one
  200. // if (OpenSimRoot.Instance.ClientThreads.ContainsKey(epSender))
  201. // do we already have a circuit for this endpoint
  202. if (this.clientCircuits.ContainsKey(epSender))
  203. {
  204. ClientThreads[this.clientCircuits[epSender]].InPacket(packet);
  205. }
  206. else if (packet.Type == PacketType.UseCircuitCode)
  207. { // new client
  208. UseCircuitCodePacket useCircuit = (UseCircuitCodePacket)packet;
  209. this.clientCircuits.Add(epSender, useCircuit.CircuitCode.Code);
  210. SimClient newuser = new SimClient(epSender, useCircuit, LocalWorld, ClientThreads, AssetCache, GridServers.GridServer, this, InventoryCache, m_sandbox);
  211. //OpenSimRoot.Instance.ClientThreads.Add(epSender, newuser);
  212. ClientThreads.Add(useCircuit.CircuitCode.Code, newuser);
  213. }
  214. else
  215. { // invalid client
  216. Console.Error.WriteLine("Main.cs:OnReceivedData() - WARNING: Got a packet from an invalid client - " + epSender.ToString());
  217. }
  218. Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null);
  219. }
  220. private void MainServerListener()
  221. {
  222. m_console.WriteLine("Main.cs:MainServerListener() - New thread started");
  223. m_console.WriteLine("Main.cs:MainServerListener() - Opening UDP socket on " + Cfg.IPListenAddr + ":" + Cfg.IPListenPort);
  224. ServerIncoming = new IPEndPoint(IPAddress.Any, Cfg.IPListenPort);
  225. Server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
  226. Server.Bind(ServerIncoming);
  227. m_console.WriteLine("Main.cs:MainServerListener() - UDP socket bound, getting ready to listen");
  228. ipeSender = new IPEndPoint(IPAddress.Any, 0);
  229. epSender = (EndPoint)ipeSender;
  230. ReceivedData = new AsyncCallback(this.OnReceivedData);
  231. Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null);
  232. m_console.WriteLine("Main.cs:MainServerListener() - Listening...");
  233. }
  234. public virtual void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode)//EndPoint packetSender)
  235. {
  236. // find the endpoint for this circuit
  237. EndPoint sendto = null;
  238. foreach (KeyValuePair<EndPoint, uint> p in this.clientCircuits)
  239. {
  240. if (p.Value == circuitcode)
  241. {
  242. sendto = p.Key;
  243. break;
  244. }
  245. }
  246. if (sendto != null)
  247. {
  248. //we found the endpoint so send the packet to it
  249. this.Server.SendTo(buffer, size, flags, sendto);
  250. }
  251. }
  252. public virtual void RemoveClientCircuit(uint circuitcode)
  253. {
  254. foreach (KeyValuePair<EndPoint, uint> p in this.clientCircuits)
  255. {
  256. if (p.Value == circuitcode)
  257. {
  258. this.clientCircuits.Remove(p.Key);
  259. break;
  260. }
  261. }
  262. }
  263. public virtual void Shutdown()
  264. {
  265. m_console.WriteLine("Main.cs:Shutdown() - Closing all threads");
  266. m_console.WriteLine("Main.cs:Shutdown() - Killing listener thread");
  267. m_console.WriteLine("Main.cs:Shutdown() - Killing clients");
  268. // IMPLEMENT THIS
  269. m_console.WriteLine("Main.cs:Shutdown() - Closing console and terminating");
  270. LocalWorld.Close();
  271. GridServers.Close();
  272. m_console.Close();
  273. Environment.Exit(0);
  274. }
  275. void Timer1Tick(object sender, System.EventArgs e)
  276. {
  277. LocalWorld.Update();
  278. }
  279. public void RunCmd(string command, string[] cmdparams)
  280. {
  281. switch (command)
  282. {
  283. case "help":
  284. m_console.WriteLine("show users - show info about connected users");
  285. m_console.WriteLine("shutdown - disconnect all clients and shutdown");
  286. m_console.WriteLine("regenerate - regenerate the sim's terrain");
  287. break;
  288. case "show":
  289. Show(cmdparams[0]);
  290. break;
  291. case "regenerate":
  292. LocalWorld.RegenerateTerrain();
  293. break;
  294. case "shutdown":
  295. Shutdown();
  296. break;
  297. }
  298. }
  299. public void Show(string ShowWhat)
  300. {
  301. switch (ShowWhat)
  302. {
  303. case "uptime":
  304. m_console.WriteLine("OpenSim has been running since " + startuptime.ToString());
  305. m_console.WriteLine("That is " + (DateTime.Now - startuptime).ToString());
  306. break;
  307. case "users":
  308. OpenSim.world.Avatar TempAv;
  309. m_console.WriteLine(String.Format("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16}{5,-16}", "Firstname", "Lastname", "Agent ID", "Session ID", "Circuit", "IP"));
  310. foreach (libsecondlife.LLUUID UUID in LocalWorld.Entities.Keys)
  311. {
  312. if (LocalWorld.Entities[UUID].ToString() == "OpenSim.world.Avatar")
  313. {
  314. TempAv = (OpenSim.world.Avatar)LocalWorld.Entities[UUID];
  315. m_console.WriteLine(String.Format("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16},{5,-16}", TempAv.firstname, TempAv.lastname, UUID, TempAv.ControllingClient.SessionID, TempAv.ControllingClient.CircuitCode, TempAv.ControllingClient.userEP.ToString()));
  316. }
  317. }
  318. break;
  319. }
  320. }
  321. }
  322. }