Пример #1
0
        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);
        }
Пример #2
0
        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;
        }