mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-28 07:56:20 -04:00
Majorly optimise /undo and /redo - less memory and CPU usage, less bandwidth usage, and less likelihood of overloading the server.
This commit is contained in:
parent
fe0b16b33f
commit
7dd3f578e7
@ -44,6 +44,7 @@ namespace MCGalaxy.Commands {
|
|||||||
Level lvl = LevelInfo.FindExact(node.MapName);
|
Level lvl = LevelInfo.FindExact(node.MapName);
|
||||||
if (lvl == null) { node = node.Prev; continue; }
|
if (lvl == null) { node = node.Prev; continue; }
|
||||||
List<UndoCacheItem> items = node.Items;
|
List<UndoCacheItem> items = node.Items;
|
||||||
|
BufferedBlockSender buffer = new BufferedBlockSender(lvl);
|
||||||
|
|
||||||
for (int i = items.Count - 1; i >= 0; i--) {
|
for (int i = items.Count - 1; i >= 0; i--) {
|
||||||
UndoCacheItem item = items[i];
|
UndoCacheItem item = items[i];
|
||||||
@ -53,8 +54,12 @@ namespace MCGalaxy.Commands {
|
|||||||
byte type = lvl.GetTile(x, y, z), extType = 0;
|
byte type = lvl.GetTile(x, y, z), extType = 0;
|
||||||
if (type == Block.custom_block)
|
if (type == Block.custom_block)
|
||||||
extType = lvl.GetExtTile(x, y, z);
|
extType = lvl.GetExtTile(x, y, z);
|
||||||
lvl.Blockchange(p, x, y, z, item.Type, item.ExtType);
|
if (lvl.DoBlockchange(p, x, y, z, item.Type, item.ExtType)) {
|
||||||
|
buffer.Add(lvl.PosToInt(x, y, z), item.Type, item.ExtType);
|
||||||
|
buffer.CheckIfSend(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
buffer.CheckIfSend(true);
|
||||||
node = node.Prev;
|
node = node.Prev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,6 +169,7 @@ namespace MCGalaxy.Commands
|
|||||||
if (lvl == null) { node = node.Prev; continue; }
|
if (lvl == null) { node = node.Prev; continue; }
|
||||||
saveLvl = lvl;
|
saveLvl = lvl;
|
||||||
List<UndoCacheItem> items = node.Items;
|
List<UndoCacheItem> items = node.Items;
|
||||||
|
BufferedBlockSender buffer = new BufferedBlockSender(lvl);
|
||||||
|
|
||||||
for (int i = items.Count - 1; i >= 0; i--) {
|
for (int i = items.Count - 1; i >= 0; i--) {
|
||||||
UndoCacheItem item = items[i];
|
UndoCacheItem item = items[i];
|
||||||
@ -179,11 +180,14 @@ namespace MCGalaxy.Commands
|
|||||||
|
|
||||||
byte b = lvl.GetTile(x, y, z);
|
byte b = lvl.GetTile(x, y, z);
|
||||||
if (b == item.NewType || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava) {
|
if (b == item.NewType || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava) {
|
||||||
Player.UndoPos uP = default(Player.UndoPos);
|
Player.UndoPos uP = default(Player.UndoPos);
|
||||||
uP.newtype = item.Type; uP.newExtType = item.ExtType;
|
uP.newtype = item.Type; uP.newExtType = item.ExtType;
|
||||||
byte extType = 0;
|
byte extType = 0;
|
||||||
if (b == Block.custom_block) extType = lvl.GetExtTile(x, y, z);
|
if (b == Block.custom_block) extType = lvl.GetExtTile(x, y, z);
|
||||||
lvl.Blockchange(p, x, y, z, item.Type, item.ExtType);
|
if (lvl.DoBlockchange(p, x, y, z, item.Type, item.ExtType)) {
|
||||||
|
buffer.Add(lvl.PosToInt(x, y, z), item.Type, item.ExtType);
|
||||||
|
buffer.CheckIfSend(false);
|
||||||
|
}
|
||||||
|
|
||||||
uP.type = b; uP.extType = extType;
|
uP.type = b; uP.extType = extType;
|
||||||
uP.x = x; uP.y = y; uP.z = z;
|
uP.x = x; uP.y = y; uP.z = z;
|
||||||
@ -191,8 +195,9 @@ namespace MCGalaxy.Commands
|
|||||||
time = node.BaseTime.AddSeconds(item.TimeDelta);
|
time = node.BaseTime.AddSeconds(item.TimeDelta);
|
||||||
uP.timeDelta = (int)time.Subtract(Server.StartTime).TotalSeconds;
|
uP.timeDelta = (int)time.Subtract(Server.StartTime).TotalSeconds;
|
||||||
if (p != null) p.RedoBuffer.Add(lvl, uP);
|
if (p != null) p.RedoBuffer.Add(lvl, uP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
buffer.CheckIfSend(true);
|
||||||
node = node.Prev;
|
node = node.Prev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,12 +347,12 @@ namespace MCGalaxy
|
|||||||
public static bool canPlace(Player p, byte type) {
|
public static bool canPlace(Player p, byte type) {
|
||||||
Blocks b = BlockList[type];
|
Blocks b = BlockList[type];
|
||||||
LevelPermission perm = p.group.Permission;
|
LevelPermission perm = p.group.Permission;
|
||||||
return (perm >= b.lowestRank || b.allow.Contains(perm)) && !b.disallow.Contains(perm));
|
return (perm >= b.lowestRank || b.allow.Contains(perm)) && !b.disallow.Contains(perm);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool canPlace(LevelPermission perm, byte type) {
|
public static bool canPlace(LevelPermission perm, byte type) {
|
||||||
Blocks b = BlockList[type];
|
Blocks b = BlockList[type];
|
||||||
return (perm >= b.lowestRank || b.allow.Contains(perm)) && !b.disallow.Contains(perm));
|
return (perm >= b.lowestRank || b.allow.Contains(perm)) && !b.disallow.Contains(perm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ namespace MCGalaxy {
|
|||||||
|
|
||||||
// Different clients support varying types of blocks
|
// Different clients support varying types of blocks
|
||||||
byte[] packet = null;
|
byte[] packet = null;
|
||||||
if (p.HasCpeExt(CpeExt.BulkBlockUpdate) && p.hasCustomBlocks && p.hasBlockDefs && count >= 1600) {
|
if (p.HasCpeExt(CpeExt.BulkBlockUpdate) && p.hasCustomBlocks && p.hasBlockDefs && count >= 160) {
|
||||||
if (bulk == null) bulk = MakeBulkPacket();
|
if (bulk == null) bulk = MakeBulkPacket();
|
||||||
packet = bulk;
|
packet = bulk;
|
||||||
} else if (p.hasCustomBlocks && p.hasBlockDefs) {
|
} else if (p.hasCustomBlocks && p.hasBlockDefs) {
|
||||||
|
@ -299,18 +299,23 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void Blockchange(Player p, ushort x, ushort y, ushort z, byte type, byte extType = 0) {
|
public void Blockchange(Player p, ushort x, ushort y, ushort z, byte type, byte extType = 0) {
|
||||||
|
if (DoBlockchange(p, x, y, z, type, extType))
|
||||||
|
Player.GlobalBlockchange(this, x, y, z, type, extType);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool DoBlockchange(Player p, ushort x, ushort y, ushort z, byte type, byte extType = 0) {
|
||||||
string errorLocation = "start";
|
string errorLocation = "start";
|
||||||
retry:
|
retry:
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//if (x < 0 || y < 0 || z < 0) return;
|
//if (x < 0 || y < 0 || z < 0) return;
|
||||||
if (x >= Width || y >= Height || z >= Length) return;
|
if (x >= Width || y >= Height || z >= Length) return false;
|
||||||
byte b = GetTile(x, y, z), extB = 0;
|
byte b = GetTile(x, y, z), extB = 0;
|
||||||
if (b == Block.custom_block) extB = GetExtTile(x, y, z);
|
if (b == Block.custom_block) extB = GetExtTile(x, y, z);
|
||||||
|
|
||||||
errorLocation = "Permission checking";
|
errorLocation = "Permission checking";
|
||||||
if (!CheckAffectPermissions(p, x, y, z, b, type, extType)) {
|
if (!CheckAffectPermissions(p, x, y, z, b, type, extType)) {
|
||||||
p.RevertBlock(x, y, z); return;
|
p.RevertBlock(x, y, z); return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b == Block.sponge && physics > 0 && type != Block.sponge)
|
if (b == Block.sponge && physics > 0 && type != Block.sponge)
|
||||||
@ -332,20 +337,9 @@ namespace MCGalaxy {
|
|||||||
p.overallBlocks++;
|
p.overallBlocks++;
|
||||||
SetTile(x, y, z, type);
|
SetTile(x, y, z, type);
|
||||||
if (b == Block.custom_block && type != Block.custom_block)
|
if (b == Block.custom_block && type != Block.custom_block)
|
||||||
RevertExtTileNoCheck(x, y, z);
|
RevertExtTileNoCheck(x, y, z);
|
||||||
if (type == Block.custom_block)
|
if (type == Block.custom_block)
|
||||||
SetExtTileNoCheck(x, y, z, extType);
|
SetExtTileNoCheck(x, y, z, extType);
|
||||||
|
|
||||||
errorLocation = "Block sending";
|
|
||||||
bool diffBlock = b == Block.custom_block ? extB != extType :
|
|
||||||
Block.Convert(b) != Block.Convert(type);
|
|
||||||
if (diffBlock) Player.GlobalBlockchange(this, x, y, z, type, extType);
|
|
||||||
|
|
||||||
errorLocation = "Growing grass";
|
|
||||||
if (GetTile(x, (ushort)(y - 1), z) == Block.grass && GrassDestroy
|
|
||||||
&& !Block.LightPass(type, extType, CustomBlockDefs)) {
|
|
||||||
Blockchange(p, x, (ushort)(y - 1), z, Block.dirt);
|
|
||||||
}
|
|
||||||
|
|
||||||
errorLocation = "Adding physics";
|
errorLocation = "Adding physics";
|
||||||
if (p.PlayingTntWars && type == Block.smalltnt) AddCheck(PosToInt(x, y, z), false, p);
|
if (p.PlayingTntWars && type == Block.smalltnt) AddCheck(PosToInt(x, y, z), false, p);
|
||||||
@ -353,6 +347,9 @@ namespace MCGalaxy {
|
|||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
backedup = false;
|
backedup = false;
|
||||||
|
bool diffBlock = b == Block.custom_block ? extB != extType :
|
||||||
|
Block.Convert(b) != Block.Convert(type);
|
||||||
|
return diffBlock;
|
||||||
} catch (OutOfMemoryException) {
|
} catch (OutOfMemoryException) {
|
||||||
Player.SendMessage(p, "Undo buffer too big! Cleared!");
|
Player.SendMessage(p, "Undo buffer too big! Cleared!");
|
||||||
p.UndoBuffer.Clear();
|
p.UndoBuffer.Clear();
|
||||||
@ -363,6 +360,7 @@ namespace MCGalaxy {
|
|||||||
Chat.GlobalMessageOps("Error location: " + errorLocation);
|
Chat.GlobalMessageOps("Error location: " + errorLocation);
|
||||||
Server.s.Log(p.name + " triggered a non-fatal error on " + name);
|
Server.s.Log(p.name + " triggered a non-fatal error on " + name);
|
||||||
Server.s.Log("Error location: " + errorLocation);
|
Server.s.Log("Error location: " + errorLocation);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -736,7 +736,7 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DeleteBlock(byte b, ushort x, ushort y, ushort z, byte type, byte extType) {
|
void DeleteBlock(byte b, ushort x, ushort y, ushort z, byte type, byte extType) {
|
||||||
if ( deleteMode && b != Block.c4det ) { level.Blockchange(this, x, y, z, Block.air); return; }
|
if ( deleteMode && b != Block.c4det ) { ChangeBlock(x, y, z, Block.air, 0); return; }
|
||||||
|
|
||||||
if ( Block.tDoor(b) ) { RevertBlock(x, y, z); return; }
|
if ( Block.tDoor(b) ) { RevertBlock(x, y, z); return; }
|
||||||
if ( Block.DoorAirs(b) != 0 ) {
|
if ( Block.DoorAirs(b) != 0 ) {
|
||||||
@ -748,7 +748,7 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
if ( Block.odoor(b) != Block.Zero ) {
|
if ( Block.odoor(b) != Block.Zero ) {
|
||||||
if ( b == Block.odoor8 || b == Block.odoor8_air ) {
|
if ( b == Block.odoor8 || b == Block.odoor8_air ) {
|
||||||
level.Blockchange(this, x, y, z, Block.odoor(b));
|
ChangeBlock(x, y, z, Block.odoor(b), 0);
|
||||||
} else {
|
} else {
|
||||||
RevertBlock(x, y, z);
|
RevertBlock(x, y, z);
|
||||||
}
|
}
|
||||||
@ -835,21 +835,19 @@ namespace MCGalaxy {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
level.Blockchange(this, x, y, z, (byte)( Block.air ));
|
ChangeBlock(x, y, z, Block.air, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( (level.physics == 0 || level.physics == 5) && level.GetTile(x, (ushort)( y - 1 ), z) == Block.dirt )
|
if ((level.physics == 0 || level.physics == 5) && level.GetTile(x, (ushort)(y - 1), z) == Block.dirt)
|
||||||
level.Blockchange(this, x, (ushort)( y - 1 ), z, Block.grass);
|
ChangeBlock(x, (ushort)(y - 1), z, Block.grass, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaceBlock(byte b, ushort x, ushort y, ushort z, byte type, byte extType) {
|
void PlaceBlock(byte b, ushort x, ushort y, ushort z, byte type, byte extType) {
|
||||||
if ( Block.odoor(b) != Block.Zero ) { SendMessage("oDoor here!"); return; }
|
if ( Block.odoor(b) != Block.Zero ) { SendMessage("oDoor here!"); return; }
|
||||||
|
|
||||||
if (modeType != 0) {
|
if (modeType != 0) {
|
||||||
if (b == modeType)
|
if (b == modeType) SendBlockchange(x, y, z, b);
|
||||||
SendBlockchange(x, y, z, b);
|
else ChangeBlock(x, y, z, modeType, 0);
|
||||||
else
|
|
||||||
level.Blockchange(this, x, y, z, modeType);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -861,28 +859,35 @@ namespace MCGalaxy {
|
|||||||
extAbove = level.GetExtTile(x, (ushort)(y + 1), z);
|
extAbove = level.GetExtTile(x, (ushort)(y + 1), z);
|
||||||
|
|
||||||
if (Block.LightPass(above, extAbove, level.CustomBlockDefs))
|
if (Block.LightPass(above, extAbove, level.CustomBlockDefs))
|
||||||
level.Blockchange(this, x, y, z, (byte)Block.grass);
|
ChangeBlock(x, y, z, Block.grass, 0);
|
||||||
else
|
else
|
||||||
level.Blockchange(this, x, y, z, (byte)Block.dirt);
|
ChangeBlock(x, y, z, Block.dirt, 0);
|
||||||
break;
|
break;
|
||||||
case Block.staircasestep: //stair handler
|
case Block.staircasestep:
|
||||||
if ( level.GetTile(x, (ushort)( y - 1 ), z) == Block.staircasestep ) {
|
if (level.GetTile(x, (ushort)(y - 1), z) == Block.staircasestep) {
|
||||||
SendBlockchange(x, y, z, Block.air); //send the air block back only to the user.
|
SendBlockchange(x, y, z, Block.air); //send the air block back only to the user.
|
||||||
//level.Blockchange(this, x, y, z, (byte)(Block.air));
|
ChangeBlock(x, (ushort)( y - 1 ), z, Block.staircasefull, 0);
|
||||||
level.Blockchange(this, x, (ushort)( y - 1 ), z, (byte)( Block.staircasefull ));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//else
|
ChangeBlock(x, y, z, type, extType);
|
||||||
level.Blockchange(this, x, y, z, type, extType);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
level.Blockchange(this, x, y, z, type, extType);
|
ChangeBlock(x, y, z, type, extType);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
level.Blockchange(this, x, y, z, type, extType);
|
ChangeBlock(x, y, z, type, extType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChangeBlock(ushort x, ushort y, ushort z, byte type, byte extType) {
|
||||||
|
level.Blockchange(this, x, y, z, type, extType);
|
||||||
|
if (level.GetTile(x, (ushort)(y - 1), z) == Block.grass && level.GrassDestroy
|
||||||
|
&& !Block.LightPass(type, extType, level.CustomBlockDefs)) {
|
||||||
|
level.Blockchange(this, x, (ushort)(y - 1), z, Block.dirt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void HandleMovement(byte[] message) {
|
void HandleMovement(byte[] message) {
|
||||||
if ( !loggedIn || trainGrab || following != "" || frozen )
|
if ( !loggedIn || trainGrab || following != "" || frozen )
|
||||||
|
Loading…
x
Reference in New Issue
Block a user