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