public static void SetParamIteration(Player p, CommandReader cmd) { string strParam = cmd.Next(); if (string.IsNullOrWhiteSpace(strParam)) { p.Message("Error: missing param variable name"); return; } strParam = strParam.ToLower(); try { CheckParamVar(strParam); double from = ReadDoubleParam(cmd, "lower bound"); double to = ReadDoubleParam(cmd, "upper bound"); double step = ReadDoubleParam(cmd, "step"); if (step == 0 || (to - from)/step < 0) throw new ArgumentException("wrong iteration bounds/step combination"); p.Message("Iteration for " + strParam + " from " + from + " to " + to + " with step " + step + ". " + ((to - from)/step + 1) + " steps."); GetPlayerParametrizationParamsStorage(p)[VarNameToIdx(strParam[0])] = new double[] {from, to, step}; } catch (Exception e) { p.Message("Error: " + e.Message); } }
protected FuncDrawOperation(Player player, CommandReader cmd) : base(player) { string strFunc = cmd.Next(); if (string.IsNullOrWhiteSpace(strFunc)) { player.Message("&WEmpty function expression"); return; } if (strFunc.Length < 3) { player.Message("&WExpression is too short (should be like z=f(x,y))"); return; } strFunc = strFunc.ToLower(); _vaxis = GetAxis(SimpleParser.PreparseAssignment(ref strFunc)); _expression = SimpleParser.Parse(strFunc, GetVarArray(_vaxis)); player.Message("Expression parsed as "+_expression.Print()); string scalingStr=cmd.Next(); _scaler = new Scaler(scalingStr); }
private static void TrollHandler( Player player, CommandReader cmd ) { string Name = cmd.Next(); if ( Name == null ) { player.Message( "Player not found. Please specify valid name." ); return; } if ( !Player.IsValidPlayerName( Name ) ) return; Player target = Server.FindPlayerOrPrintMatches( player, Name, SearchOptions.Default ); if ( target == null ) return; string options = cmd.Next(); if ( options == null ) { CdTroll.PrintUsage( player ); return; } string Message = cmd.NextAll(); if ( Message.Length < 1 && options.ToLower() != "leave" ) { player.Message( "&WError: Please enter a message for {0}.", target.ClassyName ); return; } switch ( options.ToLower() ) { case "pm": if ( player.Can( Permission.UseColorCodes ) && Message.Contains( "%" ) ) { Message = Chat.ReplacePercentColorCodes( Message, false ); } Server.Players.Message( "&Pfrom {0}: {1}", target.Name, Message ); break; case "st": case "staff": Chat.SendStaff( target, Message ); break; case "i": case "impersonate": case "msg": case "message": case "m": Server.Message( "{0}&S&F: {1}", target.ClassyName, Message ); break; case "leave": case "disconnect": case "gtfo": Server.Players.Message( "&SPlayer {0}&S left the server.", target.ClassyName ); break; default: player.Message( "Invalid option. Please choose st, ac, pm, message or leave" ); break; } }
public override MapGeneratorParameters CreateParameters(Player player, CommandReader cmd) { string themeName = cmd.Next(); if (themeName == null) { return(CreateDefaultParameters()); } MapGenTheme theme; RealisticMapGenTerrainType terrainType; string templateName = cmd.Next(); if (templateName == null) { player.Message("SetGen: Realistic MapGen requires both a theme and a terrainType. " + "See &H/Help SetGen Realistic&S or check wiki.fCraft.net for details"); return(null); } // parse theme bool swapThemeAndTemplate; if (EnumUtil.TryParse(themeName, out theme, true)) { swapThemeAndTemplate = false; } else if (EnumUtil.TryParse(templateName, out theme, true)) { swapThemeAndTemplate = true; } else { player.Message("SetGen: Unrecognized theme \"{0}\". Available themes are: {1}", themeName, Enum.GetNames(typeof(MapGenTheme)).JoinToString()); return(null); } // parse terrainType if (swapThemeAndTemplate && !EnumUtil.TryParse(themeName, out terrainType, true)) { MessageTemplateList(themeName, player); return(null); } else if (!EnumUtil.TryParse(templateName, out terrainType, true)) { MessageTemplateList(templateName, player); return(null); } // TODO: optional parameters for preset customization return(CreateParameters(terrainType, theme)); }
static void MassRankHandler(Player player, CommandReader cmd) { string fromRankName = cmd.Next(); string toRankName = cmd.Next(); string reason = cmd.NextAll(); if (fromRankName == null || toRankName == null) { CdMassRank.PrintUsage(player); return; } Rank fromRank = RankManager.FindRank(fromRankName); if (fromRank == null) { player.MessageNoRank(fromRankName); return; } Rank toRank = RankManager.FindRank(toRankName); if (toRank == null) { player.MessageNoRank(toRankName); return; } if (fromRank == toRank) { player.Message("Ranks must be different"); return; } int playerCount; using (PlayerDB.GetReadLock()) { playerCount = PlayerDB.List.Count(t => t.Rank == fromRank); } string verb = (fromRank > toRank ? "demot" : "promot"); if (!cmd.IsConfirmed) { player.Confirm(cmd, "MassRank: {0}e {1} players?", verb.UppercaseFirst(), playerCount); return; } player.Message("MassRank: {0}ing {1} players...", verb, playerCount); int affected = PlayerDB.MassRankChange(player, fromRank, toRank, reason); player.Message("MassRank: done, {0} records affected.", affected); }
private static void ModelHandler(Player player, CommandReader cmd) { PlayerInfo otherPlayer = InfoCommands.FindPlayerInfo(player, cmd, cmd.Next() ?? player.Name); if (otherPlayer == null) return; if (!player.IsStaff && otherPlayer != player.Info) { Rank staffRank = RankManager.GetMinRankWithAnyPermission(Permission.ReadStaffChat); if (staffRank != null) { player.Message("You must be {0}&s+ to change another players Model", staffRank.ClassyName); } else { player.Message("No ranks have the ReadStaffChat permission so no one can change other players Model, yell at the owner."); } return; } if (otherPlayer.Rank.Index < player.Info.Rank.Index) { player.Message("Cannot change the Model of someone higher rank than you."); return; } if (otherPlayer == null) { player.Message("Your current Model: &f" + player.Info.Mob); return; } string model = cmd.Next(); if (string.IsNullOrEmpty(model)) { player.Message("Current Model for {0}: &f{1}", otherPlayer.Name, otherPlayer.Mob); return; } if (otherPlayer.IsOnline && otherPlayer.Rank.Index >= player.Info.Rank.Index) { if (!validEntities.Contains(model.ToLower())) { Block block; if (Map.GetBlockByName(model, false, out block)) { model = block.GetHashCode().ToString(); } else { player.Message("Model not valid, see &h/Help Model&s."); return; } } if (otherPlayer.Mob.ToLower() == model.ToLower()) { player.Message("&f{0}&s's model is already set to &f{1}", otherPlayer.Name, model); return; } if (otherPlayer.IsOnline) { otherPlayer.PlayerObject.Message("&f{0}&shanged your model from &f{1} &sto &f{2}", (otherPlayer.PlayerObject == player ? "&sC" : player.Name + " &sc"), otherPlayer.Mob, model); } if (otherPlayer.PlayerObject != player) { player.Message("&sChanged model of &f{0} &sfrom &f{1} &sto &f{2}", otherPlayer.Name, otherPlayer.Mob, model); } otherPlayer.oldMob = otherPlayer.Mob; otherPlayer.Mob = model; } else { player.Message("Player not found/online or lower rank than you"); } }
static void ZoneInfoHandler(Player player, CommandReader cmd) { string zoneName = cmd.Next(); if (zoneName == null) { player.Message("No zone name specified. See &H/Help ZInfo"); return; } Zone zone = player.WorldMap.Zones.Find(zoneName); if (zone == null) { player.MessageNoZone(zoneName); return; } player.Message("About zone \"{0}\": size {1} x {2} x {3}, contains {4} blocks, editable by {5}+.", zone.Name, zone.Bounds.Width, zone.Bounds.Length, zone.Bounds.Height, zone.Bounds.Volume, zone.Controller.MinRank.ClassyName); player.Message(" Zone center is at ({0},{1},{2}).", (zone.Bounds.XMin + zone.Bounds.XMax) / 2, (zone.Bounds.YMin + zone.Bounds.YMax) / 2, (zone.Bounds.ZMin + zone.Bounds.ZMax) / 2); if (zone.CreatedBy != null) { player.Message(" Zone created by {0}&S on {1:MMM d} at {1:h:mm} ({2} ago).", zone.CreatedByClassy, zone.CreatedDate, DateTime.UtcNow.Subtract(zone.CreatedDate).ToMiniString()); } if (zone.EditedBy != null) { player.Message(" Zone last edited by {0}&S on {1:MMM d} at {1:h:mm} ({2}d {3}h ago).", zone.EditedByClassy, zone.EditedDate, DateTime.UtcNow.Subtract(zone.EditedDate).Days, DateTime.UtcNow.Subtract(zone.EditedDate).Hours); } PlayerExceptions zoneExceptions = zone.ExceptionList; if (zoneExceptions.Included.Length > 0) { player.Message(" Zone whitelist includes: {0}", zoneExceptions.Included.JoinToClassyString()); } if (zoneExceptions.Excluded.Length > 0) { player.Message(" Zone blacklist excludes: {0}", zoneExceptions.Excluded.JoinToClassyString()); } }
static void ZoneMarkHandler([NotNull] Player player, [NotNull] CommandReader cmd) { switch (player.SelectionMarksExpected) { case 0: player.MessageNow("Cannot use ZMark - no selection in progress."); break; case 2: { string zoneName = cmd.Next(); if (zoneName == null) { CdZoneMark.PrintUsage(player); return; } Zone zone = player.WorldMap.Zones.Find(zoneName); if (zone == null) { player.MessageNoZone(zoneName); return; } player.SelectionResetMarks(); player.SelectionAddMark(zone.Bounds.MinVertex, false, false); player.SelectionAddMark(zone.Bounds.MaxVertex, false, true); } break; default: player.MessageNow("ZMark can only be used with 2-block/2-click selections."); break; } }
public static void SetParametrization(Player p, CommandReader cmd) { string strFunc = cmd.Next(); if (string.IsNullOrWhiteSpace(strFunc)) { p.Message("Error: empty parametrization expression"); return; } if (strFunc.Length < 3) { p.Message("Error: expression is too short (should be like x=f(t,u,v))"); return; } strFunc = strFunc.ToLower(); try { string coordVar = SimpleParser.PreparseAssignment(ref strFunc); CheckCoordVar(coordVar); Expression expression = SimpleParser.Parse(strFunc, new string[] { "t", "u", "v" }); p.Message("Expression parsed as " + coordVar + "=" + expression.Print()); GetPlayerParametrizationCoordsStorage(p)[VarNameToIdx(coordVar[0])] = expression; } catch (Exception e) { p.Message("Error: "+e.Message); } }
static void BumHandler(Player player, CommandReader cmd) { string newModeName = cmd.Next(); if (newModeName == null) { player.Message("&sBytes Sent: {0} Per Second: {1:0.0}", player.BytesSent, player.BytesSentRate); player.Message("&sBytes Received: {0} Per Second: {1:0.0}", player.BytesReceived, player.BytesReceivedRate); player.Message("&sBandwidth mode: {0}",player.BandwidthUseMode); return; } else if (player.Can(Permission.EditPlayerDB)) { var newMode = (BandwidthUseMode)Enum.Parse(typeof(BandwidthUseMode), newModeName, true); player.Message("&sBandwidth mode: {0} --> {1}", player.BandwidthUseMode, newMode.ToString()); player.BandwidthUseMode = newMode; player.Info.BandwidthUseMode = newMode; return; } else { player.Message("You need {0}&s to change your BandwidthUseMode", RankManager.GetMinRankWithAnyPermission(Permission.EditPlayerDB).ClassyName); return; } }
static void ImportHandler(Player player, CommandReader cmd) { string action = cmd.Next(); if (action == null) { CdImport.PrintUsage(player); return; } switch (action.ToLower()) { case "bans": if (!player.Can(Permission.Ban)) { player.MessageNoAccess(Permission.Ban); return; } ImportBans(player, cmd); break; case "ranks": if (!player.Can(Permission.Promote)) { player.MessageNoAccess(Permission.Promote); return; } ImportRanks(player, cmd); break; default: CdImport.PrintUsage(player); break; } }
static void BanHandler( Player player, CommandReader cmd ) { string targetName = cmd.Next(); if( targetName == null ) { CdBan.PrintUsage( player ); return; } PlayerInfo target = PlayerDB.FindPlayerInfoOrPrintMatches( player, targetName, SearchOptions.ReturnSelfIfOnlyMatch ); if( target == null ) return; if( target == player.Info ) { player.Message( "You cannot &H/Ban&S yourself." ); return; } string reason = cmd.NextAll(); try { Player targetPlayer = target.PlayerObject; target.Ban( player, reason, true, true ); WarnIfOtherPlayersOnIP( player, target, targetPlayer ); } catch( PlayerOpException ex ) { player.Message( ex.MessageColored ); if( ex.ErrorCode == PlayerOpExceptionCode.ReasonRequired ) { FreezeIfAllowed( player, target ); } } }
static void ZoneMarkHandler(Player player, CommandReader cmd) { if (player.SelectionMarksExpected == 0) { player.MessageNow("Cannot use ZMark - no selection in progress."); } else if (player.SelectionMarksExpected == 2) { string zoneName = cmd.Next(); if (zoneName == null) { CdZoneMark.PrintUsage(player); return; } Zone zone = player.WorldMap.Zones.Find(zoneName); if (zone == null) { player.MessageNoZone(zoneName); return; } player.SelectionResetMarks(); player.SelectionAddMark(zone.Bounds.MinVertex, false); player.SelectionAddMark(zone.Bounds.MaxVertex, true); } else { player.MessageNow("ZMark can only be used for 2-block selection."); } }
static void InfoSwapHandler(Player player, CommandReader cmd) { string p1Name = cmd.Next(); string p2Name = cmd.Next(); if (p1Name == null || p2Name == null) { CdInfoSwap.PrintUsage(player); return; } PlayerInfo p1 = PlayerDB.FindByPartialNameOrPrintMatches(player, p1Name); if (p1 == null) { return; } PlayerInfo p2 = PlayerDB.FindByPartialNameOrPrintMatches(player, p2Name); if (p2 == null) { return; } if (p1 == p2) { player.Message("InfoSwap: Please specify 2 different players."); return; } if (p1.IsOnline || p2.IsOnline) { player.Message("InfoSwap: Both players must be offline to swap info."); return; } if (!cmd.IsConfirmed) { player.Confirm(cmd, "InfoSwap: Swap stats of players {0}&S and {1}&S?", p1.ClassyName, p2.ClassyName); } else { PlayerDB.SwapPlayerInfo(p1, p2); player.Message("InfoSwap: Stats of {0}&S and {1}&S have been swapped.", p1.ClassyName, p2.ClassyName); } }
static void ReloadHandler(Player player, CommandReader cmd) { string whatToReload = cmd.Next(); if (whatToReload == null) { CdReload.PrintUsage(player); return; } whatToReload = whatToReload.ToLower(); using (LogRecorder rec = new LogRecorder()) { bool success; switch (whatToReload) { case "config": try { Config.Reload(false); success = true; } catch (Exception ex) { Logger.Log(LogType.Error, "Error reloading config: {0}", ex); player.Message("An error occurred while trying to reload config: {0}: {1}", ex.GetType().Name, ex.Message); success = false; } break; case "salt": Heartbeat.Salt = Server.GetRandomString(32); player.Message("&WNote: Until server synchronizes with Minecraft.net, " + "connecting players may have trouble verifying names."); success = true; break; default: CdReload.PrintUsage(player); return; } if (rec.HasMessages) { foreach (string msg in rec.MessageList) { player.Message(msg); } } if (success) { player.Message("Reload: reloaded {0}.", whatToReload); } else { player.Message("&WReload: Error(s) occurred while reloading {0}.", whatToReload); } } }
static void ZoneListHandler(Player player, CommandReader cmd) { World world = player.World; string worldName = cmd.Next(); if (worldName != null) { world = WorldManager.FindWorldOrPrintMatches(player, worldName); if (world == null) { return; } player.Message("List of zones on {0}&S:", world.ClassyName); } else if (world != null) { player.Message("List of zones on this world:"); } else { player.Message("When used from console, &H/Zones&S command requires a world name."); return; } Map map = world.Map; if (map == null) { if (!MapUtility.TryLoadHeader(world.MapFileName, out map)) { player.Message("&WERROR:Could not load mapfile for world {0}.", world.ClassyName); return; } } Zone[] zones = map.Zones.Cache; if (zones.Length > 0) { foreach (Zone zone in zones) { player.Message(" {0} ({1}&S) - {2} x {3} x {4}", zone.Name, zone.Controller.MinRank.ClassyName, zone.Bounds.Width, zone.Bounds.Length, zone.Bounds.Height); } player.Message(" Type &H/ZInfo ZoneName&S for details."); } else { player.Message(" No zones defined."); } }
public override MapGeneratorParameters CreateParameters( Player player, CommandReader cmd ) { string themeName = cmd.Next(); if( themeName == null ) { return CreateDefaultParameters(); } MapGenTheme theme; RealisticMapGenTerrainType terrainType; string templateName = cmd.Next(); if( templateName == null ) { player.Message( "SetGen: Realistic MapGen requires both a theme and a terrainType. " + "See &H/Help SetGen Realistic&S or check wiki.fCraft.net for details" ); return null; } // parse theme bool swapThemeAndTemplate; if( EnumUtil.TryParse( themeName, out theme, true ) ) { swapThemeAndTemplate = false; } else if( EnumUtil.TryParse( templateName, out theme, true ) ) { swapThemeAndTemplate = true; } else { player.Message( "SetGen: Unrecognized theme \"{0}\". Available themes are: {1}", themeName, Enum.GetNames( typeof( MapGenTheme ) ).JoinToString() ); return null; } // parse terrainType if( swapThemeAndTemplate && !EnumUtil.TryParse( themeName, out terrainType, true ) ) { MessageTemplateList( themeName, player ); return null; } else if( !EnumUtil.TryParse( templateName, out terrainType, true ) ) { MessageTemplateList( templateName, player ); return null; } // TODO: optional parameters for preset customization return CreateParameters( terrainType, theme ); }
public InequalityDrawOperation(Player player, CommandReader cmd) : base(player) { string strFunc = cmd.Next(); if (string.IsNullOrWhiteSpace(strFunc)) throw new ArgumentException("empty inequality expression"); if (strFunc.Length < 3) throw new ArgumentException("expression is too short (should be like f(x,y,z)>g(x,y,z))"); strFunc = strFunc.ToLower(); _expression = SimpleParser.Parse(strFunc, new string[] { "x", "y", "z" }); if (!_expression.IsInEquality()) throw new ArgumentException("the expression given is not an inequality (should be like f(x,y,z)>g(x,y,z))"); player.Message("Expression parsed as " + _expression.Print()); string scalingStr = cmd.Next(); _scaler = new Scaler(scalingStr); }
static void MassRankHandler( Player player, CommandReader cmd ) { string fromRankName = cmd.Next(); string toRankName = cmd.Next(); string reason = cmd.NextAll(); if( fromRankName == null || toRankName == null ) { CdMassRank.PrintUsage( player ); return; } Rank fromRank = RankManager.FindRank( fromRankName ); if( fromRank == null ) { player.MessageNoRank( fromRankName ); return; } Rank toRank = RankManager.FindRank( toRankName ); if( toRank == null ) { player.MessageNoRank( toRankName ); return; } if( fromRank == toRank ) { player.Message( "Ranks must be different" ); return; } int playerCount; using( PlayerDB.GetReadLock() ) { playerCount = PlayerDB.List.Count( t => t.Rank == fromRank ); } string verb = (fromRank > toRank ? "demot" : "promot"); if( !cmd.IsConfirmed ) { player.Confirm( cmd, "MassRank: {0}e {1} players?", verb.UppercaseFirst(), playerCount ); return; } player.Message( "MassRank: {0}ing {1} players...", verb, playerCount ); int affected = PlayerDB.MassRankChange( player, fromRank, toRank, reason ); player.Message( "MassRank: done, {0} records affected.", affected ); }
public EqualityDrawOperation(Player player, CommandReader cmd) : base(player) { string strFunc = cmd.Next(); if (string.IsNullOrWhiteSpace(strFunc)) { player.Message("empty equality expression"); return; } if (strFunc.Length < 3) { player.Message("expression is too short (should be like f(x,y,z)=g(x,y,z))"); return; } strFunc = strFunc.ToLower(); _expression = SimpleParser.ParseAsEquality(strFunc, new string[] { "x", "y", "z" }); player.Message("Expression parsed as " + _expression.Print()); string scalingStr = cmd.Next(); _scaler = new Scaler(scalingStr); }
public override MapGeneratorParameters CreateParameters( Player player, CommandReader cmd ) { string themeName = cmd.Next(); MapGeneratorParameters newParams; if( themeName != null ) { newParams = CreateParameters( themeName ); if( newParams == null ) { player.Message( "SetGen: \"{0}\" is not a recognized flat theme name. Available themes are: {1}", themeName, Presets.JoinToString() ); return null; } } else { newParams = CreateDefaultParameters(); } return newParams; }
static void IgnoreHandler(Player player, CommandReader cmd) { string name = cmd.Next(); if (name != null) { if (cmd.HasNext) { CdIgnore.PrintUsage(player); return; } PlayerInfo targetInfo = PlayerDB.FindByPartialNameOrPrintMatches(player, name); if (targetInfo == null) { return; } if (targetInfo == player.Info) { player.MessageNow("You cannot ignore yourself."); return; } if (player.Ignore(targetInfo)) { player.MessageNow("You are now ignoring {0}", targetInfo.ClassyName); } else { player.MessageNow("You are already ignoring {0}", targetInfo.ClassyName); } } else { PlayerInfo[] ignoreList = player.IgnoreList; if (ignoreList.Length > 0) { player.MessageNow("Ignored players: {0}", ignoreList.JoinToClassyString()); } else { player.MessageNow("You are not currently ignoring anyone."); } } }
static void BanHandler( Player player, CommandReader cmd ) { string targetName = cmd.Next(); if( targetName == null ) { CdBan.PrintUsage( player ); return; } PlayerInfo target = PlayerDB.FindByPartialNameOrPrintMatches( player, targetName ); if( target == null ) return; string reason = cmd.NextAll(); try { Player targetPlayer = target.PlayerObject; target.Ban( player, reason, true, true ); WarnIfOtherPlayersOnIP( player, target, targetPlayer ); } catch( PlayerOpException ex ) { player.Message( ex.MessageColored ); if( ex.ErrorCode == PlayerOpExceptionCode.ReasonRequired ) { FreezeIfAllowed( player, target ); } } }
public override MapGeneratorParameters CreateParameters(Player player, CommandReader cmd) { string themeName = cmd.Next(); MapGeneratorParameters newParams; if (themeName != null) { newParams = CreateParameters(themeName); if (newParams == null) { player.Message("SetGen: \"{0}\" is not a recognized flat theme name. Available themes are: {1}", themeName, Presets.JoinToString()); return(null); } } else { newParams = CreateDefaultParameters(); } return(newParams); }
static void UnignoreHandler([NotNull] Player player, [NotNull] CommandReader cmd) { string name = cmd.Next(); if (name != null) { if (cmd.HasNext) { // too many parameters given CdUnignore.PrintUsage(player); return; } // A name was given -- let's find the target PlayerInfo targetInfo = PlayerDB.FindPlayerInfoOrPrintMatches(player, name, SearchOptions.ReturnSelfIfOnlyMatch); if (targetInfo == null) { return; } if (targetInfo == player.Info) { player.Message("You cannot &H/Ignore&S (or &H/Unignore&S) yourself."); return; } if (player.Unignore(targetInfo)) { player.MessageNow("You are no longer ignoring {0}", targetInfo.ClassyName); } else { player.MessageNow("You are not currently ignoring {0}", targetInfo.ClassyName); } } else { ListIgnoredPlayers(player); } }
public ManifoldDrawOperation(Player p, CommandReader cmd) : base (p) { _expressions = PrepareParametrizedManifold.GetPlayerParametrizationCoordsStorage(p); if (null == _expressions[0]) throw new InvalidExpressionException("x is undefined"); if (null == _expressions[1]) throw new InvalidExpressionException("y is undefined"); if (null == _expressions[2]) throw new InvalidExpressionException("z is undefined"); _paramIterations = PrepareParametrizedManifold.GetPlayerParametrizationParamsStorage(p); if (null==_paramIterations[0] && null==_paramIterations[1] && null==_paramIterations[2]) throw new InvalidExpressionException("all parametrization variables are undefined"); if (GetNumOfSteps(0) * GetNumOfSteps(1) * GetNumOfSteps(2) > MaxIterationSteps) throw new InvalidExpressionException("too many iteration steps (over " + MaxIterationSteps + ")"); _scaler=new Scaler(cmd.Next()); p.Message("Going to draw the following parametrization:\nx=" + _expressions[0].Print()+ "\ny=" + _expressions[1].Print() + "\nz=" + _expressions[2].Print()); }
static void BringAllHandler( Player player, CommandReader cmd ) { World playerWorld = player.World; if( playerWorld == null ) PlayerOpException.ThrowNoWorld( player ); List<World> targetWorlds = new List<World>(); List<Rank> targetRanks = new List<Rank>(); bool allWorlds = false; bool allRanks = true; // Parse the list of worlds and ranks string arg; while( (arg = cmd.Next()) != null ) { if( arg.StartsWith( "@" ) ) { Rank rank = RankManager.FindRank( arg.Substring( 1 ) ); if( rank == null ) { player.MessageNoRank( arg.Substring( 1 ) ); return; } else { if( player.Can( Permission.Bring, rank ) ) { targetRanks.Add( rank ); } else { player.Message( "&WYou are not allowed to bring players of rank {0}", rank.ClassyName ); } allRanks = false; } } else if( arg == "*" ) { allWorlds = true; } else { World world = WorldManager.FindWorldOrPrintMatches( player, arg ); if( world == null ) return; targetWorlds.Add( world ); } } // If no worlds were specified, use player's current world if( !allWorlds && targetWorlds.Count == 0 ) { targetWorlds.Add( player.World ); } // Apply all the rank and world options HashSet<Player> targetPlayers; if( allRanks && allWorlds ) { targetPlayers = new HashSet<Player>( Server.Players ); } else if( allWorlds ) { targetPlayers = new HashSet<Player>(); foreach( Rank rank in targetRanks ) { foreach( Player rankPlayer in Server.Players.Ranked( rank ) ) { targetPlayers.Add( rankPlayer ); } } } else if( allRanks ) { targetPlayers = new HashSet<Player>(); foreach( World world in targetWorlds ) { foreach( Player worldPlayer in world.Players ) { targetPlayers.Add( worldPlayer ); } } } else { targetPlayers = new HashSet<Player>(); foreach( Rank rank in targetRanks ) { foreach( World world in targetWorlds ) { foreach( Player rankWorldPlayer in world.Players.Ranked( rank ) ) { targetPlayers.Add( rankWorldPlayer ); } } } } Rank bringLimit = player.Info.Rank.GetLimit( Permission.Bring ); // Remove the player him/herself targetPlayers.Remove( player ); int count = 0; // Actually bring all the players foreach( Player targetPlayer in targetPlayers.CanBeSeen( player ) .RankedAtMost( bringLimit ) ) { if( targetPlayer.World == playerWorld ) { // teleport within the same world targetPlayer.TeleportTo( player.Position ); targetPlayer.Position = player.Position; if( targetPlayer.Info.IsFrozen ) { targetPlayer.Position = player.Position; } } else { // teleport to a different world BringPlayerToWorld( player, targetPlayer, playerWorld, false, true ); } count++; } // Check if there's anyone to bring if( count == 0 ) { player.Message( "No players to bring!" ); } else { player.Message( "Bringing {0} players...", count ); } }
static void WorldBringHandler( Player player, CommandReader cmd ) { string playerName = cmd.Next(); string worldName = cmd.Next(); if( playerName == null || worldName == null ) { CdWorldBring.PrintUsage( player ); return; } Player target = Server.FindPlayerOrPrintMatches( player, playerName, false, false, true ); World world = WorldManager.FindWorldOrPrintMatches( player, worldName ); if( target == null || world == null ) return; if( !player.Can( Permission.Bring, target.Info.Rank ) ) { player.Message( "You may only bring players ranked {0}&S or lower.", player.Info.Rank.GetLimit( Permission.Bring ).ClassyName ); player.Message( "{0}&S is ranked {1}", target.ClassyName, target.Info.Rank.ClassyName ); return; } if( world == target.World ) { player.Message( "Player {0}&S is already in world {1}&S. They were brought to spawn.", target.ClassyName, world.ClassyName ); target.TeleportTo( target.WorldMap.Spawn ); return; } SecurityCheckResult check = world.AccessSecurity.CheckDetailed( target.Info ); if( check == SecurityCheckResult.RankTooLow ) { if( player.CanJoin( world ) ) { if( cmd.IsConfirmed ) { BringPlayerToWorld( player, target, world, true, false ); } else { Logger.Log( LogType.UserActivity, "WBring: Asked {0} to confirm overriding world permissions to bring player {1} to world {2}", player.Name, target.Name, world.Name ); player.Confirm( cmd, "Player {0}&S is ranked too low to join {1}&S. Override world permissions?", target.ClassyName, world.ClassyName ); } } else { player.Message( "Neither you nor {0}&S are allowed to join world {1}", target.ClassyName, world.ClassyName ); } } else { BringPlayerToWorld( player, target, world, false, false ); } }
static void BringHandler( Player player, CommandReader cmd ) { string name = cmd.Next(); if( name == null ) { CdBring.PrintUsage( player ); return; } // bringing someone to another player (instead of to self) string toName = cmd.Next(); Player toPlayer = player; if( toName != null ) { toPlayer = Server.FindPlayerOrPrintMatches( player, toName, true, false, true ); if( toPlayer == null ) return; } else if( toPlayer.World == null ) { player.Message( "When used from console, /Bring requires both names to be given." ); return; } World world = toPlayer.World; if( world == null ) PlayerOpException.ThrowNoWorld( toPlayer ); Player target = Server.FindPlayerOrPrintMatches( player, name, true, false, true ); if( target == null ) return; if( !player.Can( Permission.Bring, target.Info.Rank ) ) { player.Message( "You may only bring players ranked {0}&S or lower.", player.Info.Rank.GetLimit( Permission.Bring ).ClassyName ); player.Message( "{0}&S is ranked {1}", target.ClassyName, target.Info.Rank.ClassyName ); return; } if( target.World == world ) { // teleport within the same world target.TeleportTo( toPlayer.Position ); } else { // teleport to a different world SecurityCheckResult check = world.AccessSecurity.CheckDetailed( target.Info ); if( check == SecurityCheckResult.RankTooLow ) { if( player.CanJoin( world ) ) { if( cmd.IsConfirmed ) { BringPlayerToWorld( player, target, world, true, true ); } else { Logger.Log( LogType.UserActivity, "Bring: Asked {0} to confirm overriding world permissions to bring player {1} to world {2}", player.Name, target.Name, world.Name ); player.Confirm( cmd, "Player {0}&S is ranked too low to join {1}&S. Override world permissions?", target.ClassyName, world.ClassyName ); } } else { player.Message( "Neither you nor {0}&S are allowed to join world {1}", target.ClassyName, world.ClassyName ); } } else { BringPlayerToWorld( player, target, world, false, true ); } } }
static void TeleportHandler( Player player, CommandReader cmd ) { string name = cmd.Next(); if( name == null ) { CdTeleport.PrintUsage( player ); return; } if( cmd.Next() != null ) { cmd.Rewind(); int x, y, z; if( cmd.NextInt( out x ) && cmd.NextInt( out y ) && cmd.NextInt( out z ) ) { if( x <= -1024 || x >= 1024 || y <= -1024 || y >= 1024 || z <= -1024 || z >= 1024 ) { player.Message( "Coordinates are outside the valid range!" ); } else { player.TeleportTo( new Position { X = (short)(x * 32 + 16), Y = (short)(y * 32 + 16), Z = (short)(z * 32 + 16), R = player.Position.R, L = player.Position.L } ); } } else { CdTeleport.PrintUsage( player ); } } else { if( name == "-" ) { if( player.LastUsedPlayerName != null ) { name = player.LastUsedPlayerName; } else { player.Message( "Cannot repeat player name: you haven't used any names yet." ); return; } } Player[] matches = Server.FindPlayers( player, name, false, true, true ); if( matches.Length == 1 ) { Player target = matches[0]; World targetWorld = target.World; if( targetWorld == null ) PlayerOpException.ThrowNoWorld( target ); if( targetWorld == player.World ) { player.TeleportTo( target.Position ); } else { switch( targetWorld.AccessSecurity.CheckDetailed( player.Info ) ) { case SecurityCheckResult.Allowed: case SecurityCheckResult.WhiteListed: if( targetWorld.IsFull ) { player.Message( "Cannot teleport to {0}&S because world {1}&S is full.", target.ClassyName, targetWorld.ClassyName ); return; } player.StopSpectating(); player.JoinWorld( targetWorld, WorldChangeReason.Tp, target.Position ); break; case SecurityCheckResult.BlackListed: player.Message( "Cannot teleport to {0}&S because you are blacklisted on world {1}", target.ClassyName, targetWorld.ClassyName ); break; case SecurityCheckResult.RankTooLow: player.Message( "Cannot teleport to {0}&S because world {1}&S requires {2}+&S to join.", target.ClassyName, targetWorld.ClassyName, targetWorld.AccessSecurity.MinRank.ClassyName ); break; } } } else if( matches.Length > 1 ) { player.MessageManyMatches( "player", matches ); } else { player.MessageNoPlayer( name ); } } }
static void TimerHandler([NotNull] Player player, [NotNull] CommandReader cmd) { string param = cmd.Next(); // List timers if (param == null) { ChatTimer[] list = ChatTimer.TimerList.OrderBy(timer => timer.TimeLeft).ToArray(); if (list.Length == 0) { player.Message("No timers running."); } else { player.Message("There are {0} timers running:", list.Length); foreach (ChatTimer timer in list) { player.Message(" #{0} \"{1}&S\" (started by {2}, {3} left)", timer.Id, timer.Message, timer.StartedBy, timer.TimeLeft.ToMiniString()); } } return; } // Abort a timer if (param.Equals("abort", StringComparison.OrdinalIgnoreCase)) { int timerId; if (cmd.NextInt(out timerId)) { ChatTimer timer = ChatTimer.FindTimerById(timerId); if (timer == null || !timer.IsRunning) { player.Message("Given timer (#{0}) does not exist.", timerId); } else { timer.Abort(); string abortMsg = String.Format("&Y(Timer) {0}&Y aborted a timer with {1} left: {2}", player.ClassyName, timer.TimeLeft.ToMiniString(), timer.Message); Chat.SendSay(player, abortMsg); } } else { CdTimer.PrintUsage(player); } return; } // Start a timer if (player.Info.IsMuted) { player.MessageMuted(); return; } if (player.DetectChatSpam()) { return; } TimeSpan duration; if (!param.TryParseMiniTimeSpan(out duration)) { CdTimer.PrintUsage(player); return; } if (duration > DateTimeUtil.MaxTimeSpan) { player.MessageMaxTimeSpan(); return; } if (duration < ChatTimer.MinDuration) { player.Message("Timer: Must be at least 1 second."); return; } string sayMessage; string message = cmd.NextAll(); if (String.IsNullOrWhiteSpace(message)) { sayMessage = String.Format("&Y(Timer) {0}&Y started a {1} timer", player.ClassyName, duration.ToMiniString()); } else { sayMessage = String.Format("&Y(Timer) {0}&Y started a {1} timer: {2}", player.ClassyName, duration.ToMiniString(), message); } Chat.SendSay(player, sayMessage); ChatTimer.Start(duration, message, player.Name); }
static void ImportRanks(Player player, CommandReader cmd) { string serverName = cmd.Next(); string fileName = cmd.Next(); string rankName = cmd.Next(); bool silent = (cmd.Next() != null); // Make sure all parameters are specified if (serverName == null || fileName == null || rankName == null) { CdImport.PrintUsage(player); return; } // Check if file exists if (!File.Exists(fileName)) { player.Message("File not found: {0}", fileName); return; } Rank targetRank = RankManager.FindRank(rankName); if (targetRank == null) { player.MessageNoRank(rankName); return; } string[] names; switch (serverName.ToLower()) { case "mcsharp": case "mczall": case "mclawl": try { names = File.ReadAllLines(fileName); } catch (Exception ex) { Logger.Log(LogType.Error, "Could not open \"{0}\" to import ranks: {1}", fileName, ex); return; } break; default: player.Message("fCraft does not support importing from {0}", serverName); return; } if (!cmd.IsConfirmed) { player.Confirm(cmd, "Import {0} player ranks from \"{1}\"?", names.Length, Path.GetFileName(fileName)); return; } string reason = "(Import from " + serverName + ")"; foreach (string name in names) { PlayerInfo info = PlayerDB.FindExact(name) ?? PlayerDB.AddUnrecognizedPlayer(name, RankChangeType.Promoted); try { info.ChangeRank(player, targetRank, reason, !silent, true, false); } catch (PlayerOpException ex) { player.Message(ex.MessageColored); } } PlayerDB.Save(); }
static void CommandsHandler( Player player, CommandReader cmd ) { string param = cmd.Next(); if( cmd.HasNext ) { CdCommands.PrintUsage( player ); return; } CommandDescriptor[] cd; CommandCategory category; string prefix; if( param == null ) { prefix = "Available commands"; cd = CommandManager.GetCommands( player.Info.Rank, false ); } else if( param.StartsWith( "@" ) ) { string rankName = param.Substring( 1 ); Rank rank = RankManager.FindRank( rankName ); if( rank == null ) { player.MessageNoRank( rankName ); return; } else { prefix = String.Format( "Commands available to {0}&S", rank.ClassyName ); cd = CommandManager.GetCommands( rank, false ); } } else if( param.Equals( "all", StringComparison.OrdinalIgnoreCase ) ) { prefix = "All commands"; cd = CommandManager.GetCommands(); } else if( param.Equals( "hidden", StringComparison.OrdinalIgnoreCase ) ) { prefix = "Hidden commands"; cd = CommandManager.GetCommands( true ); } else if( EnumUtil.TryParse( param, out category, true ) ) { prefix = String.Format( "{0} commands", category ); cd = CommandManager.GetCommands( category, false ); } else { CdCommands.PrintUsage( player ); return; } player.MessagePrefixed( "&S ", "{0}: {1}", prefix, cd.JoinToClassyString() ); }
static void SetInfoHandler(Player player, CommandReader cmd) { string targetName = cmd.Next(); string propertyName = cmd.Next(); string valName = cmd.NextAll(); if (targetName == null || propertyName == null) { CdSetInfo.PrintUsage(player); return; } PlayerInfo info = PlayerDB.FindByPartialNameOrPrintMatches(player, targetName); if (info == null) { return; } switch (propertyName.ToLower()) { case "banreason": if (valName.Length == 0) { valName = null; } if (SetPlayerInfoField(player, "BanReason", info, info.BanReason, valName)) { info.BanReason = valName; } break; case "displayedname": string oldDisplayedName = info.DisplayedName; if (valName.Length == 0) { valName = null; } if (valName == info.DisplayedName) { if (valName == null) { player.Message("SetInfo: DisplayedName for {0} is not set.", info.Name); } else { player.Message("SetInfo: DisplayedName for {0} is already set to \"{1}&S\"", info.Name, valName); } break; } info.DisplayedName = valName; if (oldDisplayedName == null) { player.Message("SetInfo: DisplayedName for {0} set to \"{1}&S\"", info.Name, valName); } else if (valName == null) { player.Message("SetInfo: DisplayedName for {0} was reset (was \"{1}&S\")", info.Name, oldDisplayedName); } else { player.Message("SetInfo: DisplayedName for {0} changed from \"{1}&S\" to \"{2}&S\"", info.Name, oldDisplayedName, valName); } break; case "kickreason": if (valName.Length == 0) { valName = null; } if (SetPlayerInfoField(player, "KickReason", info, info.LastKickReason, valName)) { info.LastKickReason = valName; } break; case "name": if (valName.Equals(info.Name, StringComparison.OrdinalIgnoreCase)) { player.Message("SetInfo: You may change capitalization of player's real name. " + "If you'd like to make other changes to the way player's name is displayed, " + "use &H/SetInfo <Name> DisplayedName <NewName>"); break; } string oldName = info.Name; if (oldName != valName) { info.Name = valName; player.Message("Name capitalization changed from \"{0}\" to \"{1}\"", oldName, valName); } else { player.Message("Name capitalization is already \"{0}\"", oldName); } break; case "previousrank": Rank newPreviousRank; if (valName.Length > 0) { newPreviousRank = RankManager.FindRank(valName); if (newPreviousRank == null) { player.MessageNoRank(valName); break; } } else { newPreviousRank = null; } Rank oldPreviousRank = info.PreviousRank; if (newPreviousRank == oldPreviousRank) { if (newPreviousRank == null) { player.Message("SetInfo: PreviousRank for {0}&S is not set.", info.ClassyName); } else { player.Message("SetInfo: PreviousRank for {0}&S is already set to {1}", info.ClassyName, newPreviousRank.ClassyName); } break; } info.PreviousRank = newPreviousRank; if (oldPreviousRank == null) { player.Message("SetInfo: PreviousRank for {0}&S set to {1}&", info.ClassyName, newPreviousRank.ClassyName); } else if (newPreviousRank == null) { player.Message("SetInfo: PreviousRank for {0}&S was reset (was {1}&S)", info.ClassyName, oldPreviousRank.ClassyName); } else { player.Message("SetInfo: PreviousRank for {0}&S changed from {1}&S to {2}", info.ClassyName, oldPreviousRank.ClassyName, newPreviousRank.ClassyName); } break; case "rankchangetype": RankChangeType oldType = info.RankChangeType; try { info.RankChangeType = (RankChangeType)Enum.Parse(typeof(RankChangeType), valName, true); } catch (ArgumentException) { player.Message("SetInfo: Could not parse RankChangeType. Allowed values: {0}", String.Join(", ", Enum.GetNames(typeof(RankChangeType)))); break; } player.Message("SetInfo: RankChangeType for {0}&S changed from {1} to {2}", info.ClassyName, oldType, info.RankChangeType); break; case "rankreason": if (valName.Length == 0) { valName = null; } if (SetPlayerInfoField(player, "RankReason", info, info.RankChangeReason, valName)) { info.RankChangeReason = valName; } break; case "timeskicked": int oldTimesKicked = info.TimesKicked; if (ValidateInt(valName, 0, 9999)) { info.TimesKicked = Int32.Parse(valName); player.Message("SetInfo: TimesKicked for {0}&S changed from {1} to {2}", info.ClassyName, oldTimesKicked, info.TimesKicked); } else { player.Message("SetInfo: TimesKicked value out of range (Acceptable value range: 0-9999)"); } break; case "totaltime": TimeSpan newTotalTime; TimeSpan oldTotalTime = info.TotalTime; if (valName.TryParseMiniTimespan(out newTotalTime)) { if (newTotalTime > DateTimeUtil.MaxTimeSpan) { player.MessageMaxTimeSpan(); break; } info.TotalTime = newTotalTime; player.Message("SetInfo: TotalTime for {0}&S changed from {1} ({2}) to {3} ({4})", info.ClassyName, oldTotalTime.ToMiniString(), oldTotalTime.ToCompactString(), info.TotalTime.ToMiniString(), info.TotalTime.ToCompactString()); } else { player.Message("SetInfo: Could not parse value given for TotalTime."); } break; case "unbanreason": if (valName.Length == 0) { valName = null; } if (SetPlayerInfoField(player, "UnbanReason", info, info.UnbanReason, valName)) { info.UnbanReason = valName; } break; default: player.Message("Only the following properties are editable: " + "TimesKicked, PreviousRank, TotalTime, RankChangeType, " + "BanReason, UnbanReason, RankReason, KickReason, DisplayedName"); return; } }
static void ImportBans(Player player, CommandReader cmd) { string serverName = cmd.Next(); string fileName = cmd.Next(); // Make sure all parameters are specified if (serverName == null || fileName == null) { CdImport.PrintUsage(player); return; } // Check if file exists if (!File.Exists(fileName)) { player.Message("File not found: {0}", fileName); return; } string[] names; switch (serverName.ToLower()) { case "mcsharp": case "mczall": case "mclawl": try { names = File.ReadAllLines(fileName); } catch (Exception ex) { Logger.Log(LogType.Error, "Could not open \"{0}\" to import bans: {1}", fileName, ex); return; } break; default: player.Message("fCraft does not support importing from {0}", serverName); return; } if (!cmd.IsConfirmed) { player.Confirm(cmd, "Import {0} bans from \"{1}\"?", names.Length, Path.GetFileName(fileName)); return; } string reason = "(import from " + serverName + ")"; foreach (string name in names) { if (Player.IsValidName(name)) { PlayerInfo info = PlayerDB.FindExact(name) ?? PlayerDB.AddUnrecognizedPlayer(name, RankChangeType.Default); info.Ban(player, reason, true, true); } else { IPAddress ip; if (IPAddressUtil.IsIP(name) && IPAddress.TryParse(name, out ip)) { ip.BanIP(player, reason, true, true); } else { player.Message("Could not parse \"{0}\" as either name or IP. Skipping.", name); } } } PlayerDB.Save(); IPBanList.Save(); }
static void MirrorHandler([NotNull] Player player, [NotNull] CommandReader cmd) { CopyState originalInfo = player.GetCopyState(); if (originalInfo == null) { player.MessageNow("Nothing to flip! Copy something first."); return; } // clone to avoid messing up any paste-in-progress CopyState info = new CopyState(originalInfo); bool flipX = false, flipY = false, flipH = false; string axis; while ((axis = cmd.Next()) != null) { foreach (char c in axis.ToLower()) { if (c == 'x') { flipX = true; } if (c == 'y') { flipY = true; } if (c == 'z') { flipH = true; } } } if (!flipX && !flipY && !flipH) { CdMirror.PrintUsage(player); return; } Block block; if (flipX) { int left = 0; int right = info.Bounds.Width - 1; while (left < right) { for (int y = info.Bounds.Length - 1; y >= 0; y--) { for (int z = info.Bounds.Height - 1; z >= 0; z--) { block = info.Blocks[left, y, z]; info.Blocks[left, y, z] = info.Blocks[right, y, z]; info.Blocks[right, y, z] = block; } } left++; right--; } } if (flipY) { int left = 0; int right = info.Bounds.Length - 1; while (left < right) { for (int x = info.Bounds.Width - 1; x >= 0; x--) { for (int z = info.Bounds.Height - 1; z >= 0; z--) { block = info.Blocks[x, left, z]; info.Blocks[x, left, z] = info.Blocks[x, right, z]; info.Blocks[x, right, z] = block; } } left++; right--; } } if (flipH) { int left = 0; int right = info.Bounds.Height - 1; while (left < right) { for (int x = info.Bounds.Width - 1; x >= 0; x--) { for (int y = info.Bounds.Length - 1; y >= 0; y--) { block = info.Blocks[x, y, left]; info.Blocks[x, y, left] = info.Blocks[x, y, right]; info.Blocks[x, y, right] = block; } } left++; right--; } } if (flipX) { if (flipY) { if (flipH) { player.Message("Flipped copy along all axes."); } else { player.Message("Flipped copy along X (east/west) and Y (north/south) axes."); } } else { if (flipH) { player.Message("Flipped copy along X (east/west) and Z (vertical) axes."); } else { player.Message("Flipped copy along X (east/west) axis."); } } } else { if (flipY) { if (flipH) { player.Message("Flipped copy along Y (north/south) and Z (vertical) axes."); } else { player.Message("Flipped copy along Y (north/south) axis."); } } else { player.Message("Flipped copy along Z (vertical) axis."); } } player.SetCopyState(info); }
static BlockDBUndoArgs ParseBlockDBUndoParams( Player player, CommandReader cmd, string cmdName, bool not ) { // check if command's being called by a worldless player (e.g. console) World playerWorld = player.World; if( playerWorld == null ) PlayerOpException.ThrowNoWorld( player ); // ensure that BlockDB is enabled if( !BlockDB.IsEnabledGlobally ) { player.Message( "&W{0}: BlockDB is disabled on this server.", cmdName ); return null; } if( !playerWorld.BlockDB.IsEnabled ) { player.Message( "&W{0}: BlockDB is disabled in this world.", cmdName ); return null; } // parse the first parameter - either numeric or time limit string range = cmd.Next(); if( range == null ) { CdUndoPlayer.PrintUsage( player ); return null; } int countLimit; TimeSpan ageLimit = TimeSpan.Zero; if( !Int32.TryParse( range, out countLimit ) && !range.TryParseMiniTimeSpan( out ageLimit ) ) { player.Message( "{0}: First parameter should be a number or a timespan.", cmdName ); return null; } if( ageLimit > DateTimeUtil.MaxTimeSpan ) { player.MessageMaxTimeSpan(); return null; } // parse second and consequent parameters (player names) HashSet<PlayerInfo> targets = new HashSet<PlayerInfo>(); bool allPlayers = false; while( true ) { string name = cmd.Next(); if( name == null ) { break; } else if( name == "*" ) { // all players if( not ) { player.Message( "{0}: \"*\" not allowed (cannot undo \"everyone except everyone\")", cmdName ); return null; } if( allPlayers ) { player.Message( "{0}: \"*\" was listed twice.", cmdName ); return null; } allPlayers = true; } else { // individual player PlayerInfo target = PlayerDB.FindPlayerInfoOrPrintMatches( player, name, SearchOptions.IncludeSelf ); if( target == null ) { return null; } if( targets.Contains( target ) ) { player.Message( "{0}: Player {1}&S was listed twice.", target.ClassyName, cmdName ); return null; } // make sure player has the permission if( !not && player.Info != target && !player.Can( Permission.UndoAll ) && !player.Can( Permission.UndoOthersActions, target.Rank ) ) { player.Message( "&W{0}: You may only undo actions of players ranked {1}&S or lower.", cmdName, player.Info.Rank.GetLimit( Permission.UndoOthersActions ).ClassyName ); player.Message( "Player {0}&S is ranked {1}", target.ClassyName, target.Rank.ClassyName ); return null; } targets.Add( target ); } } if( targets.Count == 0 && !allPlayers ) { player.Message( "{0}: Specify at least one player name, or \"*\" to undo everyone.", cmdName ); return null; } if( targets.Count > 0 && allPlayers ) { player.Message( "{0}: Cannot mix player names and \"*\".", cmdName ); return null; } // undoing everyone ('*' in place of player name) requires UndoAll permission if( ( not || allPlayers ) && !player.Can( Permission.UndoAll ) ) { player.MessageNoAccess( Permission.UndoAll ); return null; } // Queue UndoPlayerCallback to run return new BlockDBUndoArgs { Player = player, AgeLimit = ageLimit, CountLimit = countLimit, Area = player.WorldMap.Bounds, World = playerWorld, Targets = targets.ToArray(), Not = not }; }
static void RotateHandler( Player player, CommandReader cmd ) { CopyState originalInfo = player.GetCopyState(); if( originalInfo == null ) { player.MessageNow( "Nothing to rotate! Copy something first." ); return; } int degrees; if( !cmd.NextInt( out degrees ) || (degrees != 90 && degrees != -90 && degrees != 180 && degrees != 270) ) { CdRotate.PrintUsage( player ); return; } string axisName = cmd.Next(); Axis axis = Axis.Z; if( axisName != null ) { switch( axisName.ToLower() ) { case "x": axis = Axis.X; break; case "y": axis = Axis.Y; break; case "z": case "h": axis = Axis.Z; break; default: CdRotate.PrintUsage( player ); return; } } // allocate the new buffer Block[, ,] oldBuffer = originalInfo.Blocks; Block[, ,] newBuffer; if( degrees == 180 ) { newBuffer = new Block[oldBuffer.GetLength( 0 ), oldBuffer.GetLength( 1 ), oldBuffer.GetLength( 2 )]; } else if( axis == Axis.X ) { newBuffer = new Block[oldBuffer.GetLength( 0 ), oldBuffer.GetLength( 2 ), oldBuffer.GetLength( 1 )]; } else if( axis == Axis.Y ) { newBuffer = new Block[oldBuffer.GetLength( 2 ), oldBuffer.GetLength( 1 ), oldBuffer.GetLength( 0 )]; } else { // axis == Axis.Z newBuffer = new Block[oldBuffer.GetLength( 1 ), oldBuffer.GetLength( 0 ), oldBuffer.GetLength( 2 )]; } // clone to avoid messing up any paste-in-progress CopyState info = new CopyState( originalInfo, newBuffer ); // construct the rotation matrix int[,] matrix = { {1,0,0}, {0,1,0}, {0,0,1} }; int a, b; switch( axis ) { case Axis.X: a = 1; b = 2; break; case Axis.Y: a = 0; b = 2; break; default: a = 0; b = 1; break; } switch( degrees ) { case 90: matrix[a, a] = 0; matrix[b, b] = 0; matrix[a, b] = -1; matrix[b, a] = 1; break; case 180: matrix[a, a] = -1; matrix[b, b] = -1; break; case -90: case 270: matrix[a, a] = 0; matrix[b, b] = 0; matrix[a, b] = 1; matrix[b, a] = -1; break; } // apply the rotation matrix for( int x = oldBuffer.GetLength( 0 ) - 1; x >= 0; x-- ) { for( int y = oldBuffer.GetLength( 1 ) - 1; y >= 0; y-- ) { for( int z = oldBuffer.GetLength( 2 ) - 1; z >= 0; z-- ) { int nx = (matrix[0, 0] < 0 ? oldBuffer.GetLength( 0 ) - 1 - x : (matrix[0, 0] > 0 ? x : 0)) + (matrix[0, 1] < 0 ? oldBuffer.GetLength( 1 ) - 1 - y : (matrix[0, 1] > 0 ? y : 0)) + (matrix[0, 2] < 0 ? oldBuffer.GetLength( 2 ) - 1 - z : (matrix[0, 2] > 0 ? z : 0)); int ny = (matrix[1, 0] < 0 ? oldBuffer.GetLength( 0 ) - 1 - x : (matrix[1, 0] > 0 ? x : 0)) + (matrix[1, 1] < 0 ? oldBuffer.GetLength( 1 ) - 1 - y : (matrix[1, 1] > 0 ? y : 0)) + (matrix[1, 2] < 0 ? oldBuffer.GetLength( 2 ) - 1 - z : (matrix[1, 2] > 0 ? z : 0)); int nz = (matrix[2, 0] < 0 ? oldBuffer.GetLength( 0 ) - 1 - x : (matrix[2, 0] > 0 ? x : 0)) + (matrix[2, 1] < 0 ? oldBuffer.GetLength( 1 ) - 1 - y : (matrix[2, 1] > 0 ? y : 0)) + (matrix[2, 2] < 0 ? oldBuffer.GetLength( 2 ) - 1 - z : (matrix[2, 2] > 0 ? z : 0)); newBuffer[nx, ny, nz] = oldBuffer[x, y, z]; } } } player.Message( "Rotated copy (slot {0}) by {1} degrees around {2} axis.", info.Slot + 1, degrees, axis ); player.SetCopyState( info ); }
static void RulesHandler( Player player, CommandReader cmd ) { string sectionName = cmd.Next(); // if no section name is given if( sectionName == null ) { FileInfo ruleFile = new FileInfo( Paths.RulesFileName ); if( ruleFile.Exists ) { PrintRuleFile( player, ruleFile ); } else { player.Message( DefaultRules ); } // print a list of available sections string[] sections = GetRuleSectionList(); if( sections != null ) { player.Message( "Rule sections: {0}. Type &H/Rules SectionName&S to read.", sections.JoinToString() ); } return; } // if a section name is given, but no section files exist if( !Directory.Exists( Paths.RulesPath ) ) { player.Message( "There are no rule sections defined." ); return; } string ruleFileName = null; string[] sectionFiles = Directory.GetFiles( Paths.RulesPath, "*.txt", SearchOption.TopDirectoryOnly ); for( int i = 0; i < sectionFiles.Length; i++ ) { string sectionFullName = Path.GetFileNameWithoutExtension( sectionFiles[i] ); if( sectionFullName == null ) continue; if( sectionFullName.StartsWith( sectionName, StringComparison.OrdinalIgnoreCase ) ) { if( sectionFullName.Equals( sectionName, StringComparison.OrdinalIgnoreCase ) ) { // if there is an exact match, break out of the loop early ruleFileName = sectionFiles[i]; break; } else if( ruleFileName == null ) { // if there is a partial match, keep going to check for multiple matches ruleFileName = sectionFiles[i]; } else { var matches = sectionFiles.Select( Path.GetFileNameWithoutExtension ) .Where( sn => sn != null && sn.StartsWith( sectionName, StringComparison.OrdinalIgnoreCase ) ); // if there are multiple matches, print a list player.Message( "Multiple rule sections matched \"{0}\": {1}", sectionName, matches.JoinToString() ); return; } } } if( ruleFileName != null ) { string sectionFullName = Path.GetFileNameWithoutExtension( ruleFileName ); player.Message( "Rule section \"{0}\":", sectionFullName ); PrintRuleFile( player, new FileInfo( ruleFileName ) ); } else { var sectionList = GetRuleSectionList(); if( sectionList == null ) { player.Message( "There are no rule sections defined." ); } else { player.Message( "No rule section defined for \"{0}\". Available sections: {1}", sectionName, sectionList.JoinToString() ); } } }
static void WhereHandler( Player player, CommandReader cmd ) { string name = cmd.Next(); if( cmd.HasNext ) { CdWhere.PrintUsage( player ); return; } Player target = player; if( name != null ) { if( !player.Can( Permission.ViewOthersInfo ) ) { player.MessageNoAccess( Permission.ViewOthersInfo ); return; } target = Server.FindPlayerOrPrintMatches( player, name, false, true ); if( target == null ) return; } else if( target.World == null ) { player.Message( "When called from console, &H/Where&S requires a player name." ); return; } if( target.World == null ) { // Chances of this happening are miniscule player.Message( "Player {0}&S is not in any world.", target.Name ); return; } else { player.Message( "Player {0}&S is on world {1}&S:", target.ClassyName, target.World.ClassyName ); } Vector3I targetBlockCoords = target.Position.ToBlockCoords(); player.Message( "{0}{1} - {2}", Color.Silver, targetBlockCoords, GetCompassString( target.Position.R ) ); }
// Shows general information about a particular rank. static void RankInfoHandler( Player player, CommandReader cmd ) { Rank rank; string rankName = cmd.Next(); if( cmd.HasNext ) { CdRankInfo.PrintUsage( player ); return; } if( rankName == null ) { rank = player.Info.Rank; } else { rank = RankManager.FindRank( rankName ); if( rank == null ) { player.MessageNoRank( rankName ); return; } } List<Permission> permissions = new List<Permission>(); for( int i = 0; i < rank.Permissions.Length; i++ ) { if( rank.Permissions[i] ) { permissions.Add( (Permission)i ); } } Permission[] sortedPermissionNames = permissions.OrderBy( s => s.ToString(), StringComparer.OrdinalIgnoreCase ).ToArray(); { StringBuilder sb = new StringBuilder(); sb.AppendFormat( "Players of rank {0}&S can: ", rank.ClassyName ); bool first = true; for( int i = 0; i < sortedPermissionNames.Length; i++ ) { Permission p = sortedPermissionNames[i]; if( !first ) sb.Append( ',' ).Append( ' ' ); Rank permissionLimit = rank.PermissionLimits[(int)p]; sb.Append( p ); if( permissionLimit != null ) { sb.AppendFormat( "({0}&S)", permissionLimit.ClassyName ); } first = false; } player.Message( sb.ToString() ); } if( rank.Can( Permission.Draw ) ) { StringBuilder sb = new StringBuilder(); if( rank.DrawLimit > 0 ) { sb.AppendFormat( "Draw limit: {0} blocks.", rank.DrawLimit ); } else { sb.AppendFormat( "Draw limit: None (unlimited)." ); } if( rank.Can( Permission.CopyAndPaste ) ) { sb.AppendFormat( " Copy/paste slots: {0}", rank.CopySlots ); } player.Message( sb.ToString() ); } if( rank.IdleKickTimer > 0 ) { player.Message( "Idle kick after {0}", TimeSpan.FromMinutes( rank.IdleKickTimer ).ToMiniString() ); } }
static void HelpHandler( Player player, CommandReader cmd ) { string commandName = cmd.Next(); if( commandName != null ) { CommandDescriptor descriptor = CommandManager.GetDescriptor( commandName, true ); if( descriptor == null ) { player.Message( "Unknown command: \"{0}\"", commandName ); return; } string sectionName = cmd.Next(); if( sectionName != null ) { string sectionHelp; if( descriptor.HelpSections != null && descriptor.HelpSections.TryGetValue( sectionName.ToLower(), out sectionHelp ) ) { player.MessagePrefixed( HelpPrefix, sectionHelp ); } else { player.Message( "No help found for \"{0}\"", sectionName ); } } else { StringBuilder sb = new StringBuilder( Color.Help ); sb.Append( descriptor.Usage ) .Append( "\n&S" ); if( descriptor.Aliases != null ) { sb.AppendFormat( "Aliases: &H{0}\n&S", descriptor.Aliases.JoinToString() ); } if( String.IsNullOrEmpty( descriptor.Help ) ) { sb.Append( "No help is available for this command." ); } else { sb.Append( descriptor.Help ); } if( descriptor.Permissions != null && descriptor.Permissions.Length > 0 ) { Rank minRank = descriptor.MinRank; if( minRank == null ) { sb.Append( "\nNot available to any rank" ); } else { sb.AppendFormat( "\nAvailable to {0}&S+", minRank.ClassyName ); } sb.AppendFormat( " (permissions: {0})", descriptor.Permissions.JoinToString() ); } else { sb.Append( "\nAvailable to players of all ranks." ); } player.MessagePrefixed( HelpPrefix, sb.ToString() ); } } else { player.Message( " To see a list of all commands, write &H/Commands" ); player.Message( " To see detailed help for a command, write &H/Help Command" ); if( player != Player.Console ) { player.Message( " To see your stats, write &H/Info" ); } player.Message( " To list available worlds, write &H/Worlds" ); player.Message( " To join a world, write &H/Join WorldName" ); player.Message( " To send private messages, write &H@PlayerName Message" ); } }
static void ZoneEditHandler(Player player, CommandReader cmd) { if (player.World == null) { PlayerOpException.ThrowNoWorld(player); } bool changesWereMade = false; string zoneName = cmd.Next(); if (zoneName == null) { player.Message("No zone name specified. See &H/Help ZEdit"); return; } Zone zone = player.WorldMap.Zones.Find(zoneName); if (zone == null) { player.MessageNoZone(zoneName); return; } string nextToken; while ((nextToken = cmd.Next()) != null) { // Clear whitelist if (nextToken.Equals("-*")) { PlayerInfo[] oldWhitelist = zone.Controller.ExceptionList.Included; if (oldWhitelist.Length > 0) { zone.Controller.ResetIncludedList(); player.Message("Whitelist of zone {0}&S cleared: {1}", zone.ClassyName, oldWhitelist.JoinToClassyString()); Logger.Log(LogType.UserActivity, "Player {0} cleared whitelist of zone {1} on world {2}: {3}", player.Name, zone.Name, player.World.Name, oldWhitelist.JoinToString(pi => pi.Name)); } else { player.Message("Whitelist of zone {0}&S is empty.", zone.ClassyName); } continue; } // Clear blacklist if (nextToken.Equals("+*")) { PlayerInfo[] oldBlacklist = zone.Controller.ExceptionList.Excluded; if (oldBlacklist.Length > 0) { zone.Controller.ResetExcludedList(); player.Message("Blacklist of zone {0}&S cleared: {1}", zone.ClassyName, oldBlacklist.JoinToClassyString()); Logger.Log(LogType.UserActivity, "Player {0} cleared blacklist of zone {1} on world {2}: {3}", player.Name, zone.Name, player.World.Name, oldBlacklist.JoinToString(pi => pi.Name)); } else { player.Message("Blacklist of zone {0}&S is empty.", zone.ClassyName); } continue; } if (nextToken.StartsWith("+")) { PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches(player, nextToken.Substring(1)); if (info == null) { return; } // prevent players from whitelisting themselves to bypass protection if (!player.Info.Rank.AllowSecurityCircumvention && player.Info == info) { switch (zone.Controller.CheckDetailed(info)) { case SecurityCheckResult.BlackListed: player.Message("You are not allowed to remove yourself from the blacklist of zone {0}", zone.ClassyName); continue; case SecurityCheckResult.RankTooLow: player.Message("You must be {0}+&S to add yourself to the whitelist of zone {1}", zone.Controller.MinRank.ClassyName, zone.ClassyName); continue; } } switch (zone.Controller.Include(info)) { case PermissionOverride.Deny: player.Message("{0}&S is no longer excluded from zone {1}", info.ClassyName, zone.ClassyName); changesWereMade = true; break; case PermissionOverride.None: player.Message("{0}&S is now included in zone {1}", info.ClassyName, zone.ClassyName); changesWereMade = true; break; case PermissionOverride.Allow: player.Message("{0}&S is already included in zone {1}", info.ClassyName, zone.ClassyName); break; } } else if (nextToken.StartsWith("-")) { PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches(player, nextToken.Substring(1)); if (info == null) { return; } switch (zone.Controller.Exclude(info)) { case PermissionOverride.Deny: player.Message("{0}&S is already excluded from zone {1}", info.ClassyName, zone.ClassyName); break; case PermissionOverride.None: player.Message("{0}&S is now excluded from zone {1}", info.ClassyName, zone.ClassyName); changesWereMade = true; break; case PermissionOverride.Allow: player.Message("{0}&S is no longer included in zone {1}", info.ClassyName, zone.ClassyName); changesWereMade = true; break; } } else { Rank minRank = RankManager.FindRank(nextToken); if (minRank != null) { // prevent players from lowering rank so bypass protection if (!player.Info.Rank.AllowSecurityCircumvention && zone.Controller.MinRank > player.Info.Rank && minRank <= player.Info.Rank) { player.Message("You are not allowed to lower the zone's rank."); continue; } if (zone.Controller.MinRank != minRank) { zone.Controller.MinRank = minRank; player.Message("Permission for zone \"{0}\" changed to {1}+", zone.Name, minRank.ClassyName); changesWereMade = true; } } else { player.MessageNoRank(nextToken); } } if (changesWereMade) { zone.Edit(player.Info); } else { player.Message("No changes were made to the zone."); } } }
static void BanInfoHandler( Player player, CommandReader cmd ) { string name = cmd.Next(); if( cmd.HasNext ) { CdBanInfo.PrintUsage( player ); return; } IPAddress address; PlayerInfo info = null; if( name == null ) { name = player.Name; } else if( !player.Can( Permission.ViewOthersInfo ) ) { player.MessageNoAccess( Permission.ViewOthersInfo ); return; } if( IPAddressUtil.IsIP( name ) && IPAddress.TryParse( name, out address ) ) { IPBanInfo banInfo = IPBanList.Get( address ); if( banInfo != null ) { player.Message( "{0} was banned by {1}&S on {2:dd MMM yyyy} ({3} ago)", banInfo.Address, banInfo.BannedByClassy, banInfo.BanDate, banInfo.TimeSinceLastAttempt ); if( !String.IsNullOrEmpty( banInfo.PlayerName ) ) { player.Message( " Banned by association with {0}", banInfo.PlayerNameClassy ); } if( banInfo.Attempts > 0 ) { player.Message( " There have been {0} attempts to log in, most recently {1} ago by {2}", banInfo.Attempts, banInfo.TimeSinceLastAttempt.ToMiniString(), banInfo.LastAttemptNameClassy ); } if( banInfo.BanReason != null ) { player.Message( " Ban reason: {0}", banInfo.BanReason ); } } else { player.Message( "{0} is currently NOT banned.", address ); } } else { info = PlayerDB.FindPlayerInfoOrPrintMatches( player, name ); if( info == null ) return; address = info.LastIP; IPBanInfo ipBan = IPBanList.Get( info.LastIP ); switch( info.BanStatus ) { case BanStatus.Banned: if( ipBan != null ) { player.Message( "Player {0}&S and their IP are &CBANNED", info.ClassyName ); } else { player.Message( "Player {0}&S is &CBANNED&S (but their IP is not).", info.ClassyName ); } break; case BanStatus.IPBanExempt: if( ipBan != null ) { player.Message( "Player {0}&S is exempt from an existing IP ban.", info.ClassyName ); } else { player.Message( "Player {0}&S is exempt from IP bans.", info.ClassyName ); } break; case BanStatus.NotBanned: if( ipBan != null ) { player.Message( "Player {0}&s is not banned, but their IP is.", info.ClassyName ); } else { player.Message( "Player {0}&s is not banned.", info.ClassyName ); } break; } if( info.BanDate != DateTime.MinValue ) { player.Message( " Last ban by {0}&S on {1:dd MMM yyyy} ({2} ago).", info.BannedByClassy, info.BanDate, info.TimeSinceBan.ToMiniString() ); if( info.BanReason != null ) { player.Message( " Last ban reason: {0}", info.BanReason ); } } else { player.Message( "No past bans on record." ); } if( info.UnbanDate != DateTime.MinValue && !info.IsBanned ) { player.Message( " Unbanned by {0}&S on {1:dd MMM yyyy} ({2} ago).", info.UnbannedByClassy, info.UnbanDate, info.TimeSinceUnban.ToMiniString() ); if( info.UnbanReason != null ) { player.Message( " Last unban reason: {0}", info.UnbanReason ); } } if( info.BanDate != DateTime.MinValue ) { TimeSpan banDuration; if( info.IsBanned ) { banDuration = info.TimeSinceBan; player.Message( " Ban duration: {0} so far", banDuration.ToMiniString() ); } else { banDuration = info.UnbanDate.Subtract( info.BanDate ); player.Message( " Previous ban's duration: {0}", banDuration.ToMiniString() ); } } } // Show alts if( !address.Equals( IPAddress.None ) ) { List<PlayerInfo> altNames = new List<PlayerInfo>(); int bannedAltCount = 0; foreach( PlayerInfo playerFromSameIP in PlayerDB.FindPlayers( address ) ) { if( playerFromSameIP == info ) continue; altNames.Add( playerFromSameIP ); if( playerFromSameIP.IsBanned ) { bannedAltCount++; } } if( altNames.Count > 0 ) { altNames.Sort( new PlayerInfoComparer( player ) ); if( altNames.Count > MaxAltsToPrint ) { if( bannedAltCount > 0 ) { player.MessagePrefixed( "&S ", "&S Over {0} accounts ({1} banned) on IP: {2} &Setc", MaxAltsToPrint, bannedAltCount, altNames.Take( 15 ).ToArray().JoinToClassyString() ); } else { player.MessagePrefixed( "&S ", "&S Over {0} accounts on IP: {1} &Setc", MaxAltsToPrint, altNames.Take( 15 ).ToArray().JoinToClassyString() ); } } else { if( bannedAltCount > 0 ) { player.MessagePrefixed( "&S ", "&S {0} accounts ({1} banned) on IP: {2}", altNames.Count, bannedAltCount, altNames.ToArray().JoinToClassyString() ); } else { player.MessagePrefixed( "&S ", "&S {0} accounts on IP: {1}", altNames.Count, altNames.ToArray().JoinToClassyString() ); } } } } }
static void ZoneAddHandler(Player player, CommandReader cmd) { World playerWorld = player.World; if (playerWorld == null) { PlayerOpException.ThrowNoWorld(player); } string givenZoneName = cmd.Next(); if (givenZoneName == null) { CdZoneAdd.PrintUsage(player); return; } if (!player.Info.Rank.AllowSecurityCircumvention) { SecurityCheckResult buildCheck = playerWorld.BuildSecurity.CheckDetailed(player.Info); switch (buildCheck) { case SecurityCheckResult.BlackListed: player.Message("Cannot add zones to world {0}&S: You are barred from building here.", playerWorld.ClassyName); return; case SecurityCheckResult.RankTooLow: player.Message("Cannot add zones to world {0}&S: You are not allowed to build here.", playerWorld.ClassyName); return; } } Zone newZone = new Zone(); ZoneCollection zoneCollection = player.WorldMap.Zones; if (givenZoneName.StartsWith("+")) { // personal zone (/ZAdd +Name) givenZoneName = givenZoneName.Substring(1); // Find the target player PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches(player, givenZoneName); if (info == null) { return; } // Make sure that the name is not taken already. // If a zone named after the player already exists, try adding a number after the name (e.g. "Notch2") newZone.Name = info.Name; for (int i = 2; zoneCollection.Contains(newZone.Name); i++) { newZone.Name = givenZoneName + i; } newZone.Controller.MinRank = info.Rank.NextRankUp ?? info.Rank; newZone.Controller.Include(info); player.Message("ZoneAdd: Creating a {0}+&S zone for player {1}&S. Click or &H/Mark&S 2 blocks.", newZone.Controller.MinRank.ClassyName, info.ClassyName); player.SelectionStart(2, ZoneAddCallback, newZone, CdZoneAdd.Permissions); } else { // Adding an ordinary, rank-restricted zone. if (!World.IsValidName(givenZoneName)) { player.Message("\"{0}\" is not a valid zone name", givenZoneName); return; } if (zoneCollection.Contains(givenZoneName)) { player.Message("A zone with this name already exists. Use &H/ZEdit&S to edit."); return; } newZone.Name = givenZoneName; string rankName = cmd.Next(); if (rankName == null) { player.Message("No rank was specified. See &H/Help zone"); return; } Rank minRank = RankManager.FindRank(rankName); if (minRank == null) { player.MessageNoRank(rankName); return; } string name; while ((name = cmd.Next()) != null) { if (name.Length < 1) { CdZoneAdd.PrintUsage(player); return; } PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches(player, name.Substring(1)); if (info == null) { return; } if (name.StartsWith("+")) { newZone.Controller.Include(info); } else if (name.StartsWith("-")) { newZone.Controller.Exclude(info); } } newZone.Controller.MinRank = minRank; player.SelectionStart(2, ZoneAddCallback, newZone, CdZoneAdd.Permissions); player.Message("ZoneAdd: Creating zone {0}&S. Click or &H/Mark&S 2 blocks.", newZone.ClassyName); } }
static void InfoHandler( Player player, CommandReader cmd ) { string name = cmd.Next(); if( name == null ) { // no name given, print own info PrintPlayerInfo( player, player.Info ); return; } else if( name.Equals( player.Name, StringComparison.OrdinalIgnoreCase ) ) { // own name given player.LastUsedPlayerName = player.Name; PrintPlayerInfo( player, player.Info ); return; } else if( !player.Can( Permission.ViewOthersInfo ) ) { // someone else's name or IP given, permission required. player.MessageNoAccess( Permission.ViewOthersInfo ); return; } // repeat last-typed name if( name == "-" ) { if( player.LastUsedPlayerName != null ) { name = player.LastUsedPlayerName; } else { player.Message( "Cannot repeat player name: you haven't used any names yet." ); return; } } PlayerInfo[] infos; IPAddress ip; if( name.Contains( "/" ) ) { // IP range matching (CIDR notation) string ipString = name.Substring( 0, name.IndexOf( '/' ) ); string rangeString = name.Substring( name.IndexOf( '/' ) + 1 ); byte range; if( IPAddressUtil.IsIP( ipString ) && IPAddress.TryParse( ipString, out ip ) && Byte.TryParse( rangeString, out range ) && range <= 32 ) { player.Message( "Searching {0}-{1}", ip.RangeMin( range ), ip.RangeMax( range ) ); infos = PlayerDB.FindPlayersCidr( ip, range ); } else { player.Message( "Info: Invalid IP range format. Use CIDR notation." ); return; } } else if( IPAddressUtil.IsIP( name ) && IPAddress.TryParse( name, out ip ) ) { // find players by IP infos = PlayerDB.FindPlayers( ip ); } else if( name.Equals( "*" ) ) { infos = (PlayerInfo[])PlayerDB.PlayerInfoList.Clone(); } else if( name.Contains( "*" ) || name.Contains( "?" ) ) { // find players by regex/wildcard string regexString = "^" + RegexNonNameChars.Replace( name, "" ).Replace( "*", ".*" ).Replace( "?", "." ) + "$"; Regex regex = new Regex( regexString, RegexOptions.IgnoreCase | RegexOptions.Compiled ); infos = PlayerDB.FindPlayers( regex ); } else if( name.StartsWith( "@" ) ) { string rankName = name.Substring( 1 ); Rank rank = RankManager.FindRank( rankName ); if( rank == null ) { player.MessageNoRank( rankName ); return; } else { infos = PlayerDB.PlayerInfoList .Where( info => info.Rank == rank ) .ToArray(); } } else if( name.StartsWith( "!" ) ) { // find online players by partial matches name = name.Substring( 1 ); infos = Server.FindPlayers( name, true ) .Select( p => p.Info ) .ToArray(); } else { // find players by partial matching PlayerInfo tempInfo; if( !PlayerDB.FindPlayerInfo( name, out tempInfo ) ) { infos = PlayerDB.FindPlayers( name ); } else if( tempInfo == null ) { player.MessageNoPlayer( name ); return; } else { infos = new[] { tempInfo }; } } Array.Sort( infos, new PlayerInfoComparer( player ) ); if( infos.Length == 1 ) { // only one match found; print it right away player.LastUsedPlayerName = infos[0].Name; PrintPlayerInfo( player, infos[0] ); } else if( infos.Length > 1 ) { // multiple matches found if( infos.Length <= PlayersPerPage ) { // all fit to one page player.MessageManyMatches( "player", infos ); } else { // pagination int offset; if( !cmd.NextInt( out offset ) ) offset = 0; if( offset >= infos.Length ) { offset = Math.Max( 0, infos.Length - PlayersPerPage ); } PlayerInfo[] infosPart = infos.Skip( offset ).Take( PlayersPerPage ).ToArray(); player.MessageManyMatches( "player", infosPart ); if( offset + infosPart.Length < infos.Length ) { // normal page player.Message( "Showing {0}-{1} (out of {2}). Next: &H/Info {3} {4}", offset + 1, offset + infosPart.Length, infos.Length, name, offset + infosPart.Length ); } else { // last page player.Message( "Showing matches {0}-{1} (out of {2}).", offset + 1, offset + infosPart.Length, infos.Length ); } } } else { // no matches found player.MessageNoPlayer( name ); } }
static void RotateHandler([NotNull] Player player, [NotNull] CommandReader cmd) { CopyState originalInfo = player.GetCopyState(); if (originalInfo == null) { player.MessageNow("Nothing to rotate! Copy something first."); return; } int degrees; if (!cmd.NextInt(out degrees) || (degrees != 90 && degrees != -90 && degrees != 180 && degrees != 270)) { CdRotate.PrintUsage(player); return; } string axisName = cmd.Next(); Axis axis = Axis.Z; if (axisName != null) { switch (axisName.ToLower()) { case "x": axis = Axis.X; break; case "y": axis = Axis.Y; break; case "z": case "h": axis = Axis.Z; break; default: CdRotate.PrintUsage(player); return; } } // allocate the new buffer Block[,,] oldBuffer = originalInfo.Blocks; Block[,,] newBuffer; if (degrees == 180) { newBuffer = new Block[oldBuffer.GetLength(0), oldBuffer.GetLength(1), oldBuffer.GetLength(2)]; } else if (axis == Axis.X) { newBuffer = new Block[oldBuffer.GetLength(0), oldBuffer.GetLength(2), oldBuffer.GetLength(1)]; } else if (axis == Axis.Y) { newBuffer = new Block[oldBuffer.GetLength(2), oldBuffer.GetLength(1), oldBuffer.GetLength(0)]; } else { // axis == Axis.Z newBuffer = new Block[oldBuffer.GetLength(1), oldBuffer.GetLength(0), oldBuffer.GetLength(2)]; } // clone to avoid messing up any paste-in-progress CopyState info = new CopyState(originalInfo, newBuffer); // construct the rotation matrix int[,] matrix = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }; int a, b; switch (axis) { case Axis.X: a = 1; b = 2; break; case Axis.Y: a = 0; b = 2; break; default: a = 0; b = 1; break; } switch (degrees) { case 90: matrix[a, a] = 0; matrix[b, b] = 0; matrix[a, b] = -1; matrix[b, a] = 1; break; case 180: matrix[a, a] = -1; matrix[b, b] = -1; break; case -90: case 270: matrix[a, a] = 0; matrix[b, b] = 0; matrix[a, b] = 1; matrix[b, a] = -1; break; } // apply the rotation matrix for (int x = oldBuffer.GetLength(0) - 1; x >= 0; x--) { for (int y = oldBuffer.GetLength(1) - 1; y >= 0; y--) { for (int z = oldBuffer.GetLength(2) - 1; z >= 0; z--) { int nx = (matrix[0, 0] < 0 ? oldBuffer.GetLength(0) - 1 - x : (matrix[0, 0] > 0 ? x : 0)) + (matrix[0, 1] < 0 ? oldBuffer.GetLength(1) - 1 - y : (matrix[0, 1] > 0 ? y : 0)) + (matrix[0, 2] < 0 ? oldBuffer.GetLength(2) - 1 - z : (matrix[0, 2] > 0 ? z : 0)); int ny = (matrix[1, 0] < 0 ? oldBuffer.GetLength(0) - 1 - x : (matrix[1, 0] > 0 ? x : 0)) + (matrix[1, 1] < 0 ? oldBuffer.GetLength(1) - 1 - y : (matrix[1, 1] > 0 ? y : 0)) + (matrix[1, 2] < 0 ? oldBuffer.GetLength(2) - 1 - z : (matrix[1, 2] > 0 ? z : 0)); int nz = (matrix[2, 0] < 0 ? oldBuffer.GetLength(0) - 1 - x : (matrix[2, 0] > 0 ? x : 0)) + (matrix[2, 1] < 0 ? oldBuffer.GetLength(1) - 1 - y : (matrix[2, 1] > 0 ? y : 0)) + (matrix[2, 2] < 0 ? oldBuffer.GetLength(2) - 1 - z : (matrix[2, 2] > 0 ? z : 0)); newBuffer[nx, ny, nz] = oldBuffer[x, y, z]; } } } player.Message("Rotated copy (slot {0}) by {1} degrees around {2} axis.", info.Slot + 1, degrees, axis); player.SetCopyState(info); }
static void PlayersHandler( Player player, CommandReader cmd ) { string param = cmd.Next(); Player[] players; string worldName = null; string qualifier; int offset = 0; if( param == null || Int32.TryParse( param, out offset ) ) { // No world name given; Start with a list of all players. players = Server.Players; qualifier = "online"; if( cmd.HasNext ) { CdPlayers.PrintUsage( player ); return; } } else { // Try to find the world World world = WorldManager.FindWorldOrPrintMatches( player, param ); if( world == null ) return; worldName = param; // If found, grab its player list players = world.Players; qualifier = String.Format( "in world {0}&S", world.ClassyName ); if( cmd.HasNext && !cmd.NextInt( out offset ) ) { CdPlayers.PrintUsage( player ); return; } } if( players.Length > 0 ) { // Filter out hidden players, and sort Player[] visiblePlayers = players.Where( player.CanSee ) .OrderBy( p => p, PlayerListSorter.Instance ) .ToArray(); if( visiblePlayers.Length == 0 ) { player.Message( "There are no players {0}", qualifier ); } else if( visiblePlayers.Length <= PlayersPerPage || player.IsSuper ) { player.MessagePrefixed( "&S ", "&SThere are {0} players {1}: {2}", visiblePlayers.Length, qualifier, visiblePlayers.JoinToClassyString() ); } else { if( offset >= visiblePlayers.Length ) { offset = Math.Max( 0, visiblePlayers.Length - PlayersPerPage ); } Player[] playersPart = visiblePlayers.Skip( offset ).Take( PlayersPerPage ).ToArray(); player.MessagePrefixed( "&S ", "&SPlayers {0}: {1}", qualifier, playersPart.JoinToClassyString() ); if( offset + playersPart.Length < visiblePlayers.Length ) { player.Message( "Showing {0}-{1} (out of {2}). Next: &H/Players {3}{1}", offset + 1, offset + playersPart.Length, visiblePlayers.Length, (worldName == null ? "" : worldName + " ") ); } else { player.Message( "Showing players {0}-{1} (out of {2}).", offset + 1, offset + playersPart.Length, visiblePlayers.Length ); } } } else { player.Message( "There are no players {0}", qualifier ); } }
static void ZoneRemoveHandler(Player player, CommandReader cmd) { if (player.World == null) { PlayerOpException.ThrowNoWorld(player); } string zoneName = cmd.Next(); if (zoneName == null || cmd.HasNext) { CdZoneRemove.PrintUsage(player); return; } if (zoneName == "*") { if (!cmd.IsConfirmed) { Logger.Log(LogType.UserActivity, "ZRemove: Asked {0} to confirm removing all zones on world {1}", player.Name, player.World.Name); player.Confirm(cmd, "&WRemove ALL zones on this world ({0}&W)? This cannot be undone.&S", player.World.ClassyName); return; } player.WorldMap.Zones.Clear(); Logger.Log(LogType.UserActivity, "Player {0} removed all zones on world {1}", player.Name, player.World.Name); Server.Message("Player {0}&S removed all zones on world {1}", player.ClassyName, player.World.ClassyName); return; } ZoneCollection zones = player.WorldMap.Zones; Zone zone = zones.Find(zoneName); if (zone != null) { if (!player.Info.Rank.AllowSecurityCircumvention) { switch (zone.Controller.CheckDetailed(player.Info)) { case SecurityCheckResult.BlackListed: player.Message("You are not allowed to remove zone {0}: you are blacklisted.", zone.ClassyName); return; case SecurityCheckResult.RankTooLow: player.Message("You are not allowed to remove zone {0}.", zone.ClassyName); return; } } if (!cmd.IsConfirmed) { Logger.Log(LogType.UserActivity, "ZRemove: Asked {0} to confirm removing zone {1} from world {2}", player.Name, zone.Name, player.World.Name); player.Confirm(cmd, "Remove zone {0}&S?", zone.ClassyName); return; } if (zones.Remove(zone.Name)) { Logger.Log(LogType.UserActivity, "Player {0} removed zone {1} from world {2}", player.Name, zone.Name, player.World.Name); player.Message("Zone \"{0}\" removed.", zone.Name); } } else { player.MessageNoZone(zoneName); } }
static void RestoreHandler( Player player, CommandReader cmd ) { string fileName = cmd.Next(); if( fileName == null ) { CdRestore.PrintUsage( player ); return; } if( cmd.HasNext ) { CdRestore.PrintUsage( player ); return; } string fullFileName = WorldManager.FindMapFile( player, fileName ); if( fullFileName == null ) return; Map map; if( !MapUtility.TryLoad( fullFileName, true, out map ) ) { player.Message( "Could not load the given map file ({0})", fileName ); return; } Map playerMap = player.WorldMap; if( playerMap.Width != map.Width || playerMap.Length != map.Length || playerMap.Height != map.Height ) { player.Message( "Map file dimensions must match your current world's dimensions ({0}x{1}x{2})", playerMap.Width, playerMap.Length, playerMap.Height ); return; } map.Metadata["fCraft.Temp", "FileName"] = fullFileName; player.SelectionStart( 2, RestoreCallback, map, CdRestore.Permissions ); player.MessageNow( "Restore: Click or &H/Mark&S 2 blocks." ); }
static void ZoneRenameHandler(Player player, CommandReader cmd) { World playerWorld = player.World; if (playerWorld == null) { PlayerOpException.ThrowNoWorld(player); } // make sure that both parameters are given string oldName = cmd.Next(); string newName = cmd.Next(); if (oldName == null || newName == null) { CdZoneRename.PrintUsage(player); return; } // make sure that the new name is valid if (!World.IsValidName(newName)) { player.Message("\"{0}\" is not a valid zone name", newName); return; } // find the old zone var zones = player.WorldMap.Zones; Zone oldZone = zones.Find(oldName); if (oldZone == null) { player.MessageNoZone(oldName); return; } // Check if a zone with "newName" name already exists Zone newZone = zones.FindExact(newName); if (newZone != null && newZone != oldZone) { player.Message("A zone with the name \"{0}\" already exists.", newName); return; } // check if any change is needed string fullOldName = oldZone.Name; if (fullOldName == newName) { player.Message("The zone is already named \"{0}\"", fullOldName); return; } // actually rename the zone zones.Rename(oldZone, newName); // announce the rename playerWorld.Players.Message("&SZone \"{0}\" was renamed to \"{1}&S\" by {2}", fullOldName, oldZone.ClassyName, player.ClassyName); Logger.Log(LogType.UserActivity, "Player {0} renamed zone \"{1}\" to \"{2}\" on world {3}", player.Name, fullOldName, newName, playerWorld.Name); }
static void MirrorHandler( Player player, CommandReader cmd ) { CopyState originalInfo = player.GetCopyState(); if( originalInfo == null ) { player.MessageNow( "Nothing to flip! Copy something first." ); return; } // clone to avoid messing up any paste-in-progress CopyState info = new CopyState( originalInfo ); bool flipX = false, flipY = false, flipH = false; string axis; while( (axis = cmd.Next()) != null ) { foreach( char c in axis.ToLower() ) { if( c == 'x' ) flipX = true; if( c == 'y' ) flipY = true; if( c == 'z' ) flipH = true; } } if( !flipX && !flipY && !flipH ) { CdMirror.PrintUsage( player ); return; } Block block; if( flipX ) { int left = 0; int right = info.Bounds.Width - 1; while( left < right ) { for( int y = info.Bounds.Length - 1; y >= 0; y-- ) { for( int z = info.Bounds.Height - 1; z >= 0; z-- ) { block = info.Blocks[left, y, z]; info.Blocks[left, y, z] = info.Blocks[right, y, z]; info.Blocks[right, y, z] = block; } } left++; right--; } } if( flipY ) { int left = 0; int right = info.Bounds.Length - 1; while( left < right ) { for( int x = info.Bounds.Width - 1; x >= 0; x-- ) { for( int z = info.Bounds.Height - 1; z >= 0; z-- ) { block = info.Blocks[x, left, z]; info.Blocks[x, left, z] = info.Blocks[x, right, z]; info.Blocks[x, right, z] = block; } } left++; right--; } } if( flipH ) { int left = 0; int right = info.Bounds.Height - 1; while( left < right ) { for( int x = info.Bounds.Width - 1; x >= 0; x-- ) { for( int y = info.Bounds.Length - 1; y >= 0; y-- ) { block = info.Blocks[x, y, left]; info.Blocks[x, y, left] = info.Blocks[x, y, right]; info.Blocks[x, y, right] = block; } } left++; right--; } } if( flipX ) { if( flipY ) { if( flipH ) { player.Message( "Flipped copy along all axes." ); } else { player.Message( "Flipped copy along X (east/west) and Y (north/south) axes." ); } } else { if( flipH ) { player.Message( "Flipped copy along X (east/west) and Z (vertical) axes." ); } else { player.Message( "Flipped copy along X (east/west) axis." ); } } } else { if( flipY ) { if( flipH ) { player.Message( "Flipped copy along Y (north/south) and Z (vertical) axes." ); } else { player.Message( "Flipped copy along Y (north/south) axis." ); } } else { player.Message( "Flipped copy along Z (vertical) axis." ); } } player.SetCopyState( info ); }
static void RestartHandler(Player player, CommandReader cmd) { string delayString = cmd.Next(); TimeSpan delayTime = DefaultShutdownTime; string reason = ""; if (delayString != null) { if (delayString.Equals("abort", StringComparison.OrdinalIgnoreCase)) { if (Server.CancelShutdown()) { Logger.Log(LogType.UserActivity, "Restart aborted by {0}.", player.Name); Server.Message("&WRestart aborted by {0}", player.ClassyName); } else { player.MessageNow("Cannot abort restart - too late."); } return; } else if (!delayString.TryParseMiniTimespan(out delayTime)) { CdShutdown.PrintUsage(player); return; } if (delayTime > DateTimeUtil.MaxTimeSpan) { player.MessageMaxTimeSpan(); return; } reason = cmd.NextAll(); } if (delayTime.TotalMilliseconds > Int32.MaxValue - 1) { player.Message("Restart: Delay is too long, maximum is {0}", TimeSpan.FromMilliseconds(Int32.MaxValue - 1).ToMiniString()); return; } Server.Message("&WServer restarting in {0}", delayTime.ToMiniString()); if (String.IsNullOrEmpty(reason)) { Logger.Log(LogType.UserActivity, "{0} scheduled a restart ({1} delay).", player.Name, delayTime.ToCompactString()); ShutdownParams sp = new ShutdownParams(ShutdownReason.Restarting, delayTime, true, true); Server.Shutdown(sp, false); } else { Server.Message("&WRestart reason: {0}", reason); Logger.Log(LogType.UserActivity, "{0} scheduled a restart ({1} delay). Reason: {2}", player.Name, delayTime.ToCompactString(), reason); ShutdownParams sp = new ShutdownParams(ShutdownReason.Restarting, delayTime, true, true, reason, player); Server.Shutdown(sp, false); } }