示例#1
0
        // Remove player from the list, and notify remaining players
        public static void UnregisterPlayer( Player player )
        {
            lock( playerListLock ) {
                if( players.ContainsKey( player.id ) ) {
                    SendToAll( PacketWriter.MakeRemoveEntity( player.id ) );
                    SendToAll( Color.Sys + player.GetLogName() + " left the server." );
                    Logger.Log( "{0} left the server.", LogType.UserActivity, player.name );

                    // better safe than sorry: go through ALL worlds looking for leftover players
                    lock( worldListLock ) {
                        foreach( World world in worlds.Values ) {
                            world.ReleasePlayer( player );
                        }
                    }

                    players.Remove( player.id );
                    UpdatePlayerList();
                    PlayerDB.ProcessLogout( player );
                    PlayerDB.Save();
                } else {
                    Logger.Log( "World.UnregisterPlayer: Trying to unregister a non-existent (unknown id) player.", LogType.Warning );
                }
            }
        }
示例#2
0
 internal static void SetSpawn( Player player, Command cmd )
 {
     if( player.Can( Permissions.SetSpawn ) ) {
         player.world.map.spawn = player.pos;
         player.world.map.changesSinceSave++;
         player.Send( PacketWriter.MakeTeleport( 255, player.world.map.spawn ), true );
         player.Message( "New spawn point saved." );
         Logger.Log( "{0} changed the spawned point.", LogType.UserActivity, player.GetLogName() );
     } else {
         player.NoAccessMessage( Permissions.SetSpawn );
     }
 }
示例#3
0
        // Change player class
        internal static void ChangeClass( Player player, Command cmd )
        {
            string name = cmd.Next();
            string newClassName = cmd.Next();
            if( name == null || newClassName == null ) {
                player.Message( "Usage: " + Color.Help + "/user PlayerName ClassName" );
                player.Message( "To see a list of classes and permissions, use " + Color.Help + "/class" );
                return;
            }

            Player target = Server.FindPlayer( name );
            if( target == null ) {
                player.NoPlayerMessage( name );
                return;
            }

            PlayerClass newClass = ClassList.FindClass( newClassName );
            if( newClass == null ) {
                player.Message( "Unrecognized player class: " + newClassName );
                return;
            }

            if( target.info.playerClass == newClass ) {
                player.Message( target.GetLogName() + " is already " + newClass.color + newClass.name );
                return;
            }

            bool promote = target.info.playerClass.rank < newClass.rank;

            if( (promote && !player.Can( Permissions.Promote )) ) {
                player.NoAccessMessage( Permissions.Promote );
                return;
            } else if( !promote && !player.Can( Permissions.Demote ) ) {
                player.NoAccessMessage( Permissions.Demote );
                return;
            }

            if( promote && !player.info.playerClass.CanPromote( newClass ) ) {
                player.Message( "You can only promote players up to " + player.info.playerClass.maxPromote.color + player.info.playerClass.maxPromote.name );
                player.Message( target.GetLogName() + " is ranked " + target.info.playerClass.name + "." );
                return;
            } else if( !promote && !player.info.playerClass.CanDemote( target.info.playerClass ) ) {
                player.Message( "You can only demote players that are " + player.info.playerClass.maxDemote.color + player.info.playerClass.maxDemote.name + Color.Sys + " or lower." );
                player.Message( target.GetLogName() + " is ranked " + target.info.playerClass.name + "." );
                return;
            }

            if( promote && target.info.playerClass.rank < newClass.rank ||
                target.info.playerClass.rank > newClass.rank ) {
                PlayerClass oldClass = target.info.playerClass;
                if( !Server.FirePlayerClassChange( target, player, oldClass, newClass ) ) return;

                Logger.Log( "{0} changed the class of {1} from {2} to {3}.", LogType.UserActivity,
                            player.GetLogName(), target.GetLogName(), target.info.playerClass.name, newClass.name );
                target.info.playerClass = newClass;
                target.info.classChangeDate = DateTime.Now;
                target.info.classChangedBy = player.name;

                Server.FirePlayerListChangedEvent();

                target.Send( PacketWriter.MakeSetPermission( target ) );

                target.mode = BlockPlacementMode.Normal;
                if( promote ) {
                    player.Message( "You promoted " + target.name + " to " + newClass.color + newClass.name );
                    target.Message( "You have been promoted to " + newClass.color + newClass.name + Color.Sys + " by " + player.nick );
                } else {
                    player.Message( "You demoted " + target.name + " to " + newClass.color + newClass.name );
                    target.Message( "You have been demoted to " + newClass.color + newClass.name + Color.Sys + " by " + player.nick );
                }
                if( Config.GetBool( ConfigKey.ClassPrefixesInList ) || Config.GetBool( ConfigKey.ClassColorsInChat ) ) {
                    target.world.UpdatePlayer( target );
                }
            } else {
                if( promote ) {
                    player.Message( target.GetLogName() + " is already same or lower rank than " + newClass.name );
                } else {
                    player.Message( target.GetLogName() + " is already same or higher rank than " + newClass.name );
                }
            }
        }
