static void DumpStatsHandler( Player player, Command cmd )
        {
            string fileName = cmd.Next();
            if( fileName == null ) {
                CdDumpStats.PrintUsage( player );
                return;
            }

            if( !Paths.Contains( Paths.WorkingPath, fileName ) ) {
                player.MessageUnsafePath();
                return;
            }

            // ReSharper disable AssignNullToNotNullAttribute
            if( Paths.IsProtectedFileName( Path.GetFileName( fileName ) ) ) {
                // ReSharper restore AssignNullToNotNullAttribute
                player.Message( "You may not use this file." );
                return;
            }

            string extension = Path.GetExtension( fileName );
            if( extension == null || !extension.Equals( ".txt", StringComparison.OrdinalIgnoreCase ) ) {
                player.Message( "Stats filename must end with .txt" );
                return;
            }

            if( File.Exists( fileName ) && !cmd.IsConfirmed ) {
                player.Confirm( cmd, "File \"{0}\" already exists. Overwrite?", Path.GetFileName( fileName ) );
                return;
            }

            if( !Paths.TestFile( "DumpStats file", fileName, false, FileAccess.Write ) ) {
                player.Message( "Cannot create specified file. See log for details." );
                return;
            }

            PlayerInfo[] infos;
            using( FileStream fs = File.Create( fileName ) ) {
                using( StreamWriter writer = new StreamWriter( fs ) ) {
                    infos = PlayerDB.PlayerInfoList;
                    if( infos.Length == 0 ) {
                        writer.WriteLine( "(TOTAL) (0 players)" );
                        writer.WriteLine();
                    } else {
                        DumpPlayerGroupStats( writer, infos, "(TOTAL)" );
                    }

                    List<PlayerInfo> rankPlayers = new List<PlayerInfo>();
                    foreach( Rank rank in RankManager.Ranks ) {
                        // ReSharper disable LoopCanBeConvertedToQuery
                        for( int i = 0; i < infos.Length; i++ ) {
                            // ReSharper restore LoopCanBeConvertedToQuery
                            if( infos[i].Rank == rank ) rankPlayers.Add( infos[i] );
                        }
                        if( rankPlayers.Count == 0 ) {
                            writer.WriteLine( "{0}: 0 players, 0 banned, 0 inactive", rank.Name );
                            writer.WriteLine();
                        } else {
                            DumpPlayerGroupStats( writer, rankPlayers, rank.Name );
                        }
                        rankPlayers.Clear();
                    }
                }
            }

            player.Message( "Stats saved to \"{0}\"", fileName );
        }
