Пример #1
1
        internal static void StaffChat( Player player, Command cmd ) {
            if( player.Info.IsMuted ) {
                player.MutedMessage();
                return;
            }

            if( DateTime.UtcNow < player.Info.MutedUntil ) {
                player.Message( "You are muted for another {0:0} seconds.",
                                player.Info.MutedUntil.Subtract( DateTime.UtcNow ).TotalSeconds );
                return;
            }


            Player[] plist = Server.PlayerList;

            if( plist.Length > 0 ) player.Info.LinesWritten++;

            string message = cmd.NextAll();
            if( message != null && message.Trim().Length > 0 ) {
                message = message.Trim();
                if( player.Can( Permission.UseColorCodes ) && message.Contains( "%" ) ) {
                    message = Color.ReplacePercentCodes( message );
                }
                for( int i = 0; i < plist.Length; i++ ) {
                    if( (plist[i].Can( Permission.ReadStaffChat ) || plist[i] == player) && !plist[i].IsIgnoring( player.Info ) ) {
                        plist[i].Message( "{0}(staff){1}{0}: {2}", Color.PM, player.GetClassyName(), message );
                    }
                }
            }
        }
Пример #2
0
 internal static void PlayerMessageHandler(Player player, World world, ref string message, ref bool cancel)
 {
     if (ConfigKey.IRCBotForwardFromServer.GetBool())
     {
         SendChannelMessage(player.GetClassyName() + Color.IRCReset + ": " + message);
     }
     else if (message.StartsWith("#"))
     {
         SendChannelMessage(player.GetClassyName() + Color.IRCReset + ": " + message.Substring(1));
     }
 }
Пример #3
0
 public bool Lock(Player player)
 {
     if (player == null)
     {
         throw new ArgumentNullException("player");
     }
     lock ( lockLock ) {
         if (IsLocked)
         {
             return(false);
         }
         else
         {
             LockedBy   = player.Name;
             LockedDate = DateTime.UtcNow;
             IsLocked   = true;
             if (Map != null)
             {
                 Map.ClearUpdateQueue();
             }
             SendToAll("&WMap was locked by {0}", player.GetClassyName());
             Logger.Log("World {0} was locked by {1}", LogType.UserActivity,
                        Name, player.Name);
             return(true);
         }
     }
 }
Пример #4
0
 public bool Spectate(Player target)
 {
     if (target == null)
     {
         throw new ArgumentNullException("target");
     }
     if (target == this)
     {
         throw new ArgumentException("Cannot spectate self.", "target");
     }
     Message("Now spectating {0}&S. Type &H/unspec&S to stop.", target.GetClassyName());
     return(Interlocked.Exchange <Player>(ref Session.SpectatedPlayer, target) == null);
 }