示例#4
0
        internal static void DoIPBan( Player player, IPAddress address, string reason, string playerName, bool banAll, bool unban )
        {
            Player other;
            if( unban ) {
                if( IPBanList.Remove( address ) ) {
                    player.Message( address.ToString() + " has been removed from the IP ban list." );
                } else {
                    player.Message( address.ToString() + " is not currently banned." );
                }
                if( banAll ) {
                    foreach( PlayerInfo otherInfo in PlayerDB.FindPlayersByIP( address ) ) {
                        if( otherInfo.ProcessUnBan( player.name, reason + "~UnBanAll" ) ) {
                            player.Message( otherInfo.name + " matched the IP and was also unbanned." );
                        }
                    }
                }

            } else {
                if( IPBanList.Add( new IPBanInfo( address, playerName, player.name, reason ) ) ) {
                    player.Message( address.ToString() + " has been added to the IP ban list." );

                } else {
                    player.Message( address.ToString() + " is already banned." );
                }
                foreach( PlayerInfo otherInfo in PlayerDB.FindPlayersByIP( address ) ) {
                    if( banAll && otherInfo.ProcessBan( player.name, reason + "~BanAll" ) ) {
                        player.Message( otherInfo.name + " matched the IP and was also banned." );
                    }
                    other = player.world.FindPlayerExact( otherInfo.name );
                    if( other != null ) {
                        other.session.Kick( "Your IP was just banned by " + player.GetLogName() );
                    }
                }
            }
        }
示例#5
0
        // Kick a player. One argument (mandatory) - player name (can be partial).
        internal static void Kick( Player player, Command cmd )
        {
            if( !player.Can( Permissions.Kick ) ) {
                player.NoAccessMessage( Permissions.Kick );
                return;
            }

            string name = cmd.Next();
            if( name != null ) {
                string msg = cmd.NextAll();
                Player offender = Server.FindPlayer( name );
                if( offender != null ) {
                    if( !player.info.playerClass.CanKick( offender.info.playerClass ) ) {
                        player.Message( "You can only kick players ranked " + player.info.playerClass.maxKick.color + player.info.playerClass.maxKick.name + Color.Sys + " or lower." );
                        player.Message( offender.GetLogName() + " is ranked " + offender.info.playerClass.name + "." );
                    } else {
                        Server.SendToAll( Color.Red + offender.nick + " was kicked by " + player.nick );
                        if( msg != null && msg != "" ) {
                            Logger.Log( "{0} was kicked by {1}. Memo: {2}", LogType.UserActivity, offender.GetLogName(), player.GetLogName(), msg );
                            offender.session.Kick( "Kicked by " + player.GetLogName() + ": " + msg );
                        } else {
                            Logger.Log( "{0} was kicked by {1}", LogType.UserActivity, offender.GetLogName(), player.GetLogName() );
                            offender.session.Kick( "You have been kicked by " + player.GetLogName() );
                        }
                    }
                } else {
                    player.NoPlayerMessage( name );
                }
            } else {
                player.Message( "Usage: " + Color.Help + "/kick PlayerName [Message]" +
                                   Color.Sys + " or " + Color.Help + "/k PlayerName [Message]" );
            }
        }