Пример #2
0
        static void GenHandler(Player player, Command cmd)
        {
            World playerWorld = player.World;
            string themeName = cmd.Next();
            string templateName;
            bool genOcean = false;
            bool genEmpty = false;
            bool noTrees = false;

            if (themeName == null)
            {
                CdGenerate.PrintUsage(player);
                return;
            }
            MapGenTheme theme = MapGenTheme.Forest;
            MapGenTemplate template = MapGenTemplate.Flat;

            // parse special template names (which do not need a theme)
            if (themeName.Equals("ocean"))
            {
                genOcean = true;

            }
            else if (themeName.Equals("empty"))
            {
                genEmpty = true;

            }
            else
            {
                templateName = cmd.Next();
                if (templateName == null)
                {
                    CdGenerate.PrintUsage(player);
                    return;
                }

                // parse theme
                bool swapThemeAndTemplate = false;
                if (themeName.Equals("grass", StringComparison.OrdinalIgnoreCase))
                {
                    theme = MapGenTheme.Forest;
                    noTrees = true;

                }
                else if (templateName.Equals("grass", StringComparison.OrdinalIgnoreCase))
                {
                    theme = MapGenTheme.Forest;
                    noTrees = true;
                    swapThemeAndTemplate = true;

                }
                else if (EnumUtil.TryParse(themeName, out theme, true))
                {
                    noTrees = (theme != MapGenTheme.Forest);

                }
                else if (EnumUtil.TryParse(templateName, out theme, true))
                {
                    noTrees = (theme != MapGenTheme.Forest);
                    swapThemeAndTemplate = true;

                }
                else
                {
                    player.Message("Gen: Unrecognized theme \"{0}\". Available themes are: Grass, {1}",
                                    themeName,
                                    Enum.GetNames(typeof(MapGenTheme)).JoinToString());
                    return;
                }

                // parse template
                if (swapThemeAndTemplate)
                {
                    if (!EnumUtil.TryParse(themeName, out template, true))
                    {
                        player.Message("Unrecognized template \"{0}\". Available terrain types: Empty, Ocean, {1}",
                                        themeName,
                                        Enum.GetNames(typeof(MapGenTemplate)).JoinToString());
                        return;
                    }
                }
                else
                {
                    if (!EnumUtil.TryParse(templateName, out template, true))
                    {
                        player.Message("Unrecognized template \"{0}\". Available terrain types: Empty, Ocean, {1}",
                                        templateName,
                                        Enum.GetNames(typeof(MapGenTemplate)).JoinToString());
                        return;
                    }
                }
            }

            // parse map dimensions
            int mapWidth, mapLength, mapHeight;
            if (cmd.HasNext)
            {
                int offset = cmd.Offset;
                if (!(cmd.NextInt(out mapWidth) && cmd.NextInt(out mapLength) && cmd.NextInt(out mapHeight)))
                {
                    if (playerWorld != null)
                    {
                        Map oldMap = player.WorldMap;
                        // If map dimensions were not given, use current map's dimensions
                        mapWidth = oldMap.Width;
                        mapLength = oldMap.Length;
                        mapHeight = oldMap.Height;
                    }
                    else
                    {
                        player.Message("When used from console, /Gen requires map dimensions.");
                        CdGenerate.PrintUsage(player);
                        return;
                    }
                    cmd.Offset = offset;
                }
            }
            else if (playerWorld != null)
            {
                Map oldMap = player.WorldMap;
                // If map dimensions were not given, use current map's dimensions
                mapWidth = oldMap.Width;
                mapLength = oldMap.Length;
                mapHeight = oldMap.Height;
            }
            else
            {
                player.Message("When used from console, /Gen requires map dimensions.");
                CdGenerate.PrintUsage(player);
                return;
            }

            // Check map dimensions
            const string dimensionRecommendation = "Dimensions must be between 16 and 2047. " +
                                                   "Recommended values: 16, 32, 64, 128, 256, 512, and 1024.";
            if (!Map.IsValidDimension(mapWidth))
            {
                player.Message("Cannot make map with width {0}. {1}", mapWidth, dimensionRecommendation);
                return;
            }
            else if (!Map.IsValidDimension(mapLength))
            {
                player.Message("Cannot make map with length {0}. {1}", mapLength, dimensionRecommendation);
                return;
            }
            else if (!Map.IsValidDimension(mapHeight))
            {
                player.Message("Cannot make map with height {0}. {1}", mapHeight, dimensionRecommendation);
                return;
            }
            long volume = (long)mapWidth * (long)mapLength * (long)mapHeight;
            if (volume > Int32.MaxValue)
            {
                player.Message("Map volume may not exceed {0}", Int32.MaxValue);
                return;
            }

            if (!cmd.IsConfirmed && (!Map.IsRecommendedDimension(mapWidth) || !Map.IsRecommendedDimension(mapLength) || !Map.IsRecommendedDimension(mapHeight)))
            {
                player.Message("&WThe map will have non-standard dimensions. " +
                                "You may see glitched blocks or visual artifacts. " +
                                "The only recommended map dimensions are: 16, 32, 64, 128, 256, 512, and 1024.");
            }

            // figure out full template name
            bool genFlatgrass = (theme == MapGenTheme.Forest && noTrees && template == MapGenTemplate.Flat);
            string templateFullName;
            if (genEmpty)
            {
                templateFullName = "Empty";
            }
            else if (genOcean)
            {
                templateFullName = "Ocean";
            }
            else if (genFlatgrass)
            {
                templateFullName = "Flatgrass";
            }
            else
            {
                if (theme == MapGenTheme.Forest && noTrees)
                {
                    templateFullName = "Grass " + template;
                }
                else
                {
                    templateFullName = theme + " " + template;
                }
            }

            // check file/world name
            string fileName = cmd.Next();
            string fullFileName = null;
            if (fileName == null)
            {
                // replacing current world
                if (playerWorld == null)
                {
                    player.Message("When used from console, /Gen requires FileName.");
                    CdGenerate.PrintUsage(player);
                    return;
                }
                if (!cmd.IsConfirmed)
                {
                    player.Confirm(cmd, "Replace THIS MAP with a generated one ({0})?", templateFullName);
                    return;
                }

            }
            else
            {
                if (cmd.HasNext)
                {
                    CdGenerate.PrintUsage(player);
                    return;
                }
                // saving to file
                fileName = fileName.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
                if (!fileName.EndsWith(".fcm", StringComparison.OrdinalIgnoreCase))
                {
                    fileName += ".fcm";
                }
                if (!Paths.IsValidPath(fileName))
                {
                    player.Message("Invalid filename.");
                    return;
                }
                fullFileName = Path.Combine(Paths.MapPath, fileName);
                if (!Paths.Contains(Paths.MapPath, fullFileName))
                {
                    player.MessageUnsafePath();
                    return;
                }
                string dirName = fullFileName.Substring(0, fullFileName.LastIndexOf(Path.DirectorySeparatorChar));
                if (!Directory.Exists(dirName))
                {
                    Directory.CreateDirectory(dirName);
                }
                if (!cmd.IsConfirmed && File.Exists(fullFileName))
                {
                    player.Confirm(cmd, "The mapfile \"{0}\" already exists. Overwrite?", fileName);
                    return;
                }
            }

            // generate the map
            Map map;
            player.MessageNow("Generating {0}...", templateFullName);

            if (genEmpty)
            {
                map = MapGenerator.GenerateEmpty(mapWidth, mapLength, mapHeight);

            }
            else if (genOcean)
            {
                map = MapGenerator.GenerateOcean(mapWidth, mapLength, mapHeight);

            }
            else if (genFlatgrass)
            {
                map = MapGenerator.GenerateFlatgrass(mapWidth, mapLength, mapHeight);

            }
            else
            {
                MapGeneratorArgs args = MapGenerator.MakeTemplate(template);
                if (theme == MapGenTheme.Desert)
                {
                    args.AddWater = false;
                }
                float ratio = mapHeight / (float)args.MapHeight;
                args.MapWidth = mapWidth;
                args.MapLength = mapLength;
                args.MapHeight = mapHeight;
                args.MaxHeight = (int)Math.Round(args.MaxHeight * ratio);
                args.MaxDepth = (int)Math.Round(args.MaxDepth * ratio);
                args.SnowAltitude = (int)Math.Round(args.SnowAltitude * ratio);
                args.Theme = theme;
                args.AddTrees = !noTrees;

                MapGenerator generator = new MapGenerator(args);
                map = generator.Generate();
            }

            // save map to file, or load it into a world
            if (fileName != null)
            {
                if (map.Save(fullFileName))
                {
                    player.Message("Generation done. Saved to {0}", fileName);
                }
                else
                {
                    player.Message("&WAn error occured while saving generated map to {0}", fileName);
                }
            }
            else
            {
                if (playerWorld == null) PlayerOpException.ThrowNoWorld(player);
                player.MessageNow("Generation done. Changing map...");
                playerWorld.MapChangedBy = player.Name;
                playerWorld.ChangeMap(map);
            }
            Server.RequestGC();
        }
