Beispiel #1
0
        /// <summary>
        /// Entry point of the application
        /// </summary>
        public static void Main()
        {
            // Setup LOG4NET
            XmlConfigurator.Configure();

            // Load configuration
            var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            var mudpieConfigurationSection = (MudpieConfigurationSection)config.GetSection("mudpie");

            Debug.Assert(mudpieConfigurationSection != null, "mudpieConfigurationSection != null");
            Logger.InfoFormat("Loaded configuration from {0}", config.FilePath);

            var godPlayer = new Player("God", 2, "god")
            {
                Aliases    = new[] { "Jehovah", "Yahweh", "Allah" },
                DbRef      = 2,
                Properties = new[]
                {
                    new Property
                    {
                        Name  = "_/de",
                        Value = "The Creator",
                        Owner = 2
                    }
                },
                Location = 1
            };

            using (var redis = new StackExchangeRedisCacheClient(new NewtonsoftSerializer()))
            {
                Debug.Assert(redis != null, "redis != null");

                // Setup scripting engine
                var scriptingEngine = new Engine(redis);

                // Setup server process
                Debug.Assert(mudpieConfigurationSection.Ports != null, "mudpieConfigurationSection.Ports != null");
                var server = new Server(mudpieConfigurationSection.Ports.Select(p => p.Port).ToArray(), scriptingEngine)
                {
                    ShowBytes    = true,
                    ShowCommands = false,
                    ShowData     = true
                };

                // Seed data
                Task.Run(async() =>
                {
                    if (!await redis.ExistsAsync("mudpie::dbref:counter"))
                    {
                        Console.WriteLine("Redis database is not seeded with any data.  Creating seed data...");

                        // VOID
                        var voidRoom = new Room("The Void", godPlayer.DbRef)
                        {
                            DbRef      = 1,
                            Properties = new[]
                            {
                                new Property(Property.DESCRIPTION, "An infinite emptiness of nothing.", 2)
                            }
                        };
                        await voidRoom.SaveAsync(redis, server.CancellationToken);

                        // GOD
                        using (var godPassword = new SecureString())
                        {
                            foreach (var c in "god")
                            {
                                godPassword.AppendChar(c);
                            }

                            godPlayer.SetPassword(godPassword);
                            godPassword.Clear();
                        }

                        await godPlayer.SaveAsync(redis, server.CancellationToken);

                        var nextAvailableDbRef    = 3;
                        var registerProgramToVoid = new Func <string, string[], string, int, ICacheClient, Task <int> >(async(name, aliases, desc, nextDbRef, cacheClient) =>
                        {
                            var source = await SourceUtility.GetSourceCodeLinesAsync(mudpieConfigurationSection, name);
                            Debug.Assert(source != null, $"Unable to find source code for program {name}");
                            var nameProgram = new Mudpie.Server.Data.Program(name, godPlayer.DbRef, source)
                            {
                                DbRef      = nextDbRef,
                                Properties = new[]
                                {
                                    new Property(Property.DESCRIPTION, desc, godPlayer.DbRef)
                                },
                                Interactive = false
                            };
                            await nameProgram.SaveAsync(cacheClient, server.CancellationToken);

                            // LINK-NAME-ROOM
                            var linkName = new Link(System.IO.Path.GetFileNameWithoutExtension(name), godPlayer.DbRef)
                            {
                                Aliases = aliases,
                                DbRef   = nextDbRef + 1,
                                Target  = nextDbRef
                            };
                            await linkName.MoveAsync(voidRoom.DbRef, cacheClient, server.CancellationToken);
                            var void2 = ObjectBase.GetAsync(cacheClient, voidRoom.DbRef, server.CancellationToken).Result;
                            if (void2 == null)
                            {
                                throw new InvalidOperationException("void2 cannot be null");
                            }

                            return(nextDbRef + 2);
                        });

                        // @NAME
                        nextAvailableDbRef = await registerProgramToVoid.Invoke("@create.msc", new[] { "create", "make" }, "Creates new things", nextAvailableDbRef, redis);
                        nextAvailableDbRef = await registerProgramToVoid.Invoke("@describe.msc", new[] { "@desc", "describe" }, "Sets the description of an object", nextAvailableDbRef, redis);
                        nextAvailableDbRef = await registerProgramToVoid.Invoke("@dig.msc", new[] { "dig" }, "Creates new rooms", nextAvailableDbRef, redis);
                        nextAvailableDbRef = await registerProgramToVoid.Invoke("@name.msc", new[] { "rename" }, "Rename objects", nextAvailableDbRef, redis);
                        nextAvailableDbRef = await registerProgramToVoid.Invoke("inventory.msc", new[] { "i", "inv" }, "Lists the items you are carrying", nextAvailableDbRef, redis);
                        nextAvailableDbRef = await registerProgramToVoid.Invoke("look.msc", new[] { "l" }, "Displays information about your surroundings, or an object.", nextAvailableDbRef, redis);

                        await redis.Database.StringSetAsync("mudpie::dbref:counter", nextAvailableDbRef);
                    }
                    else
                    {
                        // Ensure we can read Void and God
                        var voidRoom = await Room.GetAsync(redis, 1, server.CancellationToken);
                        Debug.Assert(voidRoom != null, "voidRoom != null");

                        godPlayer = await Player.GetAsync(redis, 2, server.CancellationToken);
                        Debug.Assert(godPlayer != null, "godPlayer != null");

                        var godComposed = await CacheManager.LookupOrRetrieveAsync(2, redis, async(d, token) => await Player.GetAsync(redis, d, token), server.CancellationToken);
                        Debug.Assert(godComposed != null, "godComposed != null");
                    }

                    /*else
                     * {
                     *  Console.WriteLine("Redis database is seeded with data.  BLOWING IT AWAY DATA...");
                     *
                     *  System.Console.WriteLine("Deleting ROOMS...");
                     *  foreach (var roomId in await redis.SetMembersAsync<string>("mudpie::rooms"))
                     *      await redis.RemoveAsync($"mudpie::room:{roomId}");
                     *  await redis.RemoveAsync("mudpie::rooms");
                     *
                     *  System.Console.WriteLine("Deleting USERS...");
                     *  foreach (var playerId in await redis.SetMembersAsync<string>("mudpie::players"))
                     *      await redis.RemoveAsync($"mudpie::player:{playerId}");
                     *  await redis.RemoveAsync("mudpie::players");
                     * }*/
                    return(0);
                }).Wait();

                // Listen for connections
                server.Start();

                Console.WriteLine("\r\nPress ~ to quit the server console");
                while (Console.ReadKey().Key != ConsoleKey.Oem3)
                {
                }

                Console.WriteLine("\r\nShutting down server...");
                server.Stop();
                Console.WriteLine("\r\nServer is shut down. End of line.");
            }
        }