diff --git a/MCGalaxy/Commands/building/CmdCopy.cs b/MCGalaxy/Commands/building/CmdCopy.cs index 6b58504c0..07cab423b 100644 --- a/MCGalaxy/Commands/building/CmdCopy.cs +++ b/MCGalaxy/Commands/building/CmdCopy.cs @@ -93,7 +93,7 @@ namespace MCGalaxy.Commands.Building { void DoCopyMark(Player p, Vec3S32[] m, int i, object state, ExtBlock block) { if (i == 2) { - CopyState copy = p.CopyBuffer; + CopyState copy = p.CopySlots[p.CurrentCopySlot]; copy.Offset.X = copy.OriginX - m[i].X; copy.Offset.Y = copy.OriginY - m[i].Y; copy.Offset.Z = copy.OriginZ - m[i].Z; @@ -105,7 +105,7 @@ namespace MCGalaxy.Commands.Building { CopyArgs cArgs = (CopyArgs)state; Vec3S32 min = Vec3S32.Min(m[0], m[1]), max = Vec3S32.Max(m[0], m[1]); ushort minX = (ushort)min.X, minY = (ushort)min.Y, minZ = (ushort)min.Z; - ushort maxX = (ushort)max.X, maxY = (ushort)max.X, maxZ = (ushort)max.Z; + ushort maxX = (ushort)max.X, maxY = (ushort)max.Y, maxZ = (ushort)max.Z; CopyState cState = new CopyState(minX, minY, minZ, maxX - minX + 1, maxY - minY + 1, maxZ - minZ + 1); @@ -135,7 +135,7 @@ namespace MCGalaxy.Commands.Building { return; } - p.CopyBuffer = cState; + p.SetCurrentCopy(cState); if (cArgs.type == 1) { DrawOp op = new CuboidDrawOp(); op.Flags = BlockDBFlags.Cut; @@ -172,7 +172,7 @@ namespace MCGalaxy.Commands.Building { using (FileStream fs = File.Create(path)) using(GZipStream gs = new GZipStream(fs, CompressionMode.Compress)) { - p.CopyBuffer.SaveTo(gs); + p.CopySlots[p.CurrentCopySlot].SaveTo(gs); } Player.Message(p, "Saved copy as " + file); } @@ -190,7 +190,7 @@ namespace MCGalaxy.Commands.Building { } else { state.LoadFromOld(gs, fs); } - p.CopyBuffer = state; + p.SetCurrentCopy(state); } Player.Message(p, "Loaded copy as " + file); } diff --git a/MCGalaxy/Commands/building/CmdCopySlot.cs b/MCGalaxy/Commands/building/CmdCopySlot.cs new file mode 100644 index 000000000..24180c536 --- /dev/null +++ b/MCGalaxy/Commands/building/CmdCopySlot.cs @@ -0,0 +1,60 @@ +/* + Copyright 2015 MCGalaxy + + Dual-licensed under the Educational Community License, Version 2.0 and + the GNU General Public License, Version 3 (the "Licenses"); you may + not use this file except in compliance with the Licenses. You may + obtain a copy of the Licenses at + + http://www.opensource.org/licenses/ecl2.php + http://www.gnu.org/licenses/gpl-3.0.html + + Unless required by applicable law or agreed to in writing, + software distributed under the Licenses are distributed on an "AS IS" + BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + or implied. See the Licenses for the specific language governing + permissions and limitations under the Licenses. + */ +using System; + +namespace MCGalaxy.Commands.Building { + public sealed class CmdCopySlot : Command { + public override string name { get { return "CopySlot"; } } + public override string shortcut { get { return "cs"; } } + public override string type { get { return CommandTypes.Building; } } + public override LevelPermission defaultRank { get { return LevelPermission.AdvBuilder; } } + public override bool SuperUseable { get { return false; } } + + public override void Use(Player p, string message) { + if (message.Length == 0) { + int used = 0; + for (int i = 0; i < p.CopySlots.Count; i++) { + if (p.CopySlots[i] == null) continue; + Player.Message(p, " #{0}: {1}", i + 1, p.CopySlots[i].Summary); + used++; + } + + Player.Message(p, "Using {0} of {1} slots, with slot #{2} selected.", + used, p.group.CopySlots, p.CurrentCopySlot + 1); + } else { + int i = 0; + if (!CommandParser.GetInt(p, message, "Slot number", ref i, 1, p.group.CopySlots)) return; + + i--; p.CurrentCopySlot = i; + if (i >= p.CopySlots.Count || p.CopySlots[i] == null) { + Player.Message(p, "Selected copy slot {0} (unused)", i + 1); + } else { + Player.Message(p, "Selected copy slot {0}: {1}", i + 1, p.CopySlots[i].Summary); + } + } + } + + public override void Help(Player p) { + Player.Message(p, "%T/CopySlot [number]."); + Player.Message(p, "%HSelects the slot to %T/copy %Hand %T/paste %Hfrom"); + Player.Message(p, "%HMaxmimum number of copy slots is determined your rank"); + Player.Message(p, "%T/CopySlot."); + Player.Message(p, "%HLists details about any copies stored in any slots"); + } + } +} diff --git a/MCGalaxy/Commands/building/CmdPaste.cs b/MCGalaxy/Commands/building/CmdPaste.cs index ce06d849a..556828782 100644 --- a/MCGalaxy/Commands/building/CmdPaste.cs +++ b/MCGalaxy/Commands/building/CmdPaste.cs @@ -34,7 +34,9 @@ namespace MCGalaxy.Commands.Building { } public override void Use(Player p, string message) { - if (p.CopyBuffer == null) { Player.Message(p, "You haven't copied anything yet"); return; } + if (p.CopySlots[p.CurrentCopySlot] == null) { + Player.Message(p, "You haven't copied anything yet"); return; + } BrushArgs args = new BrushArgs(p, message, ExtBlock.Air); Brush brush = BrushFactory.Find("paste").Construct(args); @@ -45,11 +47,11 @@ namespace MCGalaxy.Commands.Building { } bool DoPaste(Player p, Vec3S32[] m, object state, ExtBlock block) { - CopyState cState = p.CopyBuffer; + CopyState cState = p.CopySlots[p.CurrentCopySlot]; m[0] += cState.Offset; PasteDrawOp op = new PasteDrawOp(); - op.CopyState = p.CopyBuffer; + op.CopyState = cState; DrawOpPerformer.Do(op, (Brush)state, p, m); return true; } diff --git a/MCGalaxy/Commands/building/CmdSpin.cs b/MCGalaxy/Commands/building/CmdSpin.cs index 84e52ba7e..16118d656 100644 --- a/MCGalaxy/Commands/building/CmdSpin.cs +++ b/MCGalaxy/Commands/building/CmdSpin.cs @@ -31,7 +31,8 @@ namespace MCGalaxy.Commands.Building { public override void Use(Player p, string message) { if (message.Length == 0) message = "y"; - if (p.CopyBuffer == null) { + CopyState cState = p.CopySlots[p.CurrentCopySlot]; + if (cState == null) { Player.Message(p, "You haven't copied anything yet"); return; } string opt = message.ToLower(); @@ -39,13 +40,13 @@ namespace MCGalaxy.Commands.Building { // Mirroring if (opt == "mirrorx" || opt == "mirror x") { - Flip.MirrorX(p.CopyBuffer, defs); + Flip.MirrorX(cState, defs); Player.Message(p, "Flipped copy across the X (east/west) axis."); } else if (opt == "mirrory" || opt == "mirror y" || opt == "u") { - Flip.MirrorY(p.CopyBuffer, defs); + Flip.MirrorY(cState, defs); Player.Message(p, "Flipped copy across the Y (vertical) axis."); } else if (opt == "mirrorz" || opt == "mirror z" || opt == "m") { - Flip.MirrorZ(p.CopyBuffer, defs); + Flip.MirrorZ(cState, defs); Player.Message(p, "Flipped copy across the Z (north/south) axis."); } else { string[] args = opt.SplitSpaces(); @@ -56,11 +57,11 @@ namespace MCGalaxy.Commands.Building { if (angle == 0) { } else if (axis == 'X') { - p.CopyBuffer = Flip.RotateX(p.CopyBuffer, angle, defs); + p.SetCurrentCopy(Flip.RotateX(cState, angle, defs)); } else if (axis == 'Y') { - p.CopyBuffer = Flip.RotateY(p.CopyBuffer, angle, defs); + p.SetCurrentCopy(Flip.RotateY(cState, angle, defs)); } else if (axis == 'Z') { - p.CopyBuffer = Flip.RotateZ(p.CopyBuffer, angle, defs); + p.SetCurrentCopy(Flip.RotateZ(cState, angle, defs)); } Player.Message(p, "Rotated copy {0} degrees around the {1} axis", angle, axis); } diff --git a/MCGalaxy/Drawing/BrushFactories/SimpleBrushes.cs b/MCGalaxy/Drawing/BrushFactories/SimpleBrushes.cs index fe08ebf34..25eee34aa 100644 --- a/MCGalaxy/Drawing/BrushFactories/SimpleBrushes.cs +++ b/MCGalaxy/Drawing/BrushFactories/SimpleBrushes.cs @@ -99,15 +99,16 @@ namespace MCGalaxy.Drawing.Brushes { }; public override Brush Construct(BrushArgs args) { - if (args.Player.CopyBuffer == null) { + CopyState cState = args.Player.CopySlots[args.Player.CurrentCopySlot]; + if (cState == null) { args.Player.SendMessage("You haven't copied anything yet."); return null; } if (args.Message.Length == 0) - return new SimplePasteBrush(args.Player.CopyBuffer); + return new SimplePasteBrush(cState); string[] parts = args.Message.SplitSpaces(); - PasteBrush brush = new PasteBrush(args.Player.CopyBuffer); + PasteBrush brush = new PasteBrush(cState); if (parts[0].CaselessEq("not")) { brush.Exclude = ReplaceBrushFactory.GetBlocks(args.Player, 1, parts.Length, parts); diff --git a/MCGalaxy/Drawing/CopyState.cs b/MCGalaxy/Drawing/CopyState.cs index ae94e7cb5..42b9743c3 100644 --- a/MCGalaxy/Drawing/CopyState.cs +++ b/MCGalaxy/Drawing/CopyState.cs @@ -30,17 +30,19 @@ namespace MCGalaxy.Drawing { public bool PasteAir; public int UsedBlocks; public Vec3S32 Offset; + public DateTime CopyTime; internal int OppositeOriginX { get { return OriginX == X ? X + Width - 1 : X; } } internal int OppositeOriginY { get { return OriginY == Y ? Y + Height - 1 : Y; } } - internal int OppositeOriginZ { get { return OriginZ == Z ? Z + Length - 1 : Z; } } - - public int Volume { - get { return Width * Height * Length; } + internal int OppositeOriginZ { get { return OriginZ == Z ? Z + Length - 1 : Z; } } + public int Volume { get { return Width * Height * Length; } } + public string Summary { + get { return Volume + " blocks, " + (DateTime.UtcNow - CopyTime).Shorten(true) + " ago"; } } public CopyState(int x, int y, int z, int width, int height, int length) { Init(x, y, z, width, height, length); + CopyTime = DateTime.UtcNow; } void Init(int x, int y, int z, int width, int height, int length) { diff --git a/MCGalaxy/Games/ZombieSurvival/ZSPlugin.cs b/MCGalaxy/Games/ZombieSurvival/ZSPlugin.cs index 29d2f23f8..5b6b6c033 100644 --- a/MCGalaxy/Games/ZombieSurvival/ZSPlugin.cs +++ b/MCGalaxy/Games/ZombieSurvival/ZSPlugin.cs @@ -118,7 +118,7 @@ namespace MCGalaxy.Games.ZS { p.Game.Referee = false; if (p.Supports(CpeExt.HackControl)) - p.Send(Hacks.MakeHackControl(p)); + p.Send(Hacks.MakeHackControl(p, p.level.GetMotd(p))); } else { HandlePlayerDisconnect(p, null); p.Game.Referee = true; diff --git a/MCGalaxy/Levels/Hacks.cs b/MCGalaxy/Levels/Hacks.cs index 89ddd9745..a4c08a4aa 100644 --- a/MCGalaxy/Levels/Hacks.cs +++ b/MCGalaxy/Levels/Hacks.cs @@ -29,8 +29,7 @@ namespace MCGalaxy { return !noHacks; } - public static byte[] MakeHackControl(Player p) { - string motd = p.level.GetMotd(p); + public static byte[] MakeHackControl(Player p, string motd) { motd = Colors.Strip(motd); bool isOp = p.Rank >= LevelPermission.Operator; diff --git a/MCGalaxy/MCGalaxy_.csproj b/MCGalaxy/MCGalaxy_.csproj index b636b6f24..e5da60c3e 100644 --- a/MCGalaxy/MCGalaxy_.csproj +++ b/MCGalaxy/MCGalaxy_.csproj @@ -126,6 +126,7 @@ + diff --git a/MCGalaxy/Network/Player.Networking.cs b/MCGalaxy/Network/Player.Networking.cs index 3ab151d88..b182fedc8 100644 --- a/MCGalaxy/Network/Player.Networking.cs +++ b/MCGalaxy/Network/Player.Networking.cs @@ -167,9 +167,8 @@ namespace MCGalaxy { Send(packet); if (!Supports(CpeExt.HackControl)) return; - Send(Hacks.MakeHackControl(this)); - if (Game.Referee) - Send(Packet.HackControl(true, true, true, true, true, -1)); + Send(Hacks.MakeHackControl(this, level.GetMotd(this))); + if (Game.Referee) Send(Packet.HackControl(true, true, true, true, true, -1)); } public void SendMap(Level oldLevel) { SendRawMap(oldLevel, level); } diff --git a/MCGalaxy/Player/Player.Fields.cs b/MCGalaxy/Player/Player.Fields.cs index 5eecccce6..0b719ceb5 100644 --- a/MCGalaxy/Player/Player.Fields.cs +++ b/MCGalaxy/Player/Player.Fields.cs @@ -160,16 +160,17 @@ namespace MCGalaxy { //Tnt Wars public bool PlayingTntWars; - public int CurrentAmountOfTnt = 0; + public int CurrentAmountOfTnt; public int CurrentTntGameNumber; //For keeping track of which game is which public int TntWarsHealth = 2; - public int TntWarsKillStreak = 0; + public int TntWarsKillStreak; public float TntWarsScoreMultiplier = 1f; - public int TNTWarsLastKillStreakAnnounced = 0; + public int TNTWarsLastKillStreakAnnounced; public bool inTNTwarsMap; public Player HarmedBy = null; //For Assists - public CopyState CopyBuffer; + public List CopySlots = new List(); + public int CurrentCopySlot; // BlockDefinitions internal int gbStep = 0, lbStep = 0; diff --git a/MCGalaxy/Player/Player.cs b/MCGalaxy/Player/Player.cs index 2ae63839c..87fe703c0 100644 --- a/MCGalaxy/Player/Player.cs +++ b/MCGalaxy/Player/Player.cs @@ -19,6 +19,7 @@ using System.Net.Sockets; using System.Threading; using MCGalaxy.Blocks; using MCGalaxy.DB; +using MCGalaxy.Drawing; using MCGalaxy.Events.EconomyEvents; using MCGalaxy.Events.PlayerEvents; using MCGalaxy.Games; @@ -322,8 +323,11 @@ namespace MCGalaxy { connections.Remove(this); RemoveFromPending(); Extras.Clear(); - if (CopyBuffer != null) - CopyBuffer.Clear(); + + foreach (CopyState cState in CopySlots) { + if (cState != null) cState.Clear(); + } + CopySlots.Clear(); DrawOps.Clear(); if (spamChecker != null) spamChecker.Clear(); @@ -343,6 +347,11 @@ namespace MCGalaxy { } return true; } + + public void SetCurrentCopy(CopyState state) { + while (CurrentCopySlot >= CopySlots.Count) { CopySlots.Add(null); } + CopySlots[CurrentCopySlot] = state; + } #endregion