Пример #3
0
        static void WorldSaveHandler(Player player, Command cmd)
        {
            string p1 = cmd.Next(), p2 = cmd.Next();
            if (p1 == null)
            {
                CdWorldSave.PrintUsage(player);
                return;
            }

            World world = player.World;
            string fileName;
            if (p2 == null)
            {
                fileName = p1;
                if (world == null)
                {
                    player.Message("When called from console, /wsave requires WorldName. See \"/Help save\" for details.");
                    return;
                }
            }
            else
            {
                world = WorldManager.FindWorldOrPrintMatches(player, p1);
                if (world == null) return;
                fileName = p2;
            }

            // normalize the path
            fileName = fileName.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
            if (fileName.EndsWith("/") && fileName.EndsWith(@"\"))
            {
                fileName += world.Name + ".fcm";
            }
            else if (!fileName.ToLower().EndsWith(".fcm", StringComparison.OrdinalIgnoreCase))
            {
                fileName += ".fcm";
            }
            if (!Paths.IsValidPath(fileName))
            {
                player.Message("Invalid filename.");
                return;
            }
            string fullFileName = Path.Combine(Paths.MapPath, fileName);
            if (!Paths.Contains(Paths.MapPath, fullFileName))
            {
                player.MessageUnsafePath();
                return;
            }

            // Ask for confirmation if overwriting
            if (File.Exists(fullFileName))
            {
                FileInfo targetFile = new FileInfo(fullFileName);
                FileInfo sourceFile = new FileInfo(world.MapFileName);
                if (!targetFile.FullName.Equals(sourceFile.FullName, StringComparison.OrdinalIgnoreCase))
                {
                    if (!cmd.IsConfirmed)
                    {
                        player.Confirm(cmd, "Target file \"{0}\" already exists, and will be overwritten.", targetFile.Name);
                        return;
                    }
                }
            }

            // Create the target directory if it does not exist
            string dirName = fullFileName.Substring(0, fullFileName.LastIndexOf(Path.DirectorySeparatorChar));
            if (!Directory.Exists(dirName))
            {
                Directory.CreateDirectory(dirName);
            }

            player.MessageNow("Saving map to {0}", fileName);

            const string mapSavingErrorMessage = "Map saving failed. See server logs for details.";
            Map map = world.Map;
            if (map == null)
            {
                if (File.Exists(world.MapFileName))
                {
                    try
                    {
                        File.Copy(world.MapFileName, fullFileName, true);
                    }
                    catch (Exception ex)
                    {
                        Logger.Log(LogType.Error,
                                    "WorldCommands.WorldSave: Error occured while trying to copy an unloaded map: {0}", ex);
                        player.Message(mapSavingErrorMessage);
                    }
                }
                else
                {
                    Logger.Log(LogType.Error,
                                "WorldCommands.WorldSave: Map for world \"{0}\" is unloaded, and file does not exist.",
                                world.Name);
                    player.Message(mapSavingErrorMessage);
                }
            }
            else if (map.Save(fullFileName))
            {
                player.Message("Map saved succesfully.");
            }
            else
            {
                Logger.Log(LogType.Error,
                            "WorldCommands.WorldSave: Saving world \"{0}\" failed.", world.Name);
                player.Message(mapSavingErrorMessage);
            }
        }
Пример #4
0
        static void GenHandler( Player player, CommandReader cmd ) {
            World playerWorld = player.World;
            World world = null;
            string fileName = null;
            int mapWidth,
                mapLength,
                mapHeight;

            // make sure the player has generator parameters set
            MapGeneratorParameters genParams = player.GenParams;
            if( genParams == null ) {
                player.Message( "No gen parameters set. Use &H/SetGen&S to configure map generation." );
                return;
            }

            if( cmd.HasNext ) {
                // Something's given, assume that it's map dimensions.
                if( !(cmd.NextInt( out mapWidth ) && cmd.NextInt( out mapLength ) && cmd.NextInt( out mapHeight )) ) {
                    CdGen.PrintUsage( player );
                    return;
                }

            } else if( playerWorld != null ) {
                // Nothing is given. Assume that we're replacing the current world.
                // Use dimensions of the currently-loaded map.
                Map oldMap = playerWorld.LoadMap();
                mapWidth = oldMap.Width;
                mapLength = oldMap.Length;
                mapHeight = oldMap.Height;
                world = playerWorld;

            } else {
                player.Message( "When used from console, /Gen requires map dimensions." );
                CdGen.PrintUsage( player );
                return;
            }

            // Check map dimensions and volume
            const string dimensionRecommendation = "Dimensions must be between 16 and 2047. " +
                                                   "Recommended values: 16, 32, 64, 128, 256, 512, and 1024.";
            if( !Map.IsValidDimension( mapWidth ) ) {
                player.Message( "Cannot make map with width {0}. {1}", mapWidth, dimensionRecommendation );
                return;
            } else if( !Map.IsValidDimension( mapLength ) ) {
                player.Message( "Cannot make map with length {0}. {1}", mapLength, dimensionRecommendation );
                return;
            } else if( !Map.IsValidDimension( mapHeight ) ) {
                player.Message( "Cannot make map with height {0}. {1}", mapHeight, dimensionRecommendation );
                return;
            }
            long volume = (long)mapWidth*mapLength*mapHeight;
            if( volume > Int32.MaxValue ) {
                player.Message( "Map volume may not exceed {0}", Int32.MaxValue );
                return;
            }

            // Print dimension warning, if applicable.
            if( !cmd.IsConfirmed && // Only print once -- before confirmation is given.
                (!Map.IsRecommendedDimension( mapWidth ) || !Map.IsRecommendedDimension( mapLength ) ||
                 mapHeight%16 != 0) ) {
                player.Message( "&WThe map will have non-standard dimensions. " +
                                "You may see glitched blocks or visual artifacts. " +
                                "The only recommended map dimensions are: 16, 32, 64, 128, 256, 512, and 1024." );
            }

            // See what else the player has given us...
            string givenName = cmd.Next();
            if( givenName == null ) {
                // No name given. Assume that we're replacing the current world.
                if( playerWorld != null ) {
                    world = playerWorld;
                    if( !cmd.IsConfirmed ) {
                        Logger.Log( LogType.UserActivity,
                                    "Gen: Asked {0} to confirm replacing the map of world {1} (\"this map\")",
                                    player.Name,
                                    playerWorld.Name );
                        player.Confirm( cmd, "Gen: Replace THIS MAP with a generated one ({0})?", genParams );
                        return;
                    }

                } else {
                    player.Message( "When used from console, /Gen requires a world name or map file name." );
                    CdGen.PrintUsage( player );
                    return;
                }

            } else {
                // Either a world name or a filename was given. Check worlds first.
                World existingWorld = WorldManager.FindWorldExact( givenName );

                if( existingWorld != null ) {
                    // A matching world name found. Assume that we're replacing it.
                    if( !cmd.IsConfirmed ) {
                        Logger.Log( LogType.UserActivity,
                                    "Gen: Asked {0} to confirm replacing the map of world {1}",
                                    player.Name,
                                    existingWorld.Name );
                        player.Confirm( cmd,
                                        "Gen: Replace the map of world {0}&S with a generated one ({1})?",
                                        existingWorld.ClassyName,
                                        genParams );
                        return;
                    }
                    world = existingWorld;

                } else {
                    // No world with this name found. Assume that we were given a filename.
                    givenName = givenName.Replace( Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar );
                    if( !givenName.EndsWith( ".fcm", StringComparison.OrdinalIgnoreCase ) ) {
                        givenName += ".fcm";
                    }
                    if( !Paths.IsValidPath( givenName ) ) {
                        player.Message( "Gen: Invalid file name given." );
                        return;
                    }
                    fileName = Path.Combine( Paths.MapPath, givenName );
                    if( !Paths.Contains( Paths.MapPath, fileName ) ) {
                        player.MessageUnsafePath();
                        return;
                    }
                    if( File.Exists( fileName ) ) {
                        if( !cmd.IsConfirmed ) {
                            Logger.Log( LogType.UserActivity,
                                        "Gen: Asked {0} to confirm overwriting map file \"{1}\"",
                                        player.Name,
                                        givenName );
                            player.Confirm( cmd, "Gen: The map file \"{0}\" already exists. Overwrite?", givenName );
                            return;
                        }
                    }
                }
            }

            // Warn players on the affected world, if applicable
            if( world != null ) {
                world.Players
                     .Except( player )
                     .Message( "&SIncoming map change!" );
            }

            // Prepare to generate
            genParams.MapWidth = mapWidth;
            genParams.MapLength = mapLength;
            genParams.MapHeight = mapHeight;
            GenTaskParams genTaskParams = new GenTaskParams {
                Player = player,
                World = world,
                FileName = givenName,
                FullFileName = fileName,
                GenState = genParams.CreateGenerator()
            };
            player.MessageNow( "Generating (please wait): {0}", genParams );

            // Do the rest in a background thread
            Scheduler.NewBackgroundTask( GenTaskCallback, genTaskParams )
                     .RunOnce();
        }
Пример #5
0
        public static void RealmCreate(Player player, Command cmd, string themeName, string templateName)
        {
            MapGenTemplate template;
            MapGenTheme theme;

            int wx, wy, height = 128;
            if (!(cmd.NextInt(out wx) && cmd.NextInt(out wy) && cmd.NextInt(out height)))
            {
                if (player.World != null)
                {
                    wx = 128;
                    wy = 128;
                    height = 128;
                }
                else
                {
                    player.Message("When used from console, /gen requires map dimensions.");

                    return;
                }
                cmd.Rewind();
                cmd.Next();
                cmd.Next();
            }

            if (!Map.IsValidDimension(wx))
            {
                player.Message("Cannot make map with width {0}: dimensions must be multiples of 16.", wx);
                return;
            }
            else if (!Map.IsValidDimension(wy))
            {
                player.Message("Cannot make map with length {0}: dimensions must be multiples of 16.", wy);
                return;
            }
            else if (!Map.IsValidDimension(height))
            {
                player.Message("Cannot make map with height {0}: dimensions must be multiples of 16.", height);
                return;
            }

            string fileName = player.Name;
            string fullFileName = null;

            if (fileName == null)
            {
                if (player.World == null)
                {
                    player.Message("When used from console, /gen requires FileName.");

                    return;
                }
                if (!cmd.IsConfirmed)
                {
                    player.Confirm(cmd, "Replace this realm's map with a generated one?");
                    return;
                }
            }
            else
            {
                fileName = fileName.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
                if (!fileName.EndsWith(".fcm", StringComparison.OrdinalIgnoreCase))
                {
                    fileName += ".fcm";
                }
                fullFileName = Path.Combine(Paths.MapPath, fileName);
                if (!Paths.IsValidPath(fullFileName))
                {
                    player.Message("Invalid filename.");
                    return;
                }
                if (!Paths.Contains(Paths.MapPath, fullFileName))
                {
                    player.MessageUnsafePath();
                    return;
                }
                string dirName = fullFileName.Substring(0, fullFileName.LastIndexOf(Path.DirectorySeparatorChar));
                if (!Directory.Exists(dirName))
                {
                    Directory.CreateDirectory(dirName);
                }
                if (!cmd.IsConfirmed && File.Exists(fullFileName))
                {
                    player.Confirm(cmd, "The mapfile \"{0}\" already exists. Overwrite?", fileName);
                    return;
                }
            }

            bool noTrees;
            if (themeName.Equals("grass", StringComparison.OrdinalIgnoreCase))
            {
                theme = MapGenTheme.Forest;
                noTrees = true;
            }
            else
            {
                try
                {
                    theme = (MapGenTheme)Enum.Parse(typeof(MapGenTheme), themeName, true);
                    noTrees = (theme != MapGenTheme.Forest);
                }
                catch (Exception)
                {
                    player.MessageNow("Unrecognized theme \"{0}\". Available themes are: Grass, {1}",
                                       themeName,
                                       String.Join(", ", Enum.GetNames(typeof(MapGenTheme))));
                    return;
                }
            }

            try
            {
                template = (MapGenTemplate)Enum.Parse(typeof(MapGenTemplate), templateName, true);
            }
            catch (Exception)
            {
                player.Message("Unrecognized template \"{0}\". Available templates are: {1}",
                                templateName,
                                String.Join(", ", Enum.GetNames(typeof(MapGenTemplate))));
                return;
            }

            if (!Enum.IsDefined(typeof(MapGenTheme), theme) || !Enum.IsDefined(typeof(MapGenTemplate), template))
            {

                return;
            }

            MapGeneratorArgs args = MapGenerator.MakeTemplate(template);
            args.MapWidth = wx;
            args.MapLength = wy;
            args.MapHeight = height;
            args.MaxHeight = (int)(args.MaxHeight / 80d * height);
            args.MaxDepth = (int)(args.MaxDepth / 80d * height);
            args.Theme = theme;
            args.AddTrees = !noTrees;

            Map map;
            try
            {
                if (theme == MapGenTheme.Forest && noTrees)
                {
                    player.MessageNow("Generating Grass {0}...", template);
                }
                else
                {
                    player.MessageNow("Generating {0} {1}...", theme, template);
                }
                if (theme == MapGenTheme.Forest && noTrees && template == MapGenTemplate.Flat)
                {
                    map = MapGenerator.GenerateFlatgrass(args.MapWidth, args.MapLength, args.MapHeight);
                }
                else
                {
                    MapGenerator generator = new MapGenerator(args);
                    map = generator.Generate();
                }

            }
            catch (Exception ex)
            {
                Logger.Log(LogType.Error, "MapGenerator: Generation failed: {0}",
                            ex);
                player.MessageNow("&WAn error occured while generating the map.");
                return;
            }

            if (fileName != null)
            {
                if (map.Save(fullFileName))
                {
                    player.MessageNow("Generation done. Saved to {0}", fileName);
                }
                else
                {
                    player.Message("&WAn error occured while saving generated map to {0}", fileName);
                }
            }
            else
            {
                player.MessageNow("Generation done. Changing map...");
                player.World.ChangeMap(map);
            }
        }
Пример #6
0
        static void DumpStatsHandler( Player player, CommandReader cmd ) {
            string fileName = cmd.Next();
            if( fileName == null ) {
                CdDumpStats.PrintUsage( player );
                return;
            }

            if( !Paths.Contains( Paths.WorkingPath, fileName ) ) {
                player.MessageUnsafePath();
                return;
            }

            if( Paths.IsProtectedFileName( Path.GetFileName( fileName ) ) ) {
                player.Message( "You may not use this file." );
                return;
            }

            string extension = Path.GetExtension( fileName );
            if( extension == null || !extension.Equals( ".txt", StringComparison.OrdinalIgnoreCase ) ) {
                player.Message( "Stats file name must end with .txt" );
                return;
            }

            if( File.Exists( fileName ) && !cmd.IsConfirmed ) {
                Logger.Log( LogType.UserActivity,
                            "DumpStats: Asked {0} for confirmation to overwrite \"{1}\"",
                            player.Name, fileName );
                player.Confirm( cmd, "File \"{0}\" already exists. Overwrite?", Path.GetFileName( fileName ) );
                return;
            }

            if( !Paths.TestFile( "DumpStats file", fileName, false, FileAccess.Write ) ) {
                player.Message( "Cannot create specified file. See log for details." );
                return;
            }

            using( FileStream fs = File.Create( fileName ) ) {
                using( StreamWriter writer = new StreamWriter( fs ) ) {
                    PlayerInfo[] infos = PlayerDB.PlayerInfoList;
                    if( infos.Length == 0 ) {
                        writer.WriteLine( "(TOTAL) (0 players)" );
                        writer.WriteLine();
                    } else {
                        DumpPlayerGroupStats( writer, infos, "(TOTAL)" );
                    }

                    List<PlayerInfo> rankPlayers = new List<PlayerInfo>();
                    foreach( Rank rank in RankManager.Ranks ) {
                        rankPlayers.AddRange( infos.Where( t => t.Rank == rank ) );
                        if( rankPlayers.Count == 0 ) {
                            writer.WriteLine( "{0}: 0 players, 0 banned, 0 inactive", rank.Name );
                            writer.WriteLine();
                        } else {
                            DumpPlayerGroupStats( writer, rankPlayers, rank.Name );
                        }
                        rankPlayers.Clear();
                    }
                }
            }

            player.Message( "Stats saved to \"{0}\"", fileName );
        }
Пример #7
0
        static void WorldClearSaveHandler(Player player, CommandReader cmd)
        {
            string WorldCSave = player.World.Name;
            if (player.World.Name == null)
            {
                CdWorldSave.PrintUsage(player);
                return;
            }

            World world = player.World;
            string fileName;
            fileName = WorldCSave;
            {
                world = WorldManager.FindWorldOrPrintMatches(player, WorldCSave);
                if (world == null) return;
                fileName = WorldCSave;
            }

            // normalize the path
            fileName = fileName.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
            fileName = "World(" + WorldCSave + ")clear.fcm";
            if (!Paths.IsValidPath(fileName))
            {
                player.Message("Invalid file name.");
                return;
            }
            string fullFileName = Path.Combine(Paths.WClearPath, fileName);
            if (!Paths.Contains(Paths.WClearPath, fullFileName))
            {
                player.MessageUnsafePath();
                return;
            }

            // Ask for confirmation if overwriting
            if (File.Exists(fullFileName))
            {
                FileInfo targetFile = new FileInfo(fullFileName);
                FileInfo sourceFile = new FileInfo(world.MapFileName);
                if (!targetFile.FullName.Equals(sourceFile.FullName, StringComparison.OrdinalIgnoreCase))
                {
                    if (!cmd.IsConfirmed)
                    {
                        Logger.Log(LogType.UserActivity,
                                    "WCSave: Asked {0} to confirm overwriting map file \"{1}\"",
                                    player.Name, targetFile.FullName);
                        player.Confirm(cmd, "Target file \"{0}\" already exists, and will be overwritten.", targetFile.Name);
                        return;
                    }
                }
            }

            // Create the target directory if it does not exist
            string dirName = fullFileName.Substring(0, fullFileName.LastIndexOf(Path.DirectorySeparatorChar));
            if (!Directory.Exists(dirName))
            {
                Directory.CreateDirectory(dirName);
            }

            player.Message("Saving map to {0}", fileName);

            const string mapSavingErrorMessage = "Map saving failed. See server logs for details.";
            Map map = world.Map;
            if (map == null)
            {
                if (File.Exists(world.MapFileName))
                {
                    try
                    {
                        File.Copy(world.MapFileName, fullFileName, true);
                    }
                    catch (Exception ex)
                    {
                        Logger.Log(LogType.Error,
                                    "WorldCommands.WorldCSave: Error occurred while trying to copy an unloaded map: {0}", ex);
                        player.Message(mapSavingErrorMessage);
                    }
                }
                else
                {
                    Logger.Log(LogType.Error,
                                "WorldCommands.WorldCSave: Map for world \"{0}\" is unloaded, and file does not exist.",
                                world.Name);
                    player.Message(mapSavingErrorMessage);
                }
            }
            else if (map.Save(fullFileName))
            {
                player.Message("Map saved succesfully.");
            }
            else
            {
                Logger.Log(LogType.Error,
                            "WorldCommands.WorldCSave: Saving world \"{0}\" failed.", world.Name);
                player.Message(mapSavingErrorMessage);
            }
        }
Пример #8
0
        // TODO: document the fact that this only promotes (unlike "/Import Ranks")
        static void ImportRankListHandler( Player player, CommandReader cmd ) {
            string fileName = cmd.Next();
            string rankName = cmd.Next();
            string reason = cmd.NextAll();

            if( fileName == null || rankName == null ) {
                CdImportRankList.PrintUsage( player );
                return;
            }

            // parse rank name
            Rank rank = RankManager.FindRank( rankName );
            if( rank == null ) {
                player.MessageNoRank( rankName );
                return;
            }
            
            // Make sure that the target file is legit
            if( !Paths.Contains( Paths.WorkingPath, fileName ) ) {
                Logger.Log( LogType.SuspiciousActivity,
                            "ImportRankList: Player {0} tried to import from \"{1}\"",
                            player.Name,
                            fileName );
                player.MessageUnsafePath();
                return;
            }

            // Make sure file exists
            if( !File.Exists( fileName ) ) {
                player.Message( "Rank list file not found: " + fileName );
                return;
            }

            // Read list of names from file.
            // Using List list to preserve capitalization and a HashSet to avoid duplicates.
            List<string> nameList = new List<string>();
            using( StreamReader reader = new StreamReader( fileName ) ) {
                HashSet<string> lowerNameSet = new HashSet<string>();
                while( true ) {
                    string nextName = reader.ReadLine();
                    if( nextName == null ) break;
                    if( !Player.IsValidPlayerName( nextName ) ) {
                        player.Message( "ImportRankList: Invalid player name skipped: {0}", nextName );
                        continue;
                    }
                    string nameToLower = nextName.ToLowerInvariant();
                    if( lowerNameSet.Contains( nameToLower ) ) {
                        player.Message( "ImportRankList: Skipping a duplicate name: {0}", nextName );
                        continue;
                    }
                    nameList.Add( nextName );
                    lowerNameSet.Add( nameToLower );
                }
            }

            // Ask player to confirm before continuing
            if( !cmd.IsConfirmed ) {
                Logger.Log( LogType.UserActivity,
                            "Import: Asked {0} to confirm importing {1} ranks from {2}",
                            player.Name,
                            nameList.Count,
                            fileName );
                player.Confirm( cmd,
                                "ImportRankList: Are you sure you want to rank {0} players to {1}&S?",
                                nameList.Count,
                                rank.ClassyName );
                return;
            }

            // Carry out the promotions
            int newPlayers = 0,
                promotedPlayers = 0,
                skippedPlayers = 0;
            foreach( string name in nameList ) {
                PlayerInfo info = PlayerDB.FindPlayerInfoExact( name );
                if( info == null ) {
                    // Create and promote a new record
                    newPlayers++;
                    PlayerInfo newInfo = PlayerDB.CreateNewPlayerInfo( name, RankChangeType.Promoted );
                    newInfo.ChangeRank( player, rank, reason, true, true, false );
                    Logger.Log( LogType.UserActivity, "ImportRankList: Created a new player record for {0}", name );

                } else {
                    // Check if an existing record needs updating
                    if( info.Rank < rank && // don't demote anyone
                        !info.IsBanned && // don't promote banned players
                        info.RankChangeType != RankChangeType.Demoted && // don't re-promote demoted players
                        info.RankChangeType != RankChangeType.AutoDemoted ) {
                        // Promote!
                        info.ChangeRank( player, rank, reason, true, true, false );
                        promotedPlayers++;

                    } else {
                        skippedPlayers++;
                    }
                }
            }
            string successMsg = String.Format(
                "ImportRankList: Created {0} new records, promoted {1} players, " +
                "skipped {2} records from file \"{3}\"",
                newPlayers,
                promotedPlayers,
                skippedPlayers,
                Path.GetFileName( fileName ) );
            Logger.Log( LogType.UserActivity, successMsg );
            player.Message( successMsg );
        }
Пример #9
0
        public static string FindMapFile([NotNull] Player player, [NotNull] string fileName)
        {
            if (player == null)
            {
                throw new ArgumentNullException("player");
            }
            if (fileName == null)
            {
                throw new ArgumentNullException("fileName");
            }
            // Check if path contains missing drives or invalid characters
            if (!Paths.IsValidPath(fileName))
            {
                player.Message("Invalid file name or path.");
                return(null);
            }

            // Look for the file
            string sourceFullFileName = Path.Combine(Paths.MapPath, fileName);

            if (!File.Exists(sourceFullFileName) && !Directory.Exists(sourceFullFileName))
            {
                if (File.Exists(sourceFullFileName + Map.SaveExt))
                {
                    // Try with extension added
                    sourceFullFileName += Map.SaveExt;
                }
                else if (MonoCompat.IsCaseSensitive)
                {
                    try {
                        // If we're on a case-sensitive OS, try case-insensitive search
                        FileInfo[] candidates = Paths.FindFiles(sourceFullFileName + Map.SaveExt);
                        if (candidates.Length == 0)
                        {
                            candidates = Paths.FindFiles(sourceFullFileName);
                        }

                        switch (candidates.Length)
                        {
                        case 0:
                            player.Message("File/directory not found: {0}", fileName);
                            break;

                        case 1:
                            player.Message("File names are case-sensitive! Did you mean to load \"{0}\"?",
                                           candidates[0].Name);
                            break;

                        default:
                            player.Message("File names are case-sensitive! Did you mean to load one of these: {0}",
                                           String.Join(", ", candidates.Select(c => c.Name).ToArray()));
                            break;
                        }
                    } catch (DirectoryNotFoundException ex) {
                        player.Message(ex.Message);
                    }
                    return(null);
                }
                else
                {
                    // Nothing found!
                    player.Message("File/directory not found: {0}", fileName);
                    return(null);
                }
            }

            // Make sure that the given file is within the map directory
            if (!Paths.Contains(Paths.MapPath, sourceFullFileName))
            {
                player.MessageUnsafePath();
                return(null);
            }

            return(sourceFullFileName);
        }
Пример #10
0
        public static void RealmCreate(Player player, Command cmd, string themeName, string templateName)
        {
            MapGenTemplate template;
            MapGenTheme theme;

            int wx, wy, height = 128;
            if (!(cmd.NextInt(out wx) && cmd.NextInt(out wy) && cmd.NextInt(out height)))
            {
                if (player.World != null)
                {
                    wx = 128;
                    wy = 128;
                    height = 128;
                }
                else
                {
                    player.Message("When used from console, /gen requires map dimensions.");

                    return;
                }
                cmd.Rewind();
                cmd.Next();
                cmd.Next();
            }

            if (!Map.IsValidDimension(wx))
            {
                player.Message("Cannot make map with width {0}: dimensions must be multiples of 16.", wx);
                return;
            }
            else if (!Map.IsValidDimension(wy))
            {
                player.Message("Cannot make map with length {0}: dimensions must be multiples of 16.", wy);
                return;
            }
            else if (!Map.IsValidDimension(height))
            {
                player.Message("Cannot make map with height {0}: dimensions must be multiples of 16.", height);
                return;
            }

            string fileName = player.Name;
            if (player.Name.Contains('.'))
            {
                fileName = player.Name.Replace(".", "-"); //support for email names
            }
            
            string fullFileName = null;

            if (fileName == null)
            {
                if (player.World == null)
                {
                    player.Message("When used from console, /gen requires FileName.");

                    return;
                }
                if (!cmd.IsConfirmed)
                {
                    player.Confirm(cmd, "Replace this realm's map with a generated one?");
                    return;
                }
            }
            else
            {
                fileName = fileName.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
                if (!fileName.EndsWith(".fcm", StringComparison.OrdinalIgnoreCase))
                {
                    fileName += ".fcm";
                }
                fullFileName = Path.Combine(Paths.MapPath, fileName);
                if (!Paths.IsValidPath(fullFileName))
                {
                    player.Message("Invalid filename.");
                    return;
                }
                if (!Paths.Contains(Paths.MapPath, fullFileName))
                {
                    player.MessageUnsafePath();
                    return;
                }
                string dirName = fullFileName.Substring(0, fullFileName.LastIndexOf(Path.DirectorySeparatorChar));
                if (!Directory.Exists(dirName))
                {
                    Directory.CreateDirectory(dirName);
                }
                if (!cmd.IsConfirmed && File.Exists(fullFileName))
                {
                    player.Confirm(cmd, "The mapfile \"{0}\" already exists. Overwrite?", fileName);
                    return;
                }
            }

            bool noTrees;
            if (themeName.Equals("grass", StringComparison.OrdinalIgnoreCase))
            {
                theme = MapGenTheme.Forest;
                noTrees = true;
            }
            else
            {
                try
                {
                    theme = (MapGenTheme)Enum.Parse(typeof(MapGenTheme), themeName, true);
                    noTrees = (theme != MapGenTheme.Forest);
                }
                catch (Exception)
                {
                    player.MessageNow("Unrecognized theme \"{0}\". Available themes are: Grass, {1}",
                                       themeName,
                                       String.Join(", ", Enum.GetNames(typeof(MapGenTheme))));
                    return;
                }
            }

            try
            {
                template = (MapGenTemplate)Enum.Parse(typeof(MapGenTemplate), templateName, true);
            }
            catch (Exception)
            {
                player.Message("Unrecognized template \"{0}\". Available templates are: {1}",
                                templateName,
                                String.Join(", ", Enum.GetNames(typeof(MapGenTemplate))));
                return;
            }

            if (!Enum.IsDefined(typeof(MapGenTheme), theme) || !Enum.IsDefined(typeof(MapGenTemplate), template))
            {

                return;
            }

            MapGeneratorArgs args = MapGenerator.MakeTemplate(template);
            args.MapWidth = wx;
            args.MapLength = wy;
            args.MapHeight = height;
            args.MaxHeight = (int)(args.MaxHeight / 80d * height);
            args.MaxDepth = (int)(args.MaxDepth / 80d * height);
            args.Theme = theme;
            args.AddTrees = !noTrees;

            Map map;
            try
            {
                if (theme == MapGenTheme.Forest && noTrees)
                {
                    player.MessageNow("Generating Grass {0}...", template);
                }
                else
                {
                    player.MessageNow("Generating {0} {1}...", theme, template);
                }
                if (theme == MapGenTheme.Forest && noTrees && template == MapGenTemplate.Flat)
                {
                    map = MapGenerator.GenerateFlatgrass(args.MapWidth, args.MapLength, args.MapHeight);
                }
                else
                {
                    MapGenerator generator = new MapGenerator(args);
                    map = generator.Generate();
                }

            }
            catch (Exception ex)
            {
                Logger.Log(LogType.Error, "MapGenerator: Generation failed: {0}",
                            ex);
                player.MessageNow("&WAn error occured while generating the map.");
                return;
            }

            if (fileName != null)
            {
                if (map.Save(fullFileName))
                {
                    player.MessageNow("Generation done. Saved to {0}", fileName);
                }
                else
                {
                    player.Message("&WAn error occured while saving generated map to {0}", fileName);
                }
            }
            else
            {
                player.MessageNow("Generation done. Changing map...");
                player.World.ChangeMap(map);
            }
        }