示例#6
0
        internal static void WorldRename( Player player, Command cmd )
        {
            if( !player.Can( Permissions.ManageWorlds ) ) {
                player.NoAccessMessage( Permissions.ManageWorlds );
                return;
            }

            string oldName = cmd.Next();
            string newName = cmd.Next();
            if( oldName == null || newName == null ) {
                player.Message( "Syntax: " + Color.Help + "/wrename OldName NewName" );
                return;
            }

            lock( Server.worldListLock ) {
                World oldWorld = Server.FindWorld( oldName );
                World newWorld = Server.FindWorld( newName );

                if( oldWorld == null ) {
                    player.Message( "No world found with the specified name: " + oldName );
                } else if( newWorld != null ) {
                    player.Message( "A world with the specified name already exists: " + newName );
                } else {
                    oldName = oldWorld.name;
                    Server.RenameWorld( oldName, newName );
                    File.Move( oldName + ".fcm", newName + ".fcm" );
                    Server.SaveWorldList();
                    Server.SendToAll( Color.Sys + player.nick + " renamed the world \"" + oldName + "\" to \"" + newName + "\"." );
                    Logger.Log( player.GetLogName() + " renamed the world \"" + oldName + "\" to \"" + newName + "\".", LogType.UserActivity );
                }
            }
        }
示例#7
0
        internal static void DoBan( Player player, Command cmd, bool banIP, bool banAll, bool unban )
        {
            if( !player.Can( Permissions.Ban ) ) {
                player.NoAccessMessage( Permissions.Ban );
                return;
            } else if( banIP && !player.Can( Permissions.BanIP ) ) {
                player.NoAccessMessage( Permissions.BanIP );
                return;
            } else if( banAll && !player.Can( Permissions.BanAll ) ) {
                player.NoAccessMessage( Permissions.BanAll );
                return;
            }

            string arg = cmd.Next();
            string reason = cmd.NextAll();
            IPAddress address;
            Player offender = Server.FindPlayer( arg );
            PlayerInfo info = PlayerDB.FindPlayerInfoExact( arg );

            // ban by IP address
            if( banIP && IPAddress.TryParse( arg, out address ) ) {
                DoIPBan( player, address, reason, null, banAll, unban );

                // ban online players
            } else if( !unban && offender != null ) {

                // check permissions
                if( !player.info.playerClass.CanBan( offender.info.playerClass ) ) {
                    player.Message( "You can only ban players ranked " + player.info.playerClass.maxBan.color + player.info.playerClass.maxBan.name + Color.Sys + " or lower." );
                    player.Message( offender.GetLogName() + " is ranked " + offender.info.playerClass.name + "." );
                } else {
                    address = offender.info.lastIP;
                    if( banIP ) DoIPBan( player, address, reason, offender.name, banAll, unban );
                    if( offender.info.ProcessBan( player.name, reason ) ) {
                        Logger.Log( "{0} was banned by {1}.", LogType.UserActivity, offender.info.name, player.GetLogName() );
                        Server.SendToAll( Color.Red + offender.name + " was banned by " + player.nick, offender );
                        offender.session.Kick( "You were just banned by " + player.GetLogName() );
                    } else {
                        player.Message( offender.name + " is already banned." );
                    }
                }

                // ban offline players
            } else if( info != null ) {
                if( !player.info.playerClass.CanBan( info.playerClass ) ) {
                    PlayerClass maxRank = player.info.playerClass.maxBan;
                    if( maxRank == null ) {
                        player.Message( "You can only ban players ranked " + player.info.playerClass.color + player.info.playerClass.name + Color.Sys + " or lower." );
                    } else {
                        player.Message( "You can only ban players ranked " + maxRank.color + maxRank.name + Color.Sys + " or lower." );
                    }
                    player.Message( info.name + " is ranked " + info.playerClass.name + "." );
                } else {
                    address = info.lastIP;
                    if( banIP ) DoIPBan( player, address, reason, info.name, banAll, unban );
                    if( unban ) {
                        if( info.ProcessUnBan( player.name, reason ) ) {
                            Logger.Log( "{0} (offline) was unbanned by {1}", LogType.UserActivity, info.name, player.GetLogName() );
                            Server.SendToAll( Color.Red + info.name + " (offline) was unbanned by " + player.nick );
                        } else {
                            player.Message( info.name + " (offline) is not currenty banned." );
                        }
                    } else {
                        if( info.ProcessBan( player.name, reason ) ) {
                            Logger.Log( "{0} (offline) was banned by {1}.", LogType.UserActivity, info.name, player.GetLogName() );
                            Server.SendToAll( Color.Red + info.name + " (offline) was banned by " + player.nick );
                        } else {
                            player.Message( info.name + " (offline) is already banned." );
                        }
                    }
                }
            } else {
                player.NoPlayerMessage( arg );
                player.Message( "Use the FULL player name for ban/unban commands." );
            }
        }