Пример #5
0
        public bool StopSpectating()
        {
            Player wasSpectating = Interlocked.Exchange <Player>(ref Session.SpectatedPlayer, null);

            if (wasSpectating != null)
            {
                Message("Stopped spectating {0}", wasSpectating.GetClassyName());
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #6
0
        static void PlayerSomethingMessage(Player player, string action, PlayerInfo target, string reason)
        {
            string message = String.Format("{0}&W* {1}&W was {2} by {3}&W",
                                           Color.IRCBold,
                                           target.GetClassyName(),
                                           action,
                                           player.GetClassyName());

            if (!String.IsNullOrEmpty(reason))
            {
                message += " Reason: " + reason;
            }
            if (ConfigKey.IRCBotAnnounceServerEvents.GetBool())
            {
                SendAction(message);
            }
        }
Пример #7
0
        internal static void StaffChat(Player player, Command cmd)
        {
            if (player.Info.IsMuted)
            {
                player.MutedMessage();
                return;
            }

            if (DateTime.UtcNow < player.Info.MutedUntil)
            {
                player.Message("You are muted for another {0:0} seconds.",
                               player.Info.MutedUntil.Subtract(DateTime.UtcNow).TotalSeconds);
                return;
            }


            Player[] plist = Server.PlayerList;

            if (plist.Length > 0)
            {
                player.Info.LinesWritten++;
            }

            string message = cmd.NextAll();

            if (message != null && message.Trim().Length > 0)
            {
                message = message.Trim();
                if (player.Can(Permission.UseColorCodes) && message.Contains("%"))
                {
                    message = Color.ReplacePercentCodes(message);
                }
                for (int i = 0; i < plist.Length; i++)
                {
                    if ((plist[i].Can(Permission.ReadStaffChat) || plist[i] == player) && !plist[i].IsIgnoring(player.Info))
                    {
                        plist[i].Message("{0}(staff){1}{0}: {2}", Color.PM, player.GetClassyName(), message);
                    }
                }
            }
        }
Пример #8
0
        internal static void Where(Player player, Command cmd)
        {
            string name = cmd.Next();

            Player target = player;

            if (name != null)
            {
                target = Server.FindPlayerOrPrintMatches(player, name, false);
                if (target == null)
                {
                    return;
                }
            }
            else if (player.World == null)
            {
                player.Message("When called form console, &H/where&S requires a player name.");
                return;
            }

            player.Message("Player {0}&S is on world {1}&S:",
                           target.GetClassyName(),
                           target.World.GetClassyName());


            int offset = (int)(target.Position.R / 255f * 64f) + 32;

            player.Message("{0}({1},{2},{3}) - {4}[{5}{6}{7}{4}{8}]",
                           Color.Silver,
                           target.Position.X / 32,
                           target.Position.Y / 32,
                           target.Position.H / 32,
                           Color.White,
                           Compass.Substring(offset - 12, 11),
                           Color.Red,
                           Compass.Substring(offset - 1, 3),
                           Compass.Substring(offset + 2, 11));
        }
Пример #9
0
 public bool Unlock(Player player)
 {
     if (player == null)
     {
         throw new ArgumentNullException("player");
     }
     lock ( lockLock ) {
         if (IsLocked)
         {
             UnlockedBy   = player.Name;
             UnlockedDate = DateTime.UtcNow;
             IsLocked     = false;
             SendToAll("&WMap was unlocked by {0}", player.GetClassyName());
             Logger.Log("World \"{0}\" was unlocked by {1}", LogType.UserActivity,
                        Name, player.Name);
             return(true);
         }
         else
         {
             return(false);
         }
     }
 }
Пример #10
0
        internal static void Roll(Player player, Command cmd)
        {
            if (player.Info.IsMuted)
            {
                player.MutedMessage();
                return;
            }

            Random rand = new Random();
            int    min = 1, max = 100, t1;

            if (cmd.NextInt(out t1))
            {
                int t2;
                if (cmd.NextInt(out t2))
                {
                    if (t2 < t1)
                    {
                        min = t2;
                        max = t1;
                    }
                    else
                    {
                        min = t1;
                        max = t2;
                    }
                }
                else if (t1 >= 1)
                {
                    max = t1;
                }
            }
            int num = rand.Next(min, max + 1);

            Server.SendToAll("{0}{1} rolled {2} ({3}...{4})",
                             player.GetClassyName(), Color.Silver, num, min, max);
        }
Пример #11
0
 public bool Spectate( Player target ) {
     if( target == null ) throw new ArgumentNullException( "target" );
     if( target == this ) throw new ArgumentException( "Cannot spectate self.", "target" );
     Message( "Now spectating {0}&S. Type &H/unspec&S to stop.", target.GetClassyName() );
     return (Interlocked.Exchange<Player>( ref Session.SpectatedPlayer, target ) == null);
 }
Пример #12
0
        internal static void WorldLoad( Player player, Command cmd ) {
            string fileName = cmd.Next();
            string worldName = cmd.Next();

            if( worldName == null && player.World == null ) {
                player.Message( "When using /wload from console, you must specify the world name." );
                return;
            }

            if( fileName == null ) {
                // No params given at all
                cdWorldLoad.PrintUsage( player );
                return;
            }

            // Check if path contains missing drives or invalid characters
            if( !Paths.IsValidPath( fileName ) ) {
                player.Message( "Invalid filename or path." );
                return;
            }

            player.MessageNow( "Looking for \"{0}\"...", fileName );

            // Look for the file
            string sourceFullFileName = Path.Combine( Paths.MapPath, fileName );
            if( !File.Exists( sourceFullFileName ) && !Directory.Exists( sourceFullFileName ) ) {

                if( File.Exists( sourceFullFileName + ".fcm" ) ) {
                    // Try with extension added
                    fileName += ".fcm";
                    sourceFullFileName += ".fcm";

                } else if( MonoCompat.IsCaseSensitive ) {
                    try {
                        // If we're on a case-sensitive OS, try case-insensitive search
                        FileInfo[] candidates = Paths.FindFiles( sourceFullFileName + ".fcm" );
                        if( candidates.Length == 0 ) {
                            candidates = Paths.FindFiles( sourceFullFileName );
                        }

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

                        } else if( candidates.Length == 1 ) {
                            player.Message( "Filenames are case-sensitive! Did you mean to load \"{0}\"?", candidates[0].Name );

                        } else {
                            player.Message( "Filenames are case-sensitive! Did you mean to load one of these: {0}",
                                            String.Join( ", ", candidates.Select( c => c.Name ).ToArray() ) );
                        }
                    } catch( DirectoryNotFoundException ex ) {
                        player.Message( ex.Message );
                    }
                    return;

                } else {
                    // Nothing found!
                    player.Message( "File/directory not found: {0}", fileName );
                    return;
                }
            }

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

            // Loading map into current world
            if( worldName == null ) {
                if( !cmd.IsConfirmed ) {
                    player.AskForConfirmation( cmd, "About to replace THIS MAP with \"{0}\".", fileName );
                    return;
                }
                Map map;
                try {
                    map = MapUtility.Load( sourceFullFileName );
                } catch( Exception ex ) {
                    player.MessageNow( "Could not load specified file: {0}: {1}", ex.GetType().Name, ex.Message );
                    return;
                }

                // Loading to current world
                player.World.ChangeMap( map );
                player.World.SendToAllExcept( "{0}&S loaded a new map for this world.", player,
                                              player.GetClassyName() );
                player.MessageNow( "New map loaded for the world {0}", player.World.GetClassyName() );

                Logger.Log( "{0} loaded new map for world \"{1}\" from {2}", LogType.UserActivity,
                            player.Name, player.World.Name, fileName );


            } else {
                // Loading to some other (or new) world
                if( !World.IsValidName( worldName ) ) {
                    player.MessageNow( "Invalid world name: \"{0}\".", worldName );
                    return;
                }

                lock( WorldManager.WorldListLock ) {
                    World world = WorldManager.FindWorldExact( worldName );
                    if( world != null ) {
                        // Replacing existing world's map
                        if( !cmd.IsConfirmed ) {
                            player.AskForConfirmation( cmd, "About to replace map for {0}&S with \"{1}\".",
                                                       world.GetClassyName(), fileName );
                            return;
                        }

                        Map map;
                        try {
                            map = MapUtility.Load( sourceFullFileName );
                        } catch( Exception ex ) {
                            player.MessageNow( "Could not load specified file: {0}: {1}", ex.GetType().Name, ex.Message );
                            return;
                        }

                        try {
                            world.ChangeMap( map );
                        } catch( WorldOpException ex ) {
                            Logger.Log( "Could not complete WorldLoad operation: {0}", LogType.Error, ex.Message );
                            player.Message( "&WWLoad: {0}", ex.Message );
                            return;
                        }

                        world.SendToAllExcept( "{0}&S loaded a new map for the world {1}", player,
                                               player.GetClassyName(), world.GetClassyName() );
                        player.MessageNow( "New map for the world {0}&S has been loaded.", world.GetClassyName() );
                        Logger.Log( "{0} loaded new map for world \"{1}\" from {2}", LogType.UserActivity,
                                    player.Name, world.Name, sourceFullFileName );

                    } else {
                        // Adding a new world
                        string targetFullFileName = Path.Combine( Paths.MapPath, worldName + ".fcm" );
                        if( !cmd.IsConfirmed &&
                            File.Exists( targetFullFileName ) && // target file already exists
                            !Paths.Compare( targetFullFileName, sourceFullFileName ) ) { // and is different from sourceFile
                            player.AskForConfirmation( cmd, "A map named \"{0}\" already exists, and will be overwritten with \"{1}\".",
                                                       Path.GetFileName( targetFullFileName ), Path.GetFileName( sourceFullFileName ) );
                            return;
                        }

                        Map map;
                        try {
                            map = MapUtility.Load( sourceFullFileName );
                        } catch( Exception ex ) {
                            player.MessageNow( "Could not load \"{0}\": {1}: {2}",
                                               fileName, ex.GetType().Name, ex.Message );
                            return;
                        }

                        World newWorld;
                        try {
                            newWorld = WorldManager.AddWorld( player, worldName, map, false );
                        } catch( WorldOpException ex ) {
                            player.Message( "WLoad: {0}", ex.Message );
                            return;
                        }

                        if( newWorld != null ) {
                            newWorld.BuildSecurity.MinRank = RankManager.ParseRank( ConfigKey.DefaultBuildRank.GetString() );
                            Server.SendToAll( "{0}&S created a new world named {1}",
                                              player.GetClassyName(), newWorld.GetClassyName() );
                            Logger.Log( "{0} created a new world named \"{1}\" (loaded from \"{2}\")", LogType.UserActivity,
                                        player.Name, worldName, fileName );
                            WorldManager.SaveWorldList();
                            player.MessageNow( "Reminder: New world's access permission is {0}+&S, and build permission is {1}+",
                                               newWorld.AccessSecurity.MinRank.GetClassyName(),
                                               newWorld.BuildSecurity.MinRank.GetClassyName() );
                        } else {
                            player.MessageNow( "Failed to create a new world." );
                        }
                    }
                }
            }

            Server.RequestGC();
        }
Пример #13
0
        internal static void WorldBuild( Player player, Command cmd ) {
            string worldName = cmd.Next();

            // Print information about the current world
            if( worldName == null ) {
                if( player == Player.Console ) {
                    player.Message( "When calling /wbuild from console, you must specify a world name." );
                } else {
                    player.World.BuildSecurity.PrintDescription( player, player.World, "world", "modified" );
                }
                return;
            }

            // Find a world by name
            World world = WorldManager.FindWorldOrPrintMatches( player, worldName );
            if( world == null ) return;


            string name = cmd.Next();
            if( name == null ) {
                world.BuildSecurity.PrintDescription( player, world, "world", "modified" );
                return;
            }

            bool changesWereMade = false;
            do {
                if( name.Length < 2 ) continue;
                // Whitelisting individuals
                if( name.StartsWith( "+" ) ) {
                    PlayerInfo info;
                    if( !PlayerDB.FindPlayerInfo( name.Substring( 1 ), out info ) ) {
                        player.Message( "More than one player found matching \"{0}\"", name.Substring( 1 ) );
                        continue;
                    } else if( info == null ) {
                        player.NoPlayerMessage( name.Substring( 1 ) );
                        continue;
                    }

                    // prevent players from whitelisting themselves to bypass protection
                    if( player.Info == info && !player.Info.Rank.AllowSecurityCircumvention ) {
                        switch( world.BuildSecurity.CheckDetailed( player.Info ) ) {
                            case SecurityCheckResult.RankTooLow:
                                player.Message( "&WYou must be {0}&W+ to add yourself to the build whitelist of {0}",
                                                world.BuildSecurity.MinRank.GetClassyName(),
                                                world.GetClassyName() );
                                continue;
                            // TODO: RankTooHigh
                            case SecurityCheckResult.BlackListed:
                                player.Message( "&WYou cannot remove yourself from the build blacklist of {0}",
                                                world.GetClassyName() );
                                continue;
                        }
                    }

                    if( world.BuildSecurity.CheckDetailed( info ) == SecurityCheckResult.Allowed ) {
                        player.Message( "{0}&S is already allowed to build in {1}&S (by rank)",
                                        info.GetClassyName(), world.GetClassyName() );
                        continue;
                    }

                    Player target = Server.FindPlayerExact( info );
                    if( target == player ) target = null; // to avoid duplicate messages

                    switch( world.BuildSecurity.Include( info ) ) {
                        case PermissionOverride.Deny:
                            if( world.BuildSecurity.Check( info ) ) {
                                player.Message( "{0}&S is no longer barred from building in {1}",
                                                info.GetClassyName(), world.GetClassyName() );
                                if( target != null ) {
                                    target.Message( "You can now build in world {0}&S (removed from blacklist by {1}&S).",
                                                    world.GetClassyName(), player.GetClassyName() );
                                }
                            } else {
                                player.Message( "{0}&S was removed from the build blacklist of {1}&S. " +
                                                "Player is still NOT allowed to build (by rank).",
                                                info.GetClassyName(), world.GetClassyName() );
                                if( target != null ) {
                                    target.Message( "You were removed from the build blacklist of world {0}&S by {1}&S. " +
                                                    "You are still NOT allowed to build (by rank).",
                                                    player.GetClassyName(), world.GetClassyName() );
                                }
                            }
                            Logger.Log( "{0} removed {1} from the build blacklist of {2}", LogType.UserActivity,
                                        player.Name, info.Name, world.Name );
                            changesWereMade = true;
                            break;

                        case PermissionOverride.None:
                            player.Message( "{0}&S is now allowed to build in {1}",
                                            info.GetClassyName(), world.GetClassyName() );
                            if( target != null ) {
                                target.Message( "You can now build in world {0}&S (whitelisted by {1}&S).",
                                                world.GetClassyName(), player.GetClassyName() );
                            }
                            Logger.Log( "{0} added {1} to the build whitelist on world {2}", LogType.UserActivity,
                                        player.Name, info.Name, world.Name );
                            changesWereMade = true;
                            break;

                        case PermissionOverride.Allow:
                            player.Message( "{0}&S is already on the build whitelist of {1}",
                                            info.GetClassyName(), world.GetClassyName() );
                            break;
                    }

                    // Blacklisting individuals
                } else if( name.StartsWith( "-" ) ) {
                    PlayerInfo info;
                    if( !PlayerDB.FindPlayerInfo( name.Substring( 1 ), out info ) ) {
                        player.Message( "More than one player found matching \"{0}\"", name.Substring( 1 ) );
                        continue;
                    } else if( info == null ) {
                        player.NoPlayerMessage( name.Substring( 1 ) );
                        continue;
                    }

                    if( world.BuildSecurity.CheckDetailed( info ) == SecurityCheckResult.RankTooHigh ||
                        world.BuildSecurity.CheckDetailed( info ) == SecurityCheckResult.RankTooLow ) {
                        player.Message( "{0}&S is already barred from building in {1}&S (by rank)",
                                        info.GetClassyName(), world.GetClassyName() );
                        continue;
                    }

                    Player target = Server.FindPlayerExact( info );
                    if( target == player ) target = null; // to avoid duplicate messages

                    switch( world.BuildSecurity.Exclude( info ) ) {
                        case PermissionOverride.Deny:
                            player.Message( "{0}&S is already on build blacklist of {1}",
                                            info.GetClassyName(), world.GetClassyName() );
                            break;

                        case PermissionOverride.None:
                            player.Message( "{0}&S is now barred from building in {1}",
                                            info.GetClassyName(), world.GetClassyName() );
                            if( target != null ) {
                                target.Message( "&WYou were barred by {0}&W from building in world {1}",
                                                player.GetClassyName(), world.GetClassyName() );
                            }
                            Logger.Log( "{0} added {1} to the build blacklist on world {2}", LogType.UserActivity,
                                        player.Name, info.Name, world.Name );
                            changesWereMade = true;
                            break;

                        case PermissionOverride.Allow:
                            if( world.BuildSecurity.Check( info ) ) {
                                player.Message( "{0}&S is no longer on the build whitelist of {1}&S. " +
                                                "Player is still allowed to build (by rank).",
                                                info.GetClassyName(), world.GetClassyName() );
                                if( target != null ) {
                                    target.Message( "You were removed from the build whitelist of world {0}&S by {1}&S. " +
                                                    "You are still allowed to build (by rank).",
                                                    player.GetClassyName(), world.GetClassyName() );
                                }
                            } else {
                                player.Message( "{0}&S is no longer allowed to build in {1}",
                                                info.GetClassyName(), world.GetClassyName() );
                                if( target != null ) {
                                    target.Message( "&WYou can no longer build in world {0}&W (removed from whitelist by {1}&W).",
                                                    world.GetClassyName(), player.GetClassyName() );
                                }
                            }
                            Logger.Log( "{0} removed {1} from the build whitelist on world {2}", LogType.UserActivity,
                                        player.Name, info.Name, world.Name );
                            changesWereMade = true;
                            break;
                    }

                    // Setting minimum rank
                } else {
                    Rank rank = RankManager.FindRank( name );
                    if( rank == null ) {
                        player.NoRankMessage( name );
                    } else if( !player.Info.Rank.AllowSecurityCircumvention &&
                               world.BuildSecurity.MinRank > rank &&
                               world.BuildSecurity.MinRank > player.Info.Rank ) {
                        player.Message( "&WYou must be ranked {0}&W+ to lower build restrictions for world {1}",
                                        world.BuildSecurity.MinRank.GetClassyName(), world.GetClassyName() );
                    } else {
                        // list players who are redundantly blacklisted
                        SecurityController.PlayerListCollection lists = world.BuildSecurity.ExceptionList;
                        PlayerInfo[] noLongerExcluded = lists.Excluded.Where( excludedPlayer => excludedPlayer.Rank < rank ).ToArray();
                        if( noLongerExcluded.Length > 0 ) {
                            player.Message( "Following players no longer need to be blacklisted on world {0}&S: {1}",
                                            world.GetClassyName(),
                                            noLongerExcluded.JoinToClassyString() );
                        }

                        // list players who are redundantly whitelisted
                        PlayerInfo[] noLongerIncluded = lists.Included.Where( includedPlayer => includedPlayer.Rank >= rank ).ToArray();
                        if( noLongerIncluded.Length > 0 ) {
                            player.Message( "Following players no longer need to be whitelisted on world {0}&S: {1}",
                                            world.GetClassyName(),
                                            noLongerIncluded.JoinToClassyString() );
                        }

                        // apply changes
                        world.BuildSecurity.MinRank = rank;
                        changesWereMade = true;
                        if( world.BuildSecurity.MinRank == RankManager.LowestRank ) {
                            Server.SendToAll( "{0}&S allowed anyone to build on world {1}",
                                              player.GetClassyName(), world.GetClassyName() );
                        } else {
                            Server.SendToAll( "{0}&S allowed only {1}+&S to build in world {2}",
                                              player.GetClassyName(), world.BuildSecurity.MinRank.GetClassyName(), world.GetClassyName() );
                        }
                        Logger.Log( "{0} set build rank for world {1} to {2}+", LogType.UserActivity,
                                    player.Name, world.Name, world.BuildSecurity.MinRank.Name );
                    }
                }
            } while( (name = cmd.Next()) != null );

            if( changesWereMade ) {
                WorldManager.SaveWorldList();
            }
        }
Пример #14
0
        internal static void WorldMain( Player player, Command cmd ) {
            string worldName = cmd.Next();
            if( worldName == null ) {
                player.Message( "Main world is {0}", WorldManager.MainWorld.GetClassyName() );
                return;
            }

            World world = WorldManager.FindWorldOrPrintMatches( player, worldName );
            if( world == null ) {
                return;

            } else if( world == WorldManager.MainWorld ) {
                player.Message( "World {0}&S is already set as main.", world.GetClassyName() );

            } else if( !player.Info.Rank.AllowSecurityCircumvention && !player.CanJoin( world ) ) {
                // Prevent players from exploiting /wmain to gain access to restricted maps
                switch( world.AccessSecurity.CheckDetailed( player.Info ) ) {
                    case SecurityCheckResult.RankTooHigh:
                    case SecurityCheckResult.RankTooLow:
                        player.Message( "You are not allowed to set {0}&S as the main world (by rank).", world.GetClassyName() );
                        return;
                    case SecurityCheckResult.BlackListed:
                        player.Message( "You are not allowed to set {0}&S as the main world (blacklisted).", world.GetClassyName() );
                        return;
                }

            } else {
                if( world.AccessSecurity.HasRestrictions() ) {
                    world.AccessSecurity.Reset();
                    player.Message( "The main world cannot have access restrictions. " +
                                    "All access restrictions were removed from world {0}",
                                    world.GetClassyName() );
                }

                if( !world.SetMainWorld() ) {
                    player.Message( "Main world was not changed." );
                    return;
                }
                WorldManager.SaveWorldList();

                Server.SendToAll( "{0}&S set {1}&S to be the main world.",
                                  player.GetClassyName(), world.GetClassyName() );
                Logger.Log( "{0} set {1} to be the main world.", LogType.UserActivity,
                            player.Name, world.Name );
            }
        }
Пример #15
0
        internal static void WorldUnload( Player player, Command cmd ) {
            string worldName = cmd.Next();
            if( worldName == null ) {
                cdWorldUnload.PrintUsage( player );
                return;
            }

            World world = WorldManager.FindWorldOrPrintMatches( player, worldName );
            if( world == null ) return;

            try {
                WorldManager.RemoveWorld( world );
            } catch( WorldOpException ex ) {
                switch( ex.ErrorCode ) {
                    case WorldOpExceptionCode.CannotDoThatToMainWorld:
                        player.MessageNow( "&WWorld {0}&W is set as the main world. " +
                                           "Assign a new main world before deleting this one.",
                                           world.GetClassyName() );
                        return;
                    case WorldOpExceptionCode.WorldNotFound:
                        player.MessageNow( "&WWorld {0}&W is already unloaded.",
                                           world.GetClassyName() );
                        return;
                    default:
                        player.MessageNow( "&WUnexpected error occured while unloading world {0}&W: {1}",
                                           world.GetClassyName(), ex.GetType().Name );
                        Logger.Log( "WorldCommands.WorldUnload: Unexpected error while unloading world {0}: {1}",
                                    LogType.Error, world.Name, ex );
                        return;
                }
            }

            WorldManager.SaveWorldList();
            Server.SendToAllExcept( "{0}&S removed {1}&S from the world list.", player,
                                    player.GetClassyName(), world.GetClassyName() );
            player.Message( "Removed {0}&S from the world list. You can now delete the map file ({1}.fcm) manually.",
                            world.GetClassyName(), world.Name );
            Logger.Log( "{0} removed \"{1}\" from the world list.", LogType.UserActivity,
                        player.Name, worldName );

            Server.RequestGC();
        }
Пример #16
0
        internal static void WorldRename( Player player, Command cmd ) {
            string oldName = cmd.Next();
            string newName = cmd.Next();
            if( oldName == null || newName == null ) {
                cdWorldRename.PrintUsage( player );
                return;
            }

            World oldWorld = WorldManager.FindWorldOrPrintMatches( player, oldName );
            if( oldWorld == null ) return;
            oldName = oldWorld.Name;

            if( !cmd.IsConfirmed && File.Exists( Path.Combine( Paths.MapPath, newName + ".fcm" ) ) ) {
                player.AskForConfirmation( cmd, "Renaming this world will overwrite an existing map file \"{0}.fcm\".", newName );
                return;
            }

            try {
                WorldManager.RenameWorld( oldWorld, newName, true );
            } catch( WorldOpException ex ) {
                switch( ex.ErrorCode ) {
                    case WorldOpExceptionCode.NoChangeNeeded:
                        player.MessageNow( "Rename: World is already named \"{0}\"", oldName );
                        return;
                    case WorldOpExceptionCode.DuplicateWorldName:
                        player.MessageNow( "Rename: Another world named \"{0}\" already exists.", newName );
                        return;
                    case WorldOpExceptionCode.InvalidWorldName:
                        player.MessageNow( "Rename: Invalid world name: \"{0}\"", newName );
                        return;
                    case WorldOpExceptionCode.MapMoveError:
                        player.MessageNow( "Rename: World \"{0}\" was renamed to \"{1}\", but the map file could not be moved due to an error: {2}",
                                            oldName, newName, ex.InnerException );
                        return;
                    default:
                        player.MessageNow( "Unexpected error occured while renaming world \"{0}\"", oldName );
                        Logger.Log( "WorldCommands.Rename: Unexpected error while renaming world {0} to {1}: {2}",
                                    LogType.Error, oldWorld.Name, newName, ex );
                        return;
                }
            }

            WorldManager.SaveWorldList();
            Logger.Log( "{0} renamed the world \"{1}\" to \"{2}\".", LogType.UserActivity,
                        player.Name, oldName, newName );
            Server.SendToAll( "{0}&S renamed the world \"{1}\" to \"{2}\"",
                              player.GetClassyName(), oldName, newName );
        }
Пример #17
0
        // Parses message incoming from the player
        public void ParseMessage(string rawMessage, bool fromConsole)
        {
            if (rawMessage == null)
            {
                throw new ArgumentNullException("rawMessage");
            }

            if (partialMessage != null)
            {
                rawMessage     = partialMessage + rawMessage;
                partialMessage = null;
            }

            switch (CommandManager.GetMessageType(rawMessage))
            {
            case MessageType.Chat: {
                if (!Can(Permission.Chat))
                {
                    return;
                }

                if (Info.IsMuted)
                {
                    MutedMessage();
                    return;
                }

                if (DetectChatSpam())
                {
                    return;
                }

                if (World != null && !World.FireSentMessageEvent(this, ref rawMessage) ||
                    !Server.FireSentMessageEvent(this, ref rawMessage))
                {
                    return;
                }

                Info.LinesWritten++;

                Logger.Log("{0}: {1}", LogType.GlobalChat, Name, rawMessage);

                // Escaped slash removed AFTER logging, to avoid confusion with real commands
                if (rawMessage.StartsWith("//"))
                {
                    rawMessage = rawMessage.Substring(1);
                }

                if (rawMessage.EndsWith("//"))
                {
                    rawMessage = rawMessage.Substring(0, rawMessage.Length - 1);
                }

                if (Can(Permission.UseColorCodes) && rawMessage.Contains("%"))
                {
                    rawMessage = Color.ReplacePercentCodes(rawMessage);
                }

                Server.SendToAllExceptIgnored(this, "{0}{1}: {2}", Console,
                                              GetClassyName(), Color.White, rawMessage);
            } break;


            case MessageType.Command: {
                if (rawMessage.EndsWith("//"))
                {
                    rawMessage = rawMessage.Substring(0, rawMessage.Length - 1);
                }
                Logger.Log("{0}: {1}", LogType.UserCommand,
                           Name, rawMessage);
                Command cmd = new Command(rawMessage);
                LastCommand = cmd;
                CommandManager.ParseCommand(this, cmd, fromConsole);
            } break;


            case MessageType.RepeatCommand: {
                if (LastCommand == null)
                {
                    Message("No command to repeat.");
                }
                else
                {
                    LastCommand.Rewind();
                    Logger.Log("{0}: repeat {1}", LogType.UserCommand,
                               Name, LastCommand.Message);
                    Message("Repeat: {0}", LastCommand.Message);
                    CommandManager.ParseCommand(this, LastCommand, fromConsole);
                }
            } break;


            case MessageType.PrivateChat: {
                if (!Can(Permission.Chat))
                {
                    return;
                }

                if (Info.IsMuted)
                {
                    MutedMessage();
                    return;
                }

                if (DetectChatSpam())
                {
                    return;
                }

                if (rawMessage.EndsWith("//"))
                {
                    rawMessage = rawMessage.Substring(0, rawMessage.Length - 1);
                }

                string otherPlayerName, messageText;
                if (rawMessage[1] == ' ')
                {
                    otherPlayerName = rawMessage.Substring(2, rawMessage.IndexOf(' ', 2) - 2);
                    messageText     = rawMessage.Substring(rawMessage.IndexOf(' ', 2) + 1);
                }
                else
                {
                    otherPlayerName = rawMessage.Substring(1, rawMessage.IndexOf(' ') - 1);
                    messageText     = rawMessage.Substring(rawMessage.IndexOf(' ') + 1);
                }

                if (messageText.Contains("%") && Can(Permission.UseColorCodes))
                {
                    messageText = Color.ReplacePercentCodes(messageText);
                }

                // first, find ALL players (visible and hidden)
                Player[] allPlayers = Server.FindPlayers(otherPlayerName);

                // if there is more than 1 target player, exclude hidden players
                if (allPlayers.Length > 1)
                {
                    allPlayers = Server.FindPlayers(this, otherPlayerName);
                }

                if (allPlayers.Length == 1)
                {
                    Player target = allPlayers[0];
                    if (target.IsIgnoring(Info))
                    {
                        if (CanSee(target))
                        {
                            MessageNow("&WCannot PM {0}&W: you are ignored.", target.GetClassyName());
                        }
                    }
                    else
                    {
                        Logger.Log("{0} to {1}: {2}", LogType.PrivateChat,
                                   Name, target.Name, messageText);
                        target.Message("{0}from {1}: {2}",
                                       Color.PM, Name, messageText);
                        if (CanSee(target))
                        {
                            Message("{0}to {1}: {2}",
                                    Color.PM, target.Name, messageText);
                        }
                        else
                        {
                            NoPlayerMessage(otherPlayerName);
                        }
                    }
                }
                else if (allPlayers.Length == 0)
                {
                    NoPlayerMessage(otherPlayerName);
                }
                else
                {
                    ManyMatchesMessage("player", allPlayers);
                }
            } break;


            case MessageType.RankChat: {
                if (!Can(Permission.Chat))
                {
                    return;
                }

                if (Info.IsMuted)
                {
                    MutedMessage();
                    return;
                }

                if (DetectChatSpam())
                {
                    return;
                }

                if (rawMessage.EndsWith("//"))
                {
                    rawMessage = rawMessage.Substring(0, rawMessage.Length - 1);
                }

                string rankName = rawMessage.Substring(2, rawMessage.IndexOf(' ') - 2);
                Rank   rank     = RankManager.FindRank(rankName);
                if (rank != null)
                {
                    Logger.Log("{0} to rank {1}: {2}", LogType.RankChat,
                               Name, rank.Name, rawMessage);
                    string messageText = rawMessage.Substring(rawMessage.IndexOf(' ') + 1);
                    if (messageText.Contains("%") && Can(Permission.UseColorCodes))
                    {
                        messageText = Color.ReplacePercentCodes(messageText);
                    }

                    string formattedMessage = String.Format("{0}({1}{2}){3}{4}: {5}",
                                                            rank.Color,
                                                            (ConfigKey.RankPrefixesInChat.GetBool() ? rank.Prefix : ""),
                                                            rank.Name,
                                                            Color.PM,
                                                            Name,
                                                            messageText);
                    Server.SendToRank(this, formattedMessage, rank);
                    if (Info.Rank != rank)
                    {
                        Message(formattedMessage);
                    }
                }
                else
                {
                    Message("No rank found matching \"{0}\"", rankName);
                }
            } break;


            case MessageType.Confirmation: {
                if (CommandToConfirm != null)
                {
                    if (DateTime.UtcNow.Subtract(CommandToConfirmDate).TotalSeconds < ConfirmationTimeout)
                    {
                        CommandToConfirm.IsConfirmed = true;
                        CommandManager.ParseCommand(this, CommandToConfirm, fromConsole);
                        CommandToConfirm = null;
                    }
                    else
                    {
                        MessageNow("Confirmation timed out. Enter the command again.");
                    }
                }
                else
                {
                    MessageNow("There is no command to confirm.");
                }
            } break;


            case MessageType.PartialMessage:
                partialMessage = rawMessage.Substring(0, rawMessage.Length - 1);
                MessageNow("Partial: &F{0}", partialMessage);
                break;

            case MessageType.Invalid: {
                Message("Unknown command.");
            } break;
            }
        }
Пример #18
0
        internal static void Roll( Player player, Command cmd ) {
            if( player.Info.IsMuted ) {
                player.MutedMessage();
                return;
            }

            Random rand = new Random();
            int min = 1, max = 100, t1;
            if( cmd.NextInt( out t1 ) ) {
                int t2;
                if( cmd.NextInt( out t2 ) ) {
                    if( t2 < t1 ) {
                        min = t2;
                        max = t1;
                    } else {
                        min = t1;
                        max = t2;
                    }
                } else if( t1 >= 1 ) {
                    max = t1;
                }
            }
            int num = rand.Next( min, max + 1 );
            Server.SendToAll( "{0}{1} rolled {2} ({3}...{4})",
                              player.GetClassyName(), Color.Silver, num, min, max );
        }
Пример #19
0
 public bool Lock( Player player ) {
     if( player == null ) throw new ArgumentNullException( "player" );
     lock( lockLock ) {
         if( IsLocked ) {
             return false;
         } else {
             LockedBy = player.Name;
             LockedDate = DateTime.UtcNow;
             IsLocked = true;
             if( Map != null ) Map.ClearUpdateQueue();
             SendToAll( "&WMap was locked by {0}", player.GetClassyName() );
             Logger.Log( "World {0} was locked by {1}", LogType.UserActivity,
                         Name, player.Name );
             return true;
         }
     }
 }
Пример #20
0
        public Map AcceptPlayer(Player player, bool announce)
        {
            if (player == null)
            {
                throw new ArgumentNullException("player");
            }

            lock ( WorldLock ) {
                if (IsFull)
                {
                    return(null);
                }

                if (players.ContainsKey(player.Name.ToLower()))
                {
                    Logger.Log("This world already contains the player by name ({0}). " +
                               "Some sort of state corruption must have occured.", LogType.Error,
                               player.Name);
                    players.Remove(player.Name.ToLower());
                }

                players.Add(player.Name.ToLower(), player);

                // load the map, if it's not yet loaded
                PendingUnload = false;
                if (Map == null)
                {
                    LoadMap();
                }

                if (ConfigKey.BackupOnJoin.GetBool())
                {
                    string backupFileName = String.Format("{0}_{1:yyyy-MM-dd_HH-mm}_{2}.fcm",
                                                          Name, DateTime.Now, player.Name);   // localized
                    Map.SaveBackup(Path.Combine(Paths.MapPath, GetMapName()),
                                   Path.Combine(Paths.BackupPath, backupFileName),
                                   true);
                }

                AddPlayerForPatrol(player);

                UpdatePlayerList();

                if (announce && ConfigKey.ShowJoinedWorldMessages.GetBool())
                {
                    string message = String.Format("&SPlayer {0}&S joined {1}", player.GetClassyName(), GetClassyName());
                    foreach (Packet packet in PacketWriter.MakeWrappedMessage(">", message, false))
                    {
                        Server.SendToSeeing(packet, player);
                    }
                }

                Logger.Log("Player {0} joined world {1}.", LogType.UserActivity,
                           player.Name, Name);

                if (OnPlayerJoined != null)
                {
                    OnPlayerJoined(player, this);
                }

                if (IsLocked)
                {
                    player.Message("&WThis map is currently locked (read-only).");
                }

                if (player.IsHidden)
                {
                    player.Message("Reminder: You are still hidden.");
                }

                return(Map);
            }
        }
Пример #21
0
        bool LoginSequence() {
            byte opcode = reader.ReadByte();

            if( opcode != (byte)OpCode.Handshake ) {
                if( opcode == 2 ) {
                    // This may be someone connecting with an SMP client
                    int strLen = IPAddress.NetworkToHostOrder( reader.ReadInt16() );

                    if( strLen >= 2 && strLen <= 16 ) {
                        string smpPlayerName = Encoding.UTF8.GetString( reader.ReadBytes( strLen ) );

                        Logger.Log( "Session.LoginSequence: Player \"{0}\" tried connecting with SMP/Beta client from {1}. " +
                                    "fCraft does not support SMP/Beta.", LogType.Warning,
                                    smpPlayerName, IP );

                        // send SMP KICK packet
                        writer.Write( (byte)255 );
                        byte[] stringData = Encoding.UTF8.GetBytes( NoSmpMessage );
                        writer.Write( (short)stringData.Length );
                        writer.Write( stringData );
                        bytesSent += (1 + stringData.Length);
                        writer.Flush();

                    } else {
                        // Not SMP client (invalid player name length)
                        Logger.Log( "Session.LoginSequence: Unexpected opcode in the first packet from {0}: {1}.", LogType.Error,
                                    IP, opcode );
                        KickNow( "Unexpected handshake message - possible protocol mismatch!", LeaveReason.ProtocolViolation );
                    }
                    return false;

                } else {
                    Logger.Log( "Session.LoginSequence: Unexpected opcode in the first packet from {0}: {1}.", LogType.Error,
                                IP, opcode );
                    KickNow( "Unexpected handshake message - possible protocol mismatch!", LeaveReason.ProtocolViolation );
                    return false;
                }
            }


            // Check protocol version
            int clientProtocolVersion = reader.ReadByte();
            if( clientProtocolVersion != Config.ProtocolVersion ) {
                Logger.Log( "Session.LoginSequence: Wrong protocol version: {0}.", LogType.Error,
                            clientProtocolVersion );
                KickNow( "Incompatible protocol version!", LeaveReason.ProtocolViolation );
                return false;
            }

            string playerName = ReadString();
            string verificationCode = ReadString();
            reader.ReadByte(); // unused
            bytesReceived += 131;


            // Check name for nonstandard characters
            if( !Player.IsValidName( playerName ) ) {
                Logger.Log( "Session.LoginSequence: Unacceptible player name: {0} ({1})", LogType.SuspiciousActivity,
                            playerName, IP );
                KickNow( "Invalid characters in player name!", LeaveReason.ProtocolViolation );
                return false;
            }


            // Verify name
            Player = new Player( null, playerName, this, WorldManager.MainWorld.Map.Spawn );
            bool showVerifyNamesWarning = false;
            if( !Server.VerifyName( Player.Name, verificationCode, Server.Salt ) ) {
                NameVerificationMode nameVerificationMode = ConfigKey.VerifyNames.GetEnum<NameVerificationMode>();

                string standardMessage = String.Format( "Session.LoginSequence: Could not verify player name for {0} ({1}).",
                                                        Player.Name, IP );
                if( IP.Equals( IPAddress.Loopback ) && nameVerificationMode == NameVerificationMode.Always ) {
                    Logger.Log( "{0} Player was identified as connecting from localhost and allowed in.", LogType.SuspiciousActivity,
                                standardMessage );

                } else if( IP.IsLAN() && ConfigKey.AllowUnverifiedLAN.GetBool() ) {
                    Logger.Log( "{0} Player was identified as connecting from LAN and allowed in.", LogType.SuspiciousActivity,
                                standardMessage );
                } else if( Player.Info.TimesVisited > 1 && Player.Info.LastIP.Equals( IP ) ) {
                    switch( nameVerificationMode ) {
                        case NameVerificationMode.Always:
                            Player.Info.ProcessFailedLogin( this );
                            Logger.Log( "{0} IP matched previous records for that name. " +
                                        "Player was kicked anyway because VerifyNames is set to Always.", LogType.SuspiciousActivity,
                                        standardMessage );
                            KickNow( "Could not verify player name!", LeaveReason.UnverifiedName );
                            return false;
                        case NameVerificationMode.Balanced:
                        case NameVerificationMode.Never:
                            Logger.Log( "{0} IP matched previous records for that name. Player was allowed in.", LogType.SuspiciousActivity,
                                        standardMessage );
                            break;
                    }

                } else {
                    switch( nameVerificationMode ) {
                        case NameVerificationMode.Always:
                        case NameVerificationMode.Balanced:
                            Player.Info.ProcessFailedLogin( this );
                            Logger.Log( "{0} IP did not match. Player was kicked.", LogType.SuspiciousActivity,
                                        standardMessage );
                            KickNow( "Could not verify player name!", LeaveReason.UnverifiedName );
                            return false;
                        case NameVerificationMode.Never:
                            Logger.Log( "{0} IP did not match. " +
                                        "Player was allowed in anyway because VerifyNames is set to Never.", LogType.SuspiciousActivity,
                                        standardMessage );
                            Player.Message( "&WYour name could not be verified." );
                            showVerifyNamesWarning = true;
                            break;
                    }
                }
            }


            // Check if player is banned
            if( Player.Info.Banned ) {
                Player.Info.ProcessFailedLogin( this );
                Logger.Log( "Banned player {0} tried to log in from {1}", LogType.SuspiciousActivity,
                            Player.Name, IP );
                if( ConfigKey.ShowBannedConnectionMessages.GetBool() ) {
                    Server.SendToAllWhoCan( "&SBanned player {0}&S tried to log in from {1}", null, Permission.ViewPlayerIPs,
                                            Player.GetClassyName(), IP );
                    Server.SendToAllWhoCant( "&SBanned player {0}&S tried to log in.", null, Permission.ViewPlayerIPs,
                                            Player.GetClassyName() );
                }
                string bannedMessage = String.Format( "Banned {0} ago by {1}: {2}",
                                                      Player.Info.TimeSinceBan.ToMiniString(),
                                                      Player.Info.BannedBy,
                                                      Player.Info.BanReason );
                KickNow( bannedMessage, LeaveReason.LoginFailed );
                return false;
            }


            // Check if player's IP is banned
            IPBanInfo ipBanInfo = IPBanList.Get( IP );
            if( ipBanInfo != null ) {
                Player.Info.ProcessFailedLogin( this );
                ipBanInfo.ProcessAttempt( Player );
                if( ConfigKey.ShowBannedConnectionMessages.GetBool() ) {
                    Server.SendToAll( "{0}&S tried to log in from a banned IP.", Player.GetClassyName() );
                }
                Logger.Log( "{0} tried to log in from a banned IP.", LogType.SuspiciousActivity,
                            Player.Name );
                string bannedMessage = String.Format( "IP-banned {0} ago by {1}: {2}",
                                                      DateTime.UtcNow.Subtract( ipBanInfo.BanDate ).ToMiniString(),
                                                      ipBanInfo.BannedBy,
                                                      ipBanInfo.BanReason );
                KickNow( bannedMessage, LeaveReason.LoginFailed );
                return false;
            }


            // Check if max number of connections is reached for IP
            if( !Server.RegisterSessionAndCheckConnectionCount( this ) ) {
                Player.Info.ProcessFailedLogin( this );
                Logger.Log( "Session.LoginSequence: Denied player {0}: maximum number of connections was reached for {1}", LogType.SuspiciousActivity,
                            playerName, IP );
                KickNow( String.Format( "Max connection count reached for {0}", IP ), LeaveReason.LoginFailed );
                return false;
            }


            // Check if player is paid (if required)
            if( ConfigKey.PaidPlayersOnly.GetBool() ) {
                SendNow( PacketWriter.MakeHandshake( Player,
                                                     ConfigKey.ServerName.GetString(),
                                                     "Please wait; Checking paid status..." ) );
                writer.Flush();

                if( !Player.CheckPaidStatus( Player.Name ) ) {
                    Logger.Log( "Player {0} was kicked because their account is not paid, and PaidOnly setting is enabled.", LogType.SystemActivity,
                                Player.Name );
                    KickNow( "Paid players allowed only.", LeaveReason.LoginFailed );
                    return false;
                }
            }


            // Any additional security checks should be done right here
            if( Server.RaisePlayerConnectingEvent( Player ) ) return false;


            // ----==== beyond this point, player is considered connecting (allowed to join) ====----

            // Register player for future block updates
            if( !Server.RegisterPlayerAndCheckIfFull( this ) ) {
                Logger.Log( "Player {0} was kicked because server is full.", LogType.SystemActivity,
                            Player.Name );
                string kickMessage = String.Format( "Sorry, server is full ({0}/{1})",
                                        Server.PlayerList.Length, ConfigKey.MaxPlayers.GetInt() );
                KickNow( kickMessage, LeaveReason.ServerFull );
                return false;
            }
            Player.Info.ProcessLogin( Player );


            // ----==== Beyond this point, player is considered connected (authenticated and registered) ====----


            World startingWorld = Server.RaisePlayerConnectedEvent( Player, WorldManager.MainWorld );

            // Send server information
            SendNow( PacketWriter.MakeHandshake( Player, ConfigKey.ServerName.GetString(), ConfigKey.MOTD.GetString() ) );

            // AutoRank
            if( ConfigKey.AutoRankEnabled.GetBool() ) {
                Rank newRank = AutoRankManager.Check( Player.Info );
                if( newRank != null ) {
                    ModerationCommands.DoChangeRank( Player.Console, Player.Info, newRank, "~AutoRank", false, true );
                }
            }

            bool firstTime = (Player.Info.TimesVisited == 1);
            if( !JoinWorldNow( startingWorld, true, true ) ) {
                Logger.Log( "Failed to load main world ({0}) for connecting player {1} (from {2})", LogType.Error,
                            startingWorld.Name, Player.Name, IP );
                KickNow( "Unable to join the main world.", LeaveReason.WorldFull );
                return false;
            }


            // ==== Beyond this point, player is considered ready (has a world) ====


            if( showVerifyNamesWarning ) {
                Server.SendToAllExcept( "&WName and IP of {0}&W are unverified!", Player,
                                        Player.GetClassyName() );
            }

            // Check if other banned players logged in from this IP
            PlayerInfo[] bannedPlayerNames = PlayerDB.FindPlayers( IP, 25 ).Where( playerFromSameIP => playerFromSameIP.Banned ).ToArray();
            if( bannedPlayerNames.Length > 0 ) {
                string logString = String.Format( "&WPlayer {0}&W logged in from an IP previously used by banned players: {1}",
                                                  Player.GetClassyName(),
                                                  bannedPlayerNames.JoinToClassyString() );
                Server.SendToAll( logString );
                Logger.Log( logString, LogType.SuspiciousActivity );
            }

            // Announce join
            if( ConfigKey.ShowConnectionMessages.GetBool() ) {
                Server.SendToAllExcept( Server.MakePlayerConnectedMessage( Player, firstTime, Player.World ), Player );
            }

            // check if player is still muted
            if( Player.Info.MutedUntil > DateTime.UtcNow ) {
                int secondsLeft = (int)Player.Info.MutedUntil.Subtract( DateTime.UtcNow ).TotalSeconds;
                Player.Message( "&WYou were previously muted by {0}, {1} seconds left.",
                                Player.Info.MutedBy, secondsLeft );
                Server.SendToAllExcept( "&WPlayer {0}&W was previously muted by {1}&W, {2} seconds left.", Player,
                                        Player.GetClassyName(), Player.Info.MutedBy, secondsLeft );
            }

            // check if player is still frozen
            if( Player.Info.IsFrozen ) {
                if( Player.Info.FrozenOn != DateTime.MinValue ) {
                    Player.Message( "&WYou were previously frozen {0} ago by {1}",
                                    Player.Info.TimeSinceFrozen.ToMiniString(),
                                    Player.Info.FrozenBy );
                    Server.SendToAllExcept( "&WPlayer {0}&W was previously frozen {1} ago by {2}.", Player,
                                            Player.GetClassyName(),
                                            Player.Info.TimeSinceFrozen.ToMiniString(),
                                            Player.Info.FrozenBy );
                } else {
                    Player.Message( "&WYou were previously frozen by {0}",
                                    Player.Info.FrozenBy );
                    Server.SendToAllExcept( "&WPlayer {0}&W was previously frozen by {1}.", Player,
                                            Player.GetClassyName(),
                                            Player.Info.FrozenBy );
                }
            }

            // Welcome message
            if( File.Exists( Paths.GreetingFileName ) ) {
                string[] greetingText = File.ReadAllLines( Paths.GreetingFileName );
                foreach( string greetingLine in greetingText ) {
                    StringBuilder sb = new StringBuilder( greetingLine );
                    sb.Replace( "{SERVER_NAME}", ConfigKey.ServerName.GetString() );
                    sb.Replace( "{RANK}", Player.Info.Rank.GetClassyName() );
                    sb.Replace( "{PLAYER_NAME}", Player.GetClassyName() );
                    sb.Replace( "{TIME}", DateTime.Now.ToShortTimeString() ); // localized
                    sb.Replace( "{WORLD}", Player.World.GetClassyName() );
                    sb.Replace( "{PLAYERS}", Server.CountVisiblePlayers( Player ).ToString() );
                    sb.Replace( "{WORLDS}", WorldManager.WorldList.Length.ToString() );
                    sb.Replace( "{MOTD}", ConfigKey.MOTD.GetString() );
                    Player.Message( sb.ToString() );
                }
            } else {
                if( firstTime ) {
                    Player.Message( "Welcome to {0}", ConfigKey.ServerName.GetString() );
                } else {
                    Player.Message( "Welcome back to {0}", ConfigKey.ServerName.GetString() );
                }

                Player.Message( "Your rank is {0}&S. Type &H/help&S for help.",
                                Player.Info.Rank.GetClassyName() );
            }

            // A reminder for first-time users
            if( PlayerDB.CountTotalPlayers() == 1 && Player.Info.Rank != RankManager.HighestRank ) {
                Player.Message( "Type &H/rank {0} {1}&S in console to promote yourself",
                                Player.Name, RankManager.HighestRank.Name );
            }

            Server.RaisePlayerReadyEvent( Player );
            IsReady = true;

            return true;
        }
Пример #22
0
 public bool Unlock( Player player ) {
     if( player == null ) throw new ArgumentNullException( "player" );
     lock( lockLock ) {
         if( IsLocked ) {
             UnlockedBy = player.Name;
             UnlockedDate = DateTime.UtcNow;
             IsLocked = false;
             SendToAll( "&WMap was unlocked by {0}", player.GetClassyName() );
             Logger.Log( "World \"{0}\" was unlocked by {1}", LogType.UserActivity,
                         Name, player.Name );
             return true;
         } else {
             return false;
         }
     }
 }
Пример #23
0
        public Map AcceptPlayer( Player player, bool announce ) {
            if( player == null ) throw new ArgumentNullException( "player" );

            lock( WorldLock ) {

                if( IsFull ) {
                    return null;
                }

                if( players.ContainsKey( player.Name.ToLower() ) ) {
                    Logger.Log( "This world already contains the player by name ({0}). " +
                                "Some sort of state corruption must have occured.", LogType.Error,
                                player.Name );
                    players.Remove( player.Name.ToLower() );
                }

                players.Add( player.Name.ToLower(), player );

                // load the map, if it's not yet loaded
                PendingUnload = false;
                if( Map == null ) {
                    LoadMap();
                }

                if( ConfigKey.BackupOnJoin.GetBool() ) {
                    string backupFileName = String.Format( "{0}_{1:yyyy-MM-dd_HH-mm}_{2}.fcm",
                                                           Name, DateTime.Now, player.Name ); // localized
                    Map.SaveBackup( Path.Combine( Paths.MapPath, GetMapName() ),
                                    Path.Combine( Paths.BackupPath, backupFileName ),
                                    true );
                }

                AddPlayerForPatrol( player );

                UpdatePlayerList();

                if( announce && ConfigKey.ShowJoinedWorldMessages.GetBool() ) {
                    string message = String.Format( "&SPlayer {0}&S joined {1}", player.GetClassyName(), GetClassyName() );
                    foreach( Packet packet in PacketWriter.MakeWrappedMessage( ">", message, false ) ) {
                        Server.SendToSeeing( packet, player );
                    }
                }

                Logger.Log( "Player {0} joined world {1}.", LogType.UserActivity,
                            player.Name, Name );

                if( OnPlayerJoined != null ) OnPlayerJoined( player, this );

                if( IsLocked ) {
                    player.Message( "&WThis map is currently locked (read-only)." );
                }

                if( player.IsHidden ) {
                    player.Message( "Reminder: You are still hidden." );
                }

                return Map;
            }
        }
Пример #24
0
        static void Shutdown( Player player, Command cmd ) {
            int delay;
            if( !cmd.NextInt( out delay ) ) {
                delay = 5;
                cmd.Rewind();
            }
            string reason = cmd.NextAll();

            if( reason.Equals( "abort", StringComparison.OrdinalIgnoreCase ) ) {
                if( Server.CancelShutdown() ) {
                    Logger.Log( "Shutdown aborted by {0}.", LogType.UserActivity, player.Name );
                    Server.SendToAll( "&WShutdown aborted by {0}", player.GetClassyName() );
                } else {
                    player.MessageNow( "Cannot abort shutdown - too late." );
                }
                return;
            }

            Server.SendToAll( "&WServer shutting down in {0} seconds.", delay );

            if( String.IsNullOrEmpty( reason ) ) {
                Logger.Log( "{0} shut down the server ({1} second delay).", LogType.UserActivity,
                            player.Name, delay );
                ShutdownParams sp = new ShutdownParams( ShutdownReason.ShuttingDown, delay, true, false );
                Server.Shutdown( sp, false );
            } else {
                Server.SendToAll( "&WShutdown reason: {0}", reason );
                Logger.Log( "{0} shut down the server ({1} second delay). Reason: {2}", LogType.UserActivity,
                            player.Name, delay, reason );
                ShutdownParams sp = new ShutdownParams( ShutdownReason.ShuttingDown, delay, true, false, reason, player );
                Server.Shutdown( sp, false );
            }
        }