Fix /up from IRC/console, fixes #378

This commit is contained in:
UnknownShadow200 2017-05-30 21:42:31 +10:00
parent efeff445d7
commit 06a460d7ce
9 changed files with 74 additions and 51 deletions

View File

@ -30,7 +30,7 @@ namespace MCGalaxy.Commands.Moderation {
public override bool museumUsable { get { return true; } }
public override LevelPermission defaultRank { get { return LevelPermission.Operator; } }
public override CommandAlias[] Aliases {
get { return new[] { new CommandAlias("xundo", null, "all"),
get { return new[] { new CommandAlias("xundo", null, "all"),
new CommandAlias("undoarea", "area"), new CommandAlias("ua", "area") }; }
}
@ -72,7 +72,21 @@ namespace MCGalaxy.Commands.Moderation {
UndoDrawOp op = new UndoDrawOp();
op.Start = DateTime.UtcNow.Subtract(delta);
op.who = names[0]; op.ids = ids;
DrawOpPerformer.Do(op, null, p, marks);
if (Player.IsSuper(p)) {
// undo them across all loaded levels
Level[] levels = LevelInfo.Loaded.Items;
if (p == null) p = new ConsolePlayer();
foreach (Level lvl in levels) {
op.SetMarks(marks);
op.SetLevel(lvl);
op.Player = p; p.level = lvl;
DrawOpPerformer.DoQueuedDrawOp(p, op, null, marks);
}
} else {
DrawOpPerformer.Do(op, null, p, marks);
}
string namesStr = names.Join(name => PlayerInfo.GetColoredName(p, name));
if (op.found) {
@ -83,6 +97,19 @@ namespace MCGalaxy.Commands.Moderation {
}
}
// TODO: nasty hack, need to find a better way of doing this
sealed class ConsolePlayer : Player {
public ConsolePlayer() : base("(console)") {
group = Group.NobodyRank;
UserID = NameConverter.InvalidNameID("(console)");
}
public override void SendMessage(byte id, string message, bool colorParse = true) {
message = Chat.Format(message, this, colorParse);
Server.s.Log(message);
}
}
int[] GetIds(Player p, string[] parts, out string[] names) {
int count = Math.Max(1, parts.Length - 1);
List<int> ids = new List<int>();

View File

@ -79,23 +79,14 @@ namespace MCGalaxy.Drawing.Ops {
Player.Message(p, format, op.Name, affected);
}
AppendDrawOp(p, op, brush, marks, affected);
DoQueuedDrawOp(p, op, brush, marks);
return true;
}
static void AppendDrawOp(Player p, DrawOp op, Brush brush, Vec3S32[] marks, long affected) {
if (p == null) {
BufferedBlockSender buffer = new BufferedBlockSender(op.Level);
op.Perform(marks, brush, b => ConsoleOutputBlock(b, op.Level, buffer));
buffer.Send(true);
return;
}
internal static void DoQueuedDrawOp(Player p, DrawOp op, Brush brush, Vec3S32[] marks) {
PendingDrawOp item = new PendingDrawOp();
item.Op = op;
item.Brush = brush;
item.Marks = marks;
item.Op = op; item.Brush = brush; item.Marks = marks;
lock (p.pendingDrawOpsLock) {
p.PendingDrawOps.Add(item);
// Another thread is already processing draw ops.
@ -104,12 +95,6 @@ namespace MCGalaxy.Drawing.Ops {
ProcessDrawOps(p);
}
static void ConsoleOutputBlock(DrawOpBlock b, Level lvl, BufferedBlockSender buffer) {
int index = lvl.PosToInt(b.X, b.Y, b.Z);
if (!lvl.DoPhysicsBlockchange(index, b.Block, false, default(PhysicsArgs))) return;
buffer.Add(index, b.Block.BlockID, b.Block.ExtID);
}
static void ProcessDrawOps(Player p) {
while (true) {
PendingDrawOp item;
@ -144,7 +129,7 @@ namespace MCGalaxy.Drawing.Ops {
if (item.Op.TotalModified > Server.DrawReloadLimit)
DoReload(p, item.Op.Level);
item.Op.TotalModified = 0; // reset total modified (as drawop instances are used in static mode)
item.Op.TotalModified = 0; // reset total modified (as drawop instances are reused in static mode)
}
}

View File

@ -22,7 +22,7 @@ namespace MCGalaxy {
public enum PlayerAction { Joker, Unjoker, AFK, UnAFK, JoinWorld, Me, Review };
/// <summary> This is the player object </summary>
public sealed partial class Player {
public partial class Player {
public bool cancelcommand, cancelchat, cancelmove, cancelBlock, cancelmysql;
public bool cancelmessage, cancellogin, cancelconnecting;

View File

@ -236,7 +236,7 @@ namespace MCGalaxy.Network {
if (!whoCmd || (DateTime.UtcNow - last).TotalSeconds <= 5) return false;
try {
Player p = MakeIRCPlayer(user.Nick, channel);
Player p = new IRCPlayer(user.Nick, channel, bot);
p.group = Group.GuestRank;
Command.all.Find("players").Use(p, "");
} catch (Exception e) {
@ -250,7 +250,7 @@ namespace MCGalaxy.Network {
bool HandleIRCCommand(UserInfo user, string channel, string cmdName, string cmdArgs) {
Command cmd = Command.all.Find(cmdName);
Player p = MakeIRCPlayer(user.Nick, channel);
Player p = new IRCPlayer(user.Nick, channel, bot);
if (cmd == null) { Player.Message(p, "Unknown command!"); return false; }
string logCmd = cmdArgs == "" ? cmdName : cmdName + " " + cmdArgs;
@ -280,26 +280,40 @@ namespace MCGalaxy.Network {
if (!foundAtAll) {
error = "You are not on the bot's list of users for some reason, please leave and rejoin."; return false;
}
}
if (bot.BannedCommands.Contains(cmdName)) {
error = "You are not allowed to use this command from IRC.";
}
return false;
}
static Player MakeIRCPlayer(string ircNick, string ircChannel) {
Player p = new Player("IRC");
p.group = Group.findPerm(Server.ircControllerRank);
if (p.group == null) p.group = Group.NobodyRank;
sealed class IRCPlayer : Player {
public readonly string IRCChannel, IRCNick;
public readonly IRCBot Bot;
p.ircChannel = ircChannel;
p.ircNick = ircNick;
p.color = "&a";
public IRCPlayer(string ircChannel, string ircNick, IRCBot bot) : base("IRC") {
group = Group.findPerm(Server.ircControllerRank);
if (group == null) group = Group.NobodyRank;
IRCChannel = ircChannel;
IRCNick = ircNick;
color = "&a";
Bot = bot;
if (ircNick != null)
UserID = NameConverter.InvalidNameID("(IRC " + ircNick + ")");
}
if (ircNick != null)
p.UserID = NameConverter.InvalidNameID("(IRC " + ircNick + ")");
return p;
public override void SendMessage(byte id, string message, bool colorParse = true) {
message = Chat.Format(message, this, colorParse);
if (IRCChannel != null) {
Bot.Message(IRCChannel, message);
} else {
Bot.Pm(IRCNick, message);
}
}
}
void Listener_OnRegistered() {
@ -454,7 +468,7 @@ namespace MCGalaxy.Network {
if (verify == IRCControllerVerify.None) return true;
if (verify == IRCControllerVerify.HalfOp) {
string prefix = GetPrefix(chanNicks[index]);
string prefix = GetPrefix(chanNicks[index]);
if (prefix == "" || prefix == "+") {
error = "You must be at least a half-op on the channel to use commands from IRC."; return false;
}

View File

@ -21,7 +21,7 @@ using MCGalaxy.Events;
using MCGalaxy.Network;
namespace MCGalaxy {
public sealed partial class Player : IDisposable {
public partial class Player : IDisposable {
public bool hasCpe, finishedCpeLogin = false;
public string appName;
@ -103,11 +103,7 @@ namespace MCGalaxy {
storedHelp += message + "\r\n";
else
Server.s.Log(message);
} else if (p.ircChannel != null) {
Server.IRC.Message(p.ircChannel, message);
} else if (p.ircNick != null) {
Server.IRC.Pm(p.ircNick, message);
} else {
} else {
p.SendMessage(0, Server.DefaultColor + message, colorParse);
}
}
@ -120,7 +116,7 @@ namespace MCGalaxy {
SendMessage(0, Server.DefaultColor + message, colorParse);
}
public void SendMessage(byte id, string message, bool colorParse = true) {
public virtual void SendMessage(byte id, string message, bool colorParse = true) {
message = Chat.Format(message, this, colorParse);
int totalTries = 0;

View File

@ -28,7 +28,7 @@ namespace MCGalaxy {
public enum VoteKickChoice { NotYetVoted, Yes, No }
public sealed partial class Player : IDisposable {
public partial class Player : IDisposable {
public Dictionary<string, object> ExtraData = new Dictionary<string, object>();
@ -103,7 +103,7 @@ namespace MCGalaxy {
public DateTime NextReviewTime, NextEat;
public float ReachDistance = 5;
public bool hackrank;
internal string ircChannel, ircNick;
public bool SuperUser;
public string FullName { get { return color + prefix + DisplayName; } }
@ -263,6 +263,6 @@ namespace MCGalaxy {
public bool verifiedName;
/// <summary> Returns whether the given player is console or IRC. </summary>
public static bool IsSuper(Player p) { return p == null || p.ircChannel != null || p.ircNick != null; }
public static bool IsSuper(Player p) { return p == null || p.SuperUser; }
}
}

View File

@ -30,7 +30,7 @@ using MCGalaxy.SQL;
using MCGalaxy.Maths;
namespace MCGalaxy {
public sealed partial class Player : IDisposable {
public partial class Player : IDisposable {
bool removedFromPending = false;
internal void RemoveFromPending() {

View File

@ -26,7 +26,7 @@ using MCGalaxy.Tasks;
using MCGalaxy.Maths;
namespace MCGalaxy {
public sealed partial class Player : IDisposable {
public partial class Player : IDisposable {
void HandleLogin(byte[] packet) {
LastAction = DateTime.UtcNow;

View File

@ -33,7 +33,7 @@ namespace MCGalaxy {
public string username { get; set; }
}
public sealed partial class Player : Entity, IDisposable {
public partial class Player : Entity, IDisposable {
static int sessionCounter;
@ -45,6 +45,7 @@ namespace MCGalaxy {
DisplayName = playername;
SessionID = Interlocked.Increment(ref sessionCounter) & SessionIDMask;
spamChecker = new SpamChecker(this);
SuperUser = true;
}
public Player(Socket s) {