示例#8
0
        internal static void WorldLoad( Player player, Command cmd )
        {
            if( !player.Can( Permissions.ManageWorlds ) ) {
                player.NoAccessMessage( Permissions.ManageWorlds );
                return;
            }

            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
                player.Message( "See " + Color.Help + "/help wload" + Color.Sys + " for usage syntax." );
                return;
            }

            Logger.Log( "Player {0} is attempting to load map \"{1}\"...", LogType.UserActivity,
                        player.GetLogName(),
                        fileName );
            player.Message( "Attempting to load " + fileName + "..." );

            Map map = Map.Load( player.world, fileName );
            if( map == null ) {
                player.Message( "Could not load specified file." );
                return;
            }

            if( worldName == null ) {
                // Loading to current world
                player.world.ChangeMap( map );
                player.world.SendToAll( Color.Sys + player.nick + " loaded a new map for the world \"" + player.world.name + "\".", player );
                player.Message( "New map for the world \"" + player.world.name + "\" has been loaded." );

                Logger.Log( player.GetLogName() + " loaded new map for " + player.world.name + " from " + fileName, LogType.UserActivity );

            } else {
                // Loading to some other (or new) world
                if( !Player.IsValidName( worldName ) ) {
                    player.Message( "Invalid world name: \"" + worldName + "\"." );
                    return;
                }

                lock( Server.worldListLock ) {
                    World world = Server.FindWorld( worldName );
                    if( world != null ) {
                        // Replacing existing world's map
                        world.ChangeMap( map );
                        world.SendToAll( Color.Sys + player.nick + " loaded a new map for the world \"" + world.name + "\".", player );
                        player.Message( "New map for the world \"" + world.name + "\" has been loaded." );
                        Logger.Log( player.GetLogName() + " loaded new map for world \"" + world.name + "\" from " + fileName, LogType.UserActivity );

                    } else {
                        // Adding a new world
                        if( Server.AddWorld( worldName, map, false ) != null ) {
                            Server.SendToAll( Color.Sys + player.nick + " created a new world named \"" + worldName + "\"." );
                            Logger.Log( player.GetLogName() + " created a new world named \"" + worldName + "\".", LogType.UserActivity );
                            Server.SaveWorldList();
                        } else {
                            player.Message( "Error occured while trying to create a new world." );
                        }
                    }
                }
            }

            GC.Collect( GC.MaxGeneration, GCCollectionMode.Optimized );
        }
示例#9
0
        internal static void WorldMain( Player player, Command cmd )
        {
            string worldName = cmd.Next();
            if( worldName == null ) {
                player.Message( "Usage: " + Color.Help + "/wmain WorldName" );
                return;
            }
            World world = Server.FindWorld( worldName );
            if( world == null ) {
                player.Message( "No world \"" + worldName + "\" found." );
            } else if( world == Server.mainWorld ) {
                player.Message( "World \"" + world.name + "\" is already set as main." );
            } else if( player.Can( Permissions.ManageWorlds ) ) {
                if( world.classAccess != ClassList.lowestClass ) {
                    world.classAccess = ClassList.lowestClass;
                    player.Message( "The main world cannot have access restrictions." );
                    player.Message( "Access restrictions were removed from world \"" + world.name + "\"" );
                }
                world.neverUnload = false;
                world.LoadMap();
                Server.mainWorld.neverUnload = true;
                Server.mainWorld = world;
                Server.SaveWorldList();

                Server.SendToAll( Color.Sys + player.nick + " set \"" + world.name + "\" to be the main world." );
                Logger.Log( player.GetLogName() + " set \"" + world.name + "\" to be the main world.", LogType.UserActivity );
            } else {
                player.NoAccessMessage( Permissions.ManageWorlds );
            }
        }
