mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-23 04:32:50 -04:00
Move appropriate functions into UndoDrawOp and HighlightDrawOp, split UndoPhysicsDrawOp into separate file.
This commit is contained in:
parent
e09d1efddc
commit
1b86b30b4c
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -38,7 +38,7 @@ namespace MCGalaxy.Undo {
|
|||||||
public static UndoFormat NewFormat = new UndoFormatCBin();
|
public static UndoFormat NewFormat = new UndoFormatCBin();
|
||||||
|
|
||||||
/// <summary> Enumerates through all the entries in the undo file. </summary>
|
/// <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>
|
/// <summary> File extension of undo files in this format. </summary>
|
||||||
protected abstract string Ext { get; }
|
protected abstract string Ext { get; }
|
||||||
@ -81,7 +81,7 @@ namespace MCGalaxy.Undo {
|
|||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
static UndoFormat GetFormat(string file) {
|
public static UndoFormat GetFormat(string file) {
|
||||||
if (file.EndsWith(TxtFormat.Ext)) return TxtFormat;
|
if (file.EndsWith(TxtFormat.Ext)) return TxtFormat;
|
||||||
if (file.EndsWith(BinFormat.Ext)) return BinFormat;
|
if (file.EndsWith(BinFormat.Ext)) return BinFormat;
|
||||||
if (file.EndsWith(NewFormat.Ext)) return NewFormat;
|
if (file.EndsWith(NewFormat.Ext)) return NewFormat;
|
||||||
@ -110,36 +110,13 @@ namespace MCGalaxy.Undo {
|
|||||||
|
|
||||||
/// <summary> Whether the format has finished retrieving undo data,
|
/// <summary> Whether the format has finished retrieving undo data,
|
||||||
/// due to finding an entry before the start range. </summary>
|
/// due to finding an entry before the start range. </summary>
|
||||||
public bool Stop;
|
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>
|
/// <summary> First instance in time that undo data should be retrieved back to. </summary>
|
||||||
internal readonly DateTime Start;
|
internal readonly DateTime Start;
|
||||||
|
|
||||||
/// <summary> Last instance in time that undo data should be retrieved up to. </summary>
|
public UndoFormatArgs(Player p, DateTime start) {
|
||||||
internal readonly DateTime End;
|
Player = p; Start = start;
|
||||||
|
|
||||||
/// <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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ namespace MCGalaxy.Undo {
|
|||||||
protected override string Ext { get { return ".unbin"; } }
|
protected override string Ext { get { return ".unbin"; } }
|
||||||
const int entrySize = 12;
|
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>();
|
List<ChunkHeader> list = new List<ChunkHeader>();
|
||||||
UndoFormatEntry pos;
|
UndoFormatEntry pos;
|
||||||
bool super = Player.IsSuper(args.Player);
|
bool super = Player.IsSuper(args.Player);
|
||||||
|
@ -28,7 +28,7 @@ namespace MCGalaxy.Undo {
|
|||||||
protected override string Ext { get { return ".uncbin"; } }
|
protected override string Ext { get { return ".uncbin"; } }
|
||||||
const int entrySize = 8;
|
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>();
|
List<ChunkHeader> list = new List<ChunkHeader>();
|
||||||
UndoFormatEntry pos;
|
UndoFormatEntry pos;
|
||||||
bool super = Player.IsSuper(args.Player);
|
bool super = Player.IsSuper(args.Player);
|
||||||
|
@ -27,7 +27,7 @@ namespace MCGalaxy.Undo {
|
|||||||
|
|
||||||
protected override string Ext { get { return ".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);
|
UndoFormatEntry pos = default(UndoFormatEntry);
|
||||||
string[] lines = new StreamReader(s).ReadToEnd().SplitSpaces();
|
string[] lines = new StreamReader(s).ReadToEnd().SplitSpaces();
|
||||||
Player p = args.Player;
|
Player p = args.Player;
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
permissions and limitations under the Licenses.
|
permissions and limitations under the Licenses.
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using MCGalaxy.DB;
|
using MCGalaxy.DB;
|
||||||
using MCGalaxy.Drawing.Brushes;
|
using MCGalaxy.Drawing.Brushes;
|
||||||
using MCGalaxy.Maths;
|
using MCGalaxy.Maths;
|
||||||
@ -65,10 +67,8 @@ namespace MCGalaxy.Drawing.Ops {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UndoFormatArgs args = new UndoFormatArgs(Player, Start, DateTime.MaxValue, Min, Max, output);
|
UndoFormatArgs args = new UndoFormatArgs(Player, Start);
|
||||||
args.PlaceHighlight = PlaceHighlight;
|
DoOldHighlight(args);
|
||||||
args.DeleteHighlight = DeleteHighlight;
|
|
||||||
UndoFormat.DoHighlight(who.ToLower(), ref found, args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Action<DrawOpBlock> output;
|
Action<DrawOpBlock> output;
|
||||||
@ -93,5 +93,37 @@ namespace MCGalaxy.Drawing.Ops {
|
|||||||
output(Place((ushort)x, (ushort)y, (ushort)z, highlight));
|
output(Place((ushort)x, (ushort)y, (ushort)z, highlight));
|
||||||
found = true;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,11 +16,12 @@
|
|||||||
permissions and limitations under the Licenses.
|
permissions and limitations under the Licenses.
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
using MCGalaxy.Blocks.Physics;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using MCGalaxy.DB;
|
using MCGalaxy.DB;
|
||||||
using MCGalaxy.Drawing.Brushes;
|
using MCGalaxy.Drawing.Brushes;
|
||||||
|
using MCGalaxy.Maths;
|
||||||
using MCGalaxy.Undo;
|
using MCGalaxy.Undo;
|
||||||
using MCGalaxy.Maths;
|
|
||||||
|
|
||||||
namespace MCGalaxy.Drawing.Ops {
|
namespace MCGalaxy.Drawing.Ops {
|
||||||
|
|
||||||
@ -69,9 +70,9 @@ namespace MCGalaxy.Drawing.Ops {
|
|||||||
if (BlockDBReadLock != null) BlockDBReadLock.Dispose();
|
if (BlockDBReadLock != null) BlockDBReadLock.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UndoFormatArgs args = new UndoFormatArgs(Player, Start, End, Min, Max, output);
|
UndoFormatArgs args = new UndoFormatArgs(Player, Start);
|
||||||
UndoFormat.DoUndo(who.ToLower(), ref found, args);
|
DoOldUndo(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
Action<DrawOpBlock> output;
|
Action<DrawOpBlock> output;
|
||||||
@ -90,57 +91,41 @@ namespace MCGalaxy.Drawing.Ops {
|
|||||||
output(Place((ushort)x, (ushort)y, (ushort)z, block));
|
output(Place((ushort)x, (ushort)y, (ushort)z, block));
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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; }
|
void DoOldUndo(UndoFormatArgs args) {
|
||||||
|
List<string> files = UndoFormat.GetUndoFiles(who.ToLower());
|
||||||
public override void Perform(Vec3S32[] marks, Brush brush, Action<DrawOpBlock> output) {
|
if (files.Count == 0) return;
|
||||||
if (Level.UndoBuffer.Count != Server.physUndo) {
|
found = true;
|
||||||
int count = Level.currentUndo;
|
|
||||||
for (int i = count; i >= 0; i--) {
|
foreach (string file in files) {
|
||||||
try {
|
using (Stream s = File.OpenRead(file)) {
|
||||||
if (!CheckBlockPhysics(Player, Level, i)) break;
|
DoOldUndo(s, UndoFormat.GetFormat(file), args);
|
||||||
} catch { }
|
if (args.Stop) break;
|
||||||
}
|
|
||||||
} 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) {
|
void DoOldUndo(Stream s, UndoFormat format, UndoFormatArgs args) {
|
||||||
Level.UndoPos undo = lvl.UndoBuffer[i];
|
Level lvl = args.Player == null ? null : args.Player.level;
|
||||||
byte b = lvl.GetTile(undo.index);
|
string lastMap = null;
|
||||||
DateTime time = Server.StartTime.AddTicks((undo.flags >> 2) * TimeSpan.TicksPerSecond);
|
DrawOpBlock block;
|
||||||
if (time < Start) return false;
|
|
||||||
|
|
||||||
byte newType = (undo.flags & 2) != 0 ? Block.custom_block : undo.newRaw;
|
foreach (UndoFormatEntry P in format.GetEntries(s, args)) {
|
||||||
if (b == newType || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava) {
|
if (P.LevelName != lastMap) lvl = LevelInfo.FindExact(P.LevelName);
|
||||||
ushort x, y, z;
|
if (lvl == null || P.Time > End) continue;
|
||||||
lvl.IntToPos(undo.index, out x, out y, out z);
|
if (P.X < Min.X || P.Y < Min.Y || P.Z < Min.Z) continue;
|
||||||
int undoIndex = lvl.currentUndo;
|
if (P.X > Max.X || P.Y > Max.Y || P.Z > Max.Z) continue;
|
||||||
lvl.currentUndo = i;
|
|
||||||
lvl.currentUndo = undoIndex;
|
|
||||||
|
|
||||||
ExtBlock oldBlock = ExtBlock.FromRaw(undo.oldRaw, (undo.flags & 1) != 0);
|
byte lvlBlock = lvl.GetTile(P.X, P.Y, P.Z);
|
||||||
lvl.Blockchange(x, y, z, oldBlock, true, default(PhysicsArgs), false);
|
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
76
MCGalaxy/Drawing/DrawOps/UndoPhysicsDrawOp.cs
Normal file
76
MCGalaxy/Drawing/DrawOps/UndoPhysicsDrawOp.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -451,6 +451,7 @@
|
|||||||
<Compile Include="Drawing\DrawOps\TreeDrawOp.cs" />
|
<Compile Include="Drawing\DrawOps\TreeDrawOp.cs" />
|
||||||
<Compile Include="Drawing\DrawOps\TriangleDrawOp.cs" />
|
<Compile Include="Drawing\DrawOps\TriangleDrawOp.cs" />
|
||||||
<Compile Include="Drawing\DrawOps\UndoDrawOp.cs" />
|
<Compile Include="Drawing\DrawOps\UndoDrawOp.cs" />
|
||||||
|
<Compile Include="Drawing\DrawOps\UndoPhysicsDrawOp.cs" />
|
||||||
<Compile Include="Drawing\DrawOps\WriteDrawOp.cs" />
|
<Compile Include="Drawing\DrawOps\WriteDrawOp.cs" />
|
||||||
<Compile Include="Drawing\Flip.cs" />
|
<Compile Include="Drawing\Flip.cs" />
|
||||||
<Compile Include="Drawing\Image\ImagePalette.cs" />
|
<Compile Include="Drawing\Image\ImagePalette.cs" />
|
||||||
@ -586,7 +587,6 @@
|
|||||||
<Compile Include="Player\PlayerInfo.cs" />
|
<Compile Include="Player\PlayerInfo.cs" />
|
||||||
<Compile Include="Player\SpamChecker.cs" />
|
<Compile Include="Player\SpamChecker.cs" />
|
||||||
<Compile Include="Player\TabList.cs" />
|
<Compile Include="Player\TabList.cs" />
|
||||||
<Compile Include="Database\Undo\UndoFormat.Helpers.cs" />
|
|
||||||
<Compile Include="Database\Undo\UndoFormatCBin.cs" />
|
<Compile Include="Database\Undo\UndoFormatCBin.cs" />
|
||||||
<Compile Include="Player\Warp.cs" />
|
<Compile Include="Player\Warp.cs" />
|
||||||
<Compile Include="Database\Undo\UndoFormat.cs" />
|
<Compile Include="Database\Undo\UndoFormat.cs" />
|
||||||
@ -652,7 +652,6 @@
|
|||||||
<Compile Include="sharkbite.thresher\ConnectionArgs.cs" />
|
<Compile Include="sharkbite.thresher\ConnectionArgs.cs" />
|
||||||
<Compile Include="sharkbite.thresher\Delegates.cs" />
|
<Compile Include="sharkbite.thresher\Delegates.cs" />
|
||||||
<Compile Include="sharkbite.thresher\Enums.cs" />
|
<Compile Include="sharkbite.thresher\Enums.cs" />
|
||||||
<Compile Include="sharkbite.thresher\Identd.cs" />
|
|
||||||
<Compile Include="sharkbite.thresher\Listener.cs" />
|
<Compile Include="sharkbite.thresher\Listener.cs" />
|
||||||
<Compile Include="sharkbite.thresher\NameGenerator.cs" />
|
<Compile Include="sharkbite.thresher\NameGenerator.cs" />
|
||||||
<Compile Include="sharkbite.thresher\ReplyCode.cs" />
|
<Compile Include="sharkbite.thresher\ReplyCode.cs" />
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user