Move appropriate functions into UndoDrawOp and HighlightDrawOp, split UndoPhysicsDrawOp into separate file.

This commit is contained in:
UnknownShadow200 2017-05-18 19:52:27 +10:00
parent e09d1efddc
commit 1b86b30b4c
10 changed files with 153 additions and 334 deletions

View File

@ -1,99 +0,0 @@
/*
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;
using System.Collections.Generic;
using System.IO;
using MCGalaxy.Maths;
namespace MCGalaxy.Undo {
/// <summary> Retrieves and saves undo data in a particular format. </summary>
/// <remarks> Note most formats only support retrieving undo data. </remarks>
public abstract partial class UndoFormat {
public static void DoUndo(string target, ref bool found, UndoFormatArgs args) {
List<string> files = GetUndoFiles(target);
if (files.Count == 0) return;
found = true;
foreach (string file in files) {
using (Stream s = File.OpenRead(file)) {
DoUndo(s, GetFormat(file), args);
if (args.Stop) break;
}
}
}
static void DoUndo(Stream s, UndoFormat format, UndoFormatArgs args) {
Level lvl = args.Player == null ? null : args.Player.level;
string lastMap = null;
Vec3S32 min = args.Min, max = args.Max;
DrawOpBlock block;
foreach (UndoFormatEntry P in format.GetEntries(s, args)) {
if (P.LevelName != lastMap) lvl = LevelInfo.FindExact(P.LevelName);
if (lvl == null || P.Time > args.End) continue;
if (P.X < min.X || P.Y < min.Y || P.Z < min.Z) continue;
if (P.X > max.X || P.Y > max.Y || P.Z > max.Z) continue;
byte lvlBlock = lvl.GetTile(P.X, P.Y, P.Z);
if (lvlBlock == P.NewBlock.BlockID || Block.Convert(lvlBlock) == Block.water
|| Block.Convert(lvlBlock) == Block.lava || lvlBlock == Block.grass) {
block.X = P.X; block.Y = P.Y; block.Z = P.Z;
block.Block = P.Block;
args.Output(block);
}
}
}
public static void DoHighlight(string target, ref bool found, UndoFormatArgs args) {
List<string> files = GetUndoFiles(target);
if (files.Count == 0) return;
found = true;
foreach (string file in files) {
using (Stream s = File.OpenRead(file)) {
DoHighlight(s, GetFormat(file), args);
if (args.Stop) break;
}
}
}
static void DoHighlight(Stream s, UndoFormat format, UndoFormatArgs args) {
Level lvl = args.Player.level;
Vec3S32 min = args.Min, max = args.Max;
DrawOpBlock block;
foreach (UndoFormatEntry P in format.GetEntries(s, args)) {
ExtBlock old = P.Block, newBlock = P.NewBlock;
if (P.X < min.X || P.Y < min.Y || P.Z < min.Z) continue;
if (P.X > max.X || P.Y > max.Y || P.Z > max.Z) continue;
block.Block = (newBlock.BlockID == Block.air
|| Block.Convert(old.BlockID) == Block.water || old.BlockID == Block.waterstill
|| Block.Convert(old.BlockID) == Block.lava || old.BlockID == Block.lavastill)
? args.DeleteHighlight : args.PlaceHighlight;
block.X = P.X; block.Y = P.Y; block.Z = P.Z;
args.Output(block);
}
}
}
}

View File

@ -38,7 +38,7 @@ namespace MCGalaxy.Undo {
public static UndoFormat NewFormat = new UndoFormatCBin();
/// <summary> Enumerates through all the entries in the undo file. </summary>
protected abstract IEnumerable<UndoFormatEntry> GetEntries(Stream s, UndoFormatArgs args);
public abstract IEnumerable<UndoFormatEntry> GetEntries(Stream s, UndoFormatArgs args);
/// <summary> File extension of undo files in this format. </summary>
protected abstract string Ext { get; }
@ -81,7 +81,7 @@ namespace MCGalaxy.Undo {
return files;
}
static UndoFormat GetFormat(string file) {
public static UndoFormat GetFormat(string file) {
if (file.EndsWith(TxtFormat.Ext)) return TxtFormat;
if (file.EndsWith(BinFormat.Ext)) return BinFormat;
if (file.EndsWith(NewFormat.Ext)) return NewFormat;
@ -112,34 +112,11 @@ namespace MCGalaxy.Undo {
/// due to finding an entry before the start range. </summary>
public bool Stop;
/// <summary> Block to highlight placements with. </summary>
public ExtBlock PlaceHighlight = (ExtBlock)Block.green;
/// <summary> Block to highlight deletions with. </summary>
public ExtBlock DeleteHighlight = (ExtBlock)Block.red;
/// <summary> First instance in time that undo data should be retrieved back to. </summary>
internal readonly DateTime Start;
/// <summary> Last instance in time that undo data should be retrieved up to. </summary>
internal readonly DateTime End;
/// <summary> Minimum coordinate of region to process blocks within. </summary>
internal readonly Vec3S32 Min;
/// <summary> Minimum coordinate of region to process blocks within. </summary>
internal readonly Vec3S32 Max;
/// <summary> Action invoked for each block processed. </summary>
internal Action<DrawOpBlock> Output;
public UndoFormatArgs(Player p, DateTime start, DateTime end,
Vec3S32 min, Vec3S32 max, Action<DrawOpBlock> output) {
Player = p;
Start = start; End = end;
Min = min; Max = max;
Output = output;
public UndoFormatArgs(Player p, DateTime start) {
Player = p; Start = start;
}
}

View File

@ -28,7 +28,7 @@ namespace MCGalaxy.Undo {
protected override string Ext { get { return ".unbin"; } }
const int entrySize = 12;
protected override IEnumerable<UndoFormatEntry> GetEntries(Stream s, UndoFormatArgs args) {
public override IEnumerable<UndoFormatEntry> GetEntries(Stream s, UndoFormatArgs args) {
List<ChunkHeader> list = new List<ChunkHeader>();
UndoFormatEntry pos;
bool super = Player.IsSuper(args.Player);

View File

@ -28,7 +28,7 @@ namespace MCGalaxy.Undo {
protected override string Ext { get { return ".uncbin"; } }
const int entrySize = 8;
protected override IEnumerable<UndoFormatEntry> GetEntries(Stream s, UndoFormatArgs args) {
public override IEnumerable<UndoFormatEntry> GetEntries(Stream s, UndoFormatArgs args) {
List<ChunkHeader> list = new List<ChunkHeader>();
UndoFormatEntry pos;
bool super = Player.IsSuper(args.Player);

View File

@ -27,7 +27,7 @@ namespace MCGalaxy.Undo {
protected override string Ext { get { return ".undo"; } }
protected override IEnumerable<UndoFormatEntry> GetEntries(Stream s, UndoFormatArgs args) {
public override IEnumerable<UndoFormatEntry> GetEntries(Stream s, UndoFormatArgs args) {
UndoFormatEntry pos = default(UndoFormatEntry);
string[] lines = new StreamReader(s).ReadToEnd().SplitSpaces();
Player p = args.Player;

View File

@ -16,6 +16,8 @@
permissions and limitations under the Licenses.
*/
using System;
using System.Collections.Generic;
using System.IO;
using MCGalaxy.DB;
using MCGalaxy.Drawing.Brushes;
using MCGalaxy.Maths;
@ -65,10 +67,8 @@ namespace MCGalaxy.Drawing.Ops {
}
}
UndoFormatArgs args = new UndoFormatArgs(Player, Start, DateTime.MaxValue, Min, Max, output);
args.PlaceHighlight = PlaceHighlight;
args.DeleteHighlight = DeleteHighlight;
UndoFormat.DoHighlight(who.ToLower(), ref found, args);
UndoFormatArgs args = new UndoFormatArgs(Player, Start);
DoOldHighlight(args);
}
Action<DrawOpBlock> output;
@ -93,5 +93,37 @@ namespace MCGalaxy.Drawing.Ops {
output(Place((ushort)x, (ushort)y, (ushort)z, highlight));
found = true;
}
void DoOldHighlight(UndoFormatArgs args) {
List<string> files = UndoFormat.GetUndoFiles(who.ToLower());
if (files.Count == 0) return;
found = true;
foreach (string file in files) {
using (Stream s = File.OpenRead(file)) {
DoOldHighlight(s, UndoFormat.GetFormat(file), args);
if (args.Stop) break;
}
}
}
void DoOldHighlight(Stream s, UndoFormat format, UndoFormatArgs args) {
DrawOpBlock block;
foreach (UndoFormatEntry P in format.GetEntries(s, args)) {
ExtBlock old = P.Block, newBlock = P.NewBlock;
if (P.X < Min.X || P.Y < Min.Y || P.Z < Min.Z) continue;
if (P.X > Max.X || P.Y > Max.Y || P.Z > Max.Z) continue;
block.Block = (newBlock.BlockID == Block.air
|| Block.Convert(old.BlockID) == Block.water || old.BlockID == Block.waterstill
|| Block.Convert(old.BlockID) == Block.lava || old.BlockID == Block.lavastill)
? DeleteHighlight : PlaceHighlight;
block.X = P.X; block.Y = P.Y; block.Z = P.Z;
output(block);
}
}
}
}