示例#10
0
        internal static void WorldBuild( Player player, Command cmd )
        {
            string worldName = cmd.Next();
            string className = cmd.Next();

            if( worldName == null ) {
                if( player.world != null ) {
                    if( player.world.classBuild == ClassList.lowestClass ) {
                        player.Message( "This world (" + player.world.name + ") can be modified by anyone." );
                    } else {
                        player.Message( "This world (" + player.world.name + ") can only be modified by " + player.world.classBuild.color + player.world.classBuild.name + "+" );
                    }
                } else {
                    player.Message( "When calling /waccess from console, you must specify the world name." );
                }
                return;
            }

            World world = Server.FindWorld( worldName );
            if( world == null ) {
                player.Message( "No world \"" + worldName + "\" found." );
            } else if( className == null ) {
                if( world.classBuild == ClassList.lowestClass ) {
                    player.Message( "World \"" + world.name + "\" can be modified by anyone." );
                } else {
                    player.Message( "World \"" + world.name + "\" can be only modified by " + world.classBuild.color + world.classBuild.name + "+" );
                }
            } else if( player.Can( Permissions.ManageWorlds ) ) {
                PlayerClass playerClass = ClassList.FindClass( className );
                if( playerClass == null ) {
                    player.Message( "No class \"" + className + "\" found." );
                } else{
                    world.classBuild = playerClass;
                    Server.SaveWorldList();
                    if( world.classBuild == ClassList.lowestClass ) {
                        Server.SendToAll( Color.Sys + player.nick + " made the world \"" + world.name + "\" modifiable by anyone." );
                    } else {
                        Server.SendToAll( Color.Sys + player.nick + " made the world \"" + world.name + "\" modifiable only by " + world.classBuild.color + world.classBuild.name + "+" );
                    }
                    Logger.Log( player.GetLogName() + " made the world \"" + world.name + "\" modifiable by " + world.classBuild.name + "+", LogType.UserActivity );
                }
            } else {
                player.NoAccessMessage( Permissions.ManageWorlds );
            }
        }
示例#11
0
        public void AcceptPlayer( Player player )
        {
            lock( playerListLock ) {
                lock( mapLock ) {
                    isReadyForUnload = false;
                    if( map == null ) {
                        LoadMap();
                    }

                    if( Config.GetBool( ConfigKey.BackupOnJoin ) ) {
                        map.SaveBackup( GetMapName(), String.Format( "backups/{0}_{1:yyyy-MM-dd HH-mm}_{2}.fcm", name, DateTime.Now, player.name ) );
                    }
                }

                players.Add( player.id, player );
                UpdatePlayerList();

                // Reveal newcommer to existing players
                if( !player.isHidden ) {
                    SendToAll( PacketWriter.MakeAddEntity( player, player.pos ), player );
                    Server.SendToAll( String.Format( "{0}Player {1} joined \"{2}\".", Color.Sys, player.GetLogName(), name ), player );
                }
            }

            Logger.Log( "Player {0} joined \"{1}\".", LogType.UserActivity, player.GetLogName(), name );

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

            if( isLocked ) {
                player.Message( Color.Red, "This map is currently locked." );
            }
        }
示例#12
0
        internal static void DoReplace(Player player, Position[] marks, object tag)
        {
            player.drawingInProgress = true;

            Block rfromBlock;
            Block rtoBlock;
            if (tag == null || player.bl2 == null)
            {
                player.Message("ERROR: variable 'tag' or 'bl2' unspecified!");
                return;
            }
            else
            {
                rfromBlock = (Block)tag;
                rtoBlock = (Block)player.bl2;
            }

            // find start/end coordinates
            int sx = Math.Min(marks[0].x, marks[1].x);
            int ex = Math.Max(marks[0].x, marks[1].x);
            int sy = Math.Min(marks[0].y, marks[1].y);
            int ey = Math.Max(marks[0].y, marks[1].y);
            int sh = Math.Min(marks[0].h, marks[1].h);
            int eh = Math.Max(marks[0].h, marks[1].h);

            int blocks;
            byte block;
            int step = 8;

            blocks = (ex - sx + 1) * (ey - sy + 1) * (eh - sh + 1);
            if (blocks > 2000000)
            {
                player.Message("NOTE: This draw command is too massive to undo.");
            }

            if (rfromBlock == Block.Admincrete && !player.Can(Permissions.DeleteAdmincrete))
            {
                player.Message("Error: Cannot delete admincrete!");
                return;
            }
            if (rtoBlock == Block.Admincrete && !player.Can(Permissions.PlaceAdmincrete))
            {
                player.Message("Error: Cannot place admincrete!");
                return;
            }
            for (int x = sx; x <= ex; x += step)
            {
                for (int y = sy; y <= ey; y += step)
                {
                    for (int h = sh; h <= eh; h++)
                    {
                        for (int y3 = 0; y3 < step && y + y3 <= ey; y3++)
                        {
                            for (int x3 = 0; x3 < step && x + x3 <= ex; x3++)
                            {
                                block = player.world.map.GetBlock(x + x3, y + y3, h);
                                if (block == (byte)rfromBlock)
                                {
                                    player.drawUndoBuffer.Enqueue(new BlockUpdate(Player.Console, x + x3, y + y3, h, block));
                                    player.world.map.QueueUpdate(new BlockUpdate(Player.Console, x + x3, y + y3, h, (byte)rtoBlock));
                                }
                            }
                        }
                    }
                }
            }
            player.Message("Replacing " + blocks + " blocks... The map is now being updated.");
            Logger.Log("{0} initiated replacing an area containing {1} blocks from type {2} to type {3}.", LogType.UserActivity,
                                  player.GetLogName(),
                                  blocks,
                                  rfromBlock.ToString(), rtoBlock.ToString());
            GC.Collect(GC.MaxGeneration, GCCollectionMode.Optimized);
            player.drawingInProgress = false;
        }
示例#13
0
        internal static void DrawEllipsoid( Player player, Position[] marks, object tag )
        {
            player.drawingInProgress = true;

            Block drawBlock;
            if( tag == null ) {
                drawBlock = player.lastUsedBlockType;
            } else {
                drawBlock = (Block)tag;
            }

            // find start/end coordinates
            int sx = Math.Min( marks[0].x, marks[1].x );
            int ex = Math.Max( marks[0].x, marks[1].x );
            int sy = Math.Min( marks[0].y, marks[1].y );
            int ey = Math.Max( marks[0].y, marks[1].y );
            int sh = Math.Min( marks[0].h, marks[1].h );
            int eh = Math.Max( marks[0].h, marks[1].h );

            int blocks;
            byte block;
            int step = 8;

            blocks = (ex - sx + 1) * (ey - sy + 1) * (eh - sh + 1);
            if( blocks > 2000000 ) {
                player.Message( "NOTE: This draw command is too massive to undo." );
            }

            // find axis lengths
            double rx = (ex - sx + 1) / 2 + .25;
            double ry = (ey - sy + 1) / 2 + .25;
            double rh = (eh - sh + 1) / 2 + .25;

            double rx2 = 1 / (rx * rx);
            double ry2 = 1 / (ry * ry);
            double rh2 = 1 / (rh * rh);

            // find center points
            double cx = (ex + sx) / 2;
            double cy = (ey + sy) / 2;
            double ch = (eh + sh) / 2;

            // prepare to draw
            player.drawUndoBuffer.Clear();

            blocks = (int)(Math.PI * 0.75 * rx * ry * rh);
            if( blocks > 2000000 ) {
                player.Message( "NOTE: This draw command is too massive to undo." );
            }

            for ( int x = sx; x <= ex; x += step ) {
                for ( int y = sy; y <= ey; y += step ) {
                    for ( int h = sh; h <= eh; h++ ) {
                        for ( int y3 = 0; y3 < step && y + y3 <= ey; y3++ ) {
                            for ( int x3 = 0; x3 < step && x + x3 <= ex; x3++ ) {

                                // get relative coordinates
                                double dx = ( x + x3 - cx );
                                double dy = ( y + y3 - cy );
                                double dh = ( h - ch );

                                // test if it's inside ellipse
                                if ( ( dx * dx ) * rx2 + ( dy * dy ) * ry2 + ( dh * dh ) * rh2 <= 1 ) {
                                    block = player.world.map.GetBlock( x + x3, y + y3, h );
                                    if ( block == (byte)drawBlock ) continue;
                                    if ( block == (byte)Block.Admincrete && !player.Can( Permissions.DeleteAdmincrete ) ) continue;
                                    player.drawUndoBuffer.Enqueue( new BlockUpdate( Player.Console, x + x3, y + y3, h, block ) );
                                    player.world.map.QueueUpdate( new BlockUpdate( Player.Console, x + x3, y + y3, h, (byte)drawBlock ) );
                                }
                            }
                        }
                    }
                }
            }
            player.drawingInProgress = false;
            player.Message( "Drawing " + blocks + " blocks... The map is now being updated." );
            Logger.Log( "{0} initiated drawing a cuboid containing {1} blocks of type {2}.", LogType.UserActivity,
                                  player.GetLogName(),
                                  blocks,
                                  drawBlock.ToString() );
            GC.Collect( GC.MaxGeneration, GCCollectionMode.Optimized );
        }
示例#14
0
        internal static void DrawCuboid( Player player, Position[] marks, object tag )
        {
            player.drawingInProgress = true;

            Block drawBlock;
            if( tag == null ) {
                drawBlock = player.lastUsedBlockType;
            } else {
                drawBlock = (Block)tag;
            }

            // find start/end coordinates
            int sx = Math.Min( marks[0].x, marks[1].x );
            int ex = Math.Max( marks[0].x, marks[1].x );
            int sy = Math.Min( marks[0].y, marks[1].y );
            int ey = Math.Max( marks[0].y, marks[1].y );
            int sh = Math.Min( marks[0].h, marks[1].h );
            int eh = Math.Max( marks[0].h, marks[1].h );

            int blocks;
            byte block;
            int step = 8;

            blocks = (ex - sx + 1) * (ey - sy + 1) * (eh - sh + 1);
            if( blocks > 2000000 ) {
                player.Message( "NOTE: This draw command is too massive to undo." );
            }

            for ( int x = sx; x <= ex; x += step ) {
                for ( int y = sy; y <= ey; y += step ) {
                    for ( int h = sh; h <= eh; h++ ) {
                        for ( int y3 = 0; y3 < step && y + y3 <= ey; y3++ ) {
                            for ( int x3 = 0; x3 < step && x + x3 <= ex; x3++ ) {
                                block = player.world.map.GetBlock( x + x3, y + y3, h );
                                if ( block == (byte)drawBlock ) continue;
                                if ( block == (byte)Block.Admincrete && !player.Can( Permissions.DeleteAdmincrete ) ) continue;
                                player.drawUndoBuffer.Enqueue( new BlockUpdate( Player.Console, x + x3, y + y3, h, block ) );
                                player.world.map.QueueUpdate( new BlockUpdate( Player.Console, x + x3, y + y3, h, (byte)drawBlock ) );
                            }
                        }
                    }
                }
            }
            player.Message( "Drawing " + blocks + " blocks... The map is now being updated." );
            Logger.Log( "{0} initiated drawing a cuboid containing {1} blocks of type {2}.", LogType.UserActivity,
                                  player.GetLogName(),
                                  blocks,
                                  drawBlock.ToString() );
            GC.Collect( GC.MaxGeneration, GCCollectionMode.Optimized );
            player.drawingInProgress = false;
        }