public void Start() { simian = new Simian.Simian(); simian.UDP = new UDPManager(); (simian.UDP as IExtension<Simian.Simian>).Start(simian); sceneManager = new SceneManager(); sceneManager.Start(simian); agent = CreateDummyAgent(); simian.Agents.Add(agent.Avatar.ID, agent); observer = CreateDummyAgent(); simian.Agents.Add(observer.Avatar.ID, observer); }
public bool Start() { IPHostEntry entry; IPAddress address; IConfig httpConfig; #region Config Parsing try { // Load the extension list (and ordering) from our config file ConfigFile = new IniConfigSource(CONFIG_FILE); httpConfig = ConfigFile.Configs["Http"]; IConfig extensionConfig = ConfigFile.Configs["Extensions"]; ExtensionList = new List<string>(extensionConfig.GetKeys()); } catch (Exception) { Logger.Log("Failed to load [Extensions] section from " + CONFIG_FILE, Helpers.LogLevel.Error); return false; } #endregion Config Parsing #region HTTP Server int port = httpConfig.GetInt("ListenPort"); string hostname = httpConfig.GetString("Hostname", null); string sslCertFile = httpConfig.GetString("SSLCertFile", null); if (String.IsNullOrEmpty(hostname)) { hostname = Dns.GetHostName(); entry = Dns.GetHostEntry(hostname); address = IPAddress.Any; } else { entry = Dns.GetHostEntry(hostname); if (entry != null && entry.AddressList.Length > 0) { address = entry.AddressList[0]; } else { Logger.Log("Could not resolve an IP address from hostname " + hostname + ", binding to all interfaces", Helpers.LogLevel.Warning); address = IPAddress.Any; } } if (!String.IsNullOrEmpty(sslCertFile)) { // HTTPS mode X509Certificate serverCert; try { serverCert = X509Certificate.CreateFromCertFile(sslCertFile); } catch (Exception ex) { Logger.Log("Failed to load SSL certificate file \"" + sslCertFile + "\": " + ex.Message, Helpers.LogLevel.Error); return false; } HttpServer = HttpListener.Create(log4netLogWriter.Instance, address, port, serverCert); HttpUri = new Uri("https://" + hostname + (port != 80 ? (":" + port) : String.Empty)); } else { // HTTP mode HttpServer = HttpListener.Create(log4netLogWriter.Instance, address, port); HttpUri = new Uri("http://" + hostname + (port != 80 ? (":" + port) : String.Empty)); } HttpServer.Start(10); Logger.Log("Simian is listening at " + HttpUri.ToString(), Helpers.LogLevel.Info); #endregion HTTP Server #region Server Extensions try { // Create a list of references for .cs extensions that are compiled at runtime List<string> references = new List<string>(); references.Add("OpenMetaverseTypes.dll"); references.Add("OpenMetaverse.dll"); references.Add("Simian.exe"); // Load extensions from the current executing assembly, Simian.*.dll assemblies on disk, and // Simian.*.cs source files on disk. extensions.LoadAllExtensions(Assembly.GetExecutingAssembly(), AppDomain.CurrentDomain.BaseDirectory, ExtensionList, references, "Simian.*.dll", "Simian.*.cs"); // Automatically assign extensions that implement interfaces to the list of interface // variables in "assignables" extensions.AssignExtensions(this, extensions.GetInterfaces(this)); } catch (ExtensionException ex) { Logger.Log("Extension loading failed, shutting down: " + ex.Message, Helpers.LogLevel.Error); Stop(); return false; } foreach (IExtension<Simian> extension in extensions.Extensions) { // Track all of the extensions with persistence if (extension is IPersistable) PersistentExtensions.Add((IPersistable)extension); } // Start all of the extensions foreach (IExtension<Simian> extension in extensions.Extensions) { Logger.Log("Starting Simian extension " + extension.GetType().Name, Helpers.LogLevel.Info); extension.Start(this); } #endregion Server Extensions #region Region Loading try { string[] configFiles = Directory.GetFiles(REGION_CONFIG_DIR, "*.ini", SearchOption.AllDirectories); for (int i = 0; i < configFiles.Length; i++) { // TODO: Support non-SceneManager scenes? ISceneProvider scene = new SceneManager(); #region Config Parsing IniConfigSource source = new IniConfigSource(configFiles[i]); IConfig regionConfig = source.Configs["Region"]; string name = regionConfig.GetString("Name", null); string defaultTerrain = regionConfig.GetString("DefaultTerrain", null); int udpPort = regionConfig.GetInt("UDPPort", 0); uint regionX, regionY; UInt32.TryParse(regionConfig.GetString("RegionX", "0"), out regionX); UInt32.TryParse(regionConfig.GetString("RegionY", "0"), out regionY); string certFile = regionConfig.GetString("RegionCertificate", null); int staticObjectLimit = regionConfig.GetInt("StaticObjectLimit", 0); int physicalObjectLimit = regionConfig.GetInt("PhysicalObjectLimit", 0); float waterHeight = regionConfig.GetFloat("WaterHeight", 0f); RegionFlags regionFlags = RegionFlags.None; if (regionConfig.GetBoolean("AllowDamage")) regionFlags |= RegionFlags.AllowDamage; if (regionConfig.GetBoolean("SunFixed")) regionFlags |= RegionFlags.SunFixed; if (regionConfig.GetBoolean("BlockTerraform")) regionFlags |= RegionFlags.BlockTerraform; if (regionConfig.GetBoolean("SkipScripts")) regionFlags |= RegionFlags.SkipScripts; if (regionConfig.GetBoolean("SkipPhysics")) regionFlags |= RegionFlags.SkipPhysics; if (regionConfig.GetBoolean("PublicAllowed")) regionFlags |= RegionFlags.PublicAllowed; if (regionConfig.GetBoolean("NoFly")) regionFlags |= RegionFlags.NoFly; if (regionConfig.GetBoolean("AllowDirectTeleport")) regionFlags |= RegionFlags.AllowDirectTeleport; if (regionConfig.GetBoolean("RestrictPushObject")) regionFlags |= RegionFlags.RestrictPushObject; if (regionConfig.GetBoolean("AllowParcelChanges")) regionFlags |= RegionFlags.AllowParcelChanges; if (String.IsNullOrEmpty(name) || regionX == 0 || regionY == 0 || String.IsNullOrEmpty(certFile)) { Logger.Log("Incomplete information in " + configFiles[i] + ", skipping", Helpers.LogLevel.Warning); continue; } // TODO: Real map tile image generation, perhaps? UUID mapTextureID = new UUID("89556747-24cb-43ed-920b-47caed15465f"); #endregion Config Parsing #region IPEndPoint Assignment IPEndPoint endpoint; if (udpPort != 0) { endpoint = new IPEndPoint(address, udpPort); } else { udpPort = DEFAULT_UDP_PORT; while (true) { endpoint = new IPEndPoint(address, udpPort); Socket udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); try { udpSocket.Bind(endpoint); udpSocket.Close(); break; } catch (SocketException) { ++udpPort; } } } // Make sure 0.0.0.0 gets replaced with a valid IP address if (endpoint.Address == IPAddress.Any) endpoint.Address = entry.AddressList.Length > 0 ? entry.AddressList[entry.AddressList.Length - 1] : IPAddress.Loopback; #endregion IPEndPoint Assignment #region Grid Registration X509Certificate2 regionCert; try { regionCert = new X509Certificate2(DATA_DIR + certFile); } catch (Exception) { Logger.Log("Failed to load region certificate file from " + certFile, Helpers.LogLevel.Error); continue; } RegionInfo regionInfo = new RegionInfo(); regionInfo.Handle = Utils.UIntsToLong(256 * regionX, 256 * regionY); regionInfo.HttpServer = HttpUri; regionInfo.IPAndPort = endpoint; regionInfo.Name = name; regionInfo.MapTextureID = mapTextureID; regionInfo.Flags = regionFlags; regionInfo.AgentCount = 0; regionInfo.WaterHeight = waterHeight; regionInfo.Online = true; // Create a capability for other regions to initiate a client connection to this region regionInfo.EnableClientCap = Capabilities.CreateCapability(scene.EnableClientCapHandler, false, null); if (!Grid.TryRegisterGridSpace(regionInfo, regionCert, out regionInfo.ID)) { Logger.Log("Failed to register grid space for region " + name, Helpers.LogLevel.Error); continue; } #endregion Grid Registration scene.Start(this, regionInfo, regionCert, defaultTerrain, staticObjectLimit, physicalObjectLimit); Scenes.Add(scene); } } catch (Exception ex) { Logger.Log("Failed to load region config files: " + ex.Message, Helpers.LogLevel.Error); return false; } #endregion Region Loading return true; }