View File

@ -16,11 +16,12 @@
permissions and limitations under the Licenses.
*/
using System;
using MCGalaxy.Blocks.Physics;
using System.Collections.Generic;
using System.IO;
using MCGalaxy.DB;
using MCGalaxy.Drawing.Brushes;
using MCGalaxy.Undo;
using MCGalaxy.Maths;
using MCGalaxy.Undo;
namespace MCGalaxy.Drawing.Ops {
@ -70,8 +71,8 @@ namespace MCGalaxy.Drawing.Ops {
}
}
UndoFormatArgs args = new UndoFormatArgs(Player, Start, End, Min, Max, output);
UndoFormat.DoUndo(who.ToLower(), ref found, args);
UndoFormatArgs args = new UndoFormatArgs(Player, Start);
DoOldUndo(args);
}
Action<DrawOpBlock> output;
@ -90,57 +91,41 @@ namespace MCGalaxy.Drawing.Ops {
output(Place((ushort)x, (ushort)y, (ushort)z, block));
found = true;
}
}
public class UndoPhysicsDrawOp : DrawOp {
public override string Name { get { return "UndoPhysics"; } }
public override bool AffectedByTransform { get { return false; } }
internal DateTime Start;
void DoOldUndo(UndoFormatArgs args) {
List<string> files = UndoFormat.GetUndoFiles(who.ToLower());
if (files.Count == 0) return;
found = true;
public override long BlocksAffected(Level lvl, Vec3S32[] marks) { return -1; }
public override void Perform(Vec3S32[] marks, Brush brush, Action<DrawOpBlock> output) {
if (Level.UndoBuffer.Count != Server.physUndo) {
int count = Level.currentUndo;
for (int i = count; i >= 0; i--) {
try {
if (!CheckBlockPhysics(Player, Level, i)) break;
} catch { }
}
} else {
int count = Level.currentUndo;
for (int i = count; i >= 0; i--) {
try {
if (!CheckBlockPhysics(Player, Level, i)) break;
} catch { }
}
for (int i = Level.UndoBuffer.Count - 1; i > count; i--) {
try {
if (!CheckBlockPhysics(Player, Level, i)) break;
} catch { }
foreach (string file in files) {
using (Stream s = File.OpenRead(file)) {
DoOldUndo(s, UndoFormat.GetFormat(file), args);
if (args.Stop) break;
}
}
}
bool CheckBlockPhysics(Player p, Level lvl, int i) {
Level.UndoPos undo = lvl.UndoBuffer[i];
byte b = lvl.GetTile(undo.index);
DateTime time = Server.StartTime.AddTicks((undo.flags >> 2) * TimeSpan.TicksPerSecond);
if (time < Start) return false;
void DoOldUndo(Stream s, UndoFormat format, UndoFormatArgs args) {
Level lvl = args.Player == null ? null : args.Player.level;
string lastMap = null;
DrawOpBlock block;
byte newType = (undo.flags & 2) != 0 ? Block.custom_block : undo.newRaw;
if (b == newType || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava) {
ushort x, y, z;
lvl.IntToPos(undo.index, out x, out y, out z);
int undoIndex = lvl.currentUndo;
lvl.currentUndo = i;
lvl.currentUndo = undoIndex;
foreach (UndoFormatEntry P in format.GetEntries(s, args)) {
if (P.LevelName != lastMap) lvl = LevelInfo.FindExact(P.LevelName);
if (lvl == null || P.Time > End) continue;
if (P.X < Min.X || P.Y < Min.Y || P.Z < Min.Z) continue;
if (P.X > Max.X || P.Y > Max.Y || P.Z > Max.Z) continue;
ExtBlock oldBlock = ExtBlock.FromRaw(undo.oldRaw, (undo.flags & 1) != 0);
lvl.Blockchange(x, y, z, oldBlock, true, default(PhysicsArgs), false);
byte lvlBlock = lvl.GetTile(P.X, P.Y, P.Z);
if (lvlBlock == P.NewBlock.BlockID || Block.Convert(lvlBlock) == Block.water
|| Block.Convert(lvlBlock) == Block.lava || lvlBlock == Block.grass) {
block.X = P.X; block.Y = P.Y; block.Z = P.Z;
block.Block = P.Block;
output(block);
}
}
return true;
}
}
}

View File

@ -0,0 +1,76 @@
/*
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;
using MCGalaxy.Blocks.Physics;
using MCGalaxy.Drawing.Brushes;
using MCGalaxy.Maths;
namespace MCGalaxy.Drawing.Ops {
public class UndoPhysicsDrawOp : DrawOp {
public override string Name { get { return "UndoPhysics"; } }
public override bool AffectedByTransform { get { return false; } }
internal DateTime Start;
public override long BlocksAffected(Level lvl, Vec3S32[] marks) { return -1; }
public override void Perform(Vec3S32[] marks, Brush brush, Action<DrawOpBlock> output) {
if (Level.UndoBuffer.Count != Server.physUndo) {
int count = Level.currentUndo;
for (int i = count; i >= 0; i--) {
try {
if (!CheckBlockPhysics(Player, Level, i)) break;
} catch { }
}
} else {
int count = Level.currentUndo;
for (int i = count; i >= 0; i--) {
try {
if (!CheckBlockPhysics(Player, Level, i)) break;
} catch { }
}
for (int i = Level.UndoBuffer.Count - 1; i > count; i--) {
try {
if (!CheckBlockPhysics(Player, Level, i)) break;
} catch { }
}
}
}
bool CheckBlockPhysics(Player p, Level lvl, int i) {
Level.UndoPos undo = lvl.UndoBuffer[i];
byte b = lvl.GetTile(undo.index);
DateTime time = Server.StartTime.AddTicks((undo.flags >> 2) * TimeSpan.TicksPerSecond);
if (time < Start) return false;
byte newType = (undo.flags & 2) != 0 ? Block.custom_block : undo.newRaw;
if (b == newType || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava) {
ushort x, y, z;
lvl.IntToPos(undo.index, out x, out y, out z);
int undoIndex = lvl.currentUndo;
lvl.currentUndo = i;
lvl.currentUndo = undoIndex;
ExtBlock oldBlock = ExtBlock.FromRaw(undo.oldRaw, (undo.flags & 1) != 0);
lvl.Blockchange(x, y, z, oldBlock, true, default(PhysicsArgs), false);
}
return true;
}
}
}

View File

@ -451,6 +451,7 @@
<Compile Include="Drawing\DrawOps\TreeDrawOp.cs" />
<Compile Include="Drawing\DrawOps\TriangleDrawOp.cs" />
<Compile Include="Drawing\DrawOps\UndoDrawOp.cs" />
<Compile Include="Drawing\DrawOps\UndoPhysicsDrawOp.cs" />
<Compile Include="Drawing\DrawOps\WriteDrawOp.cs" />
<Compile Include="Drawing\Flip.cs" />
<Compile Include="Drawing\Image\ImagePalette.cs" />
@ -586,7 +587,6 @@
<Compile Include="Player\PlayerInfo.cs" />
<Compile Include="Player\SpamChecker.cs" />
<Compile Include="Player\TabList.cs" />
<Compile Include="Database\Undo\UndoFormat.Helpers.cs" />
<Compile Include="Database\Undo\UndoFormatCBin.cs" />
<Compile Include="Player\Warp.cs" />
<Compile Include="Database\Undo\UndoFormat.cs" />
@ -652,7 +652,6 @@
<Compile Include="sharkbite.thresher\ConnectionArgs.cs" />
<Compile Include="sharkbite.thresher\Delegates.cs" />
<Compile Include="sharkbite.thresher\Enums.cs" />
<Compile Include="sharkbite.thresher\Identd.cs" />
<Compile Include="sharkbite.thresher\Listener.cs" />
<Compile Include="sharkbite.thresher\NameGenerator.cs" />
<Compile Include="sharkbite.thresher\ReplyCode.cs" />

View File

@ -1,151 +0,0 @@
/*
* Thresher IRC client library
* Copyright (C) 2002 Aaron Hunter <thresher@sharkbite.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* See the gpl.txt file located in the top-level-directory of
* the archive of this library for complete text of license.
*/
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Diagnostics;
namespace Sharkbite.Irc
{
/// <summary>
/// An Ident daemon is still used by some IRC networks for
/// authentication. It is a simple service which when queried
/// by a remote system returns a username. The server is controlled via static
/// methods all of which are Thread safe.
/// </summary>
public sealed class Identd
{
private static TcpListener listener;
private static bool running;
private static object lockObject;
private static string username;
private const string Reply = " : USERID : UNIX : ";
private const int IdentdPort = 113;
static Identd()
{
running = false;
lockObject = new object();
}
//Declare constructor private so it cannot be instatiated.
private Identd() {}
/// <summary>
/// The Identd server will start listening for queries
/// in its own thread. It can be stopped by calling
/// <see cref="Identd.Stop"/>.
/// </summary>
/// <param name="userName">Should be the same username as the one used
/// in the ConnectionArgs object when establishing a connection.</param>
/// <exception cref="Exception">If the server has already been started.</exception>
public static void Start( string userName )
{
lock( lockObject )
{
if( running )
{
throw new Exception("Identd already started.");
}
running = true;
username = userName;
Thread socketThread = new Thread( new ThreadStart( Identd.Run ) );
socketThread.Name = "Identd";
socketThread.Start();
}
}
/// <summary>
/// Check if the Identd server is running
/// </summary>
/// <returns>True if it is running</returns>
public static bool IsRunning()
{
lock( lockObject )
{
return running;
}
}
/// <summary>
/// Stop the Identd server and close the thread.
/// </summary>
public static void Stop()
{
lock( lockObject )
{
if( running )
{
listener.Stop();
Debug.WriteLineIf( Rfc2812Util.IrcTrace.TraceInfo,"[" + Thread.CurrentThread.Name +"] Identd::Stop()");
listener = null;
running = false;
}
}
}
private static void Run()
{
Debug.WriteLineIf( Rfc2812Util.IrcTrace.TraceInfo,"[" + Thread.CurrentThread.Name +"] Identd::Run()");
try
{
listener = new TcpListener( IPAddress.Any, IdentdPort );
listener.Start();
while (true)
{
try
{
TcpClient client = listener.AcceptTcpClient();
//Read query
StreamReader reader = new StreamReader(client.GetStream() );
string line = reader.ReadLine();
Debug.WriteLineIf( Rfc2812Util.IrcTrace.TraceVerbose,"[" + Thread.CurrentThread.Name +"] Identd::Run() received=" + line);
//Send back reply
StreamWriter writer = new StreamWriter( client.GetStream() );
writer.WriteLine( line.Trim() + Reply + username );
writer.Flush();
//Close connection with client
client.Close();
}
catch( IOException ioe )
{
Debug.WriteLineIf( Rfc2812Util.IrcTrace.TraceWarning,"[" + Thread.CurrentThread.Name +"] Identd::Run() exception=" + ioe);
}
}
}
catch( Exception )
{
Debug.WriteLineIf( Rfc2812Util.IrcTrace.TraceInfo,"[" + Thread.CurrentThread.Name +"] Identd::Run() Identd stopped");
}
finally
{
running = false;
}
}
}
}