mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-26 14:54:12 -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);
|
||||
if (lvl == null) { node = node.Prev; continue; }
|
||||
List<UndoCacheItem> items = node.Items;
|
||||
BufferedBlockSender buffer = new BufferedBlockSender(lvl);
|
||||
|
||||
for (int i = items.Count - 1; i >= 0; i--) {
|
||||
UndoCacheItem item = items[i];
|
||||
@ -53,8 +54,12 @@ namespace MCGalaxy.Commands {
|
||||
byte type = lvl.GetTile(x, y, z), extType = 0;
|
||||
if (type == 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);
|
||||
}
|
||||
}
|
||||
buffer.CheckIfSend(true);
|
||||
node = node.Prev;
|
||||
}
|
||||
}
|
||||
|
@ -169,6 +169,7 @@ namespace MCGalaxy.Commands
|
||||
if (lvl == null) { node = node.Prev; continue; }
|
||||
saveLvl = lvl;
|
||||
List<UndoCacheItem> items = node.Items;
|
||||
BufferedBlockSender buffer = new BufferedBlockSender(lvl);
|
||||
|
||||
for (int i = items.Count - 1; i >= 0; i--) {
|
||||
UndoCacheItem item = items[i];
|
||||
@ -179,11 +180,14 @@ namespace MCGalaxy.Commands
|
||||
|
||||
byte b = lvl.GetTile(x, y, z);
|
||||
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;
|
||||
byte extType = 0;
|
||||
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.x = x; uP.y = y; uP.z = z;
|
||||
@ -191,8 +195,9 @@ namespace MCGalaxy.Commands
|
||||
time = node.BaseTime.AddSeconds(item.TimeDelta);
|
||||
uP.timeDelta = (int)time.Subtract(Server.StartTime).TotalSeconds;
|
||||
if (p != null) p.RedoBuffer.Add(lvl, uP);
|
||||
}
|
||||
}
|
||||
}
|
||||
buffer.CheckIfSend(true);
|
||||
node = node.Prev;
|
||||
}
|
||||
}
|
||||
|
@ -347,12 +347,12 @@ namespace MCGalaxy
|
||||
public static bool canPlace(Player p, byte type) {
|
||||
Blocks b = BlockList[type];
|
||||
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) {
|
||||
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
|
||||
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();
|
||||
packet = bulk;
|
||||
} 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) {
|
||||
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";
|
||||
retry:
|
||||
try
|
||||
{
|
||||
//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;
|
||||
if (b == Block.custom_block) extB = GetExtTile(x, y, z);
|
||||
|
||||
errorLocation = "Permission checking";
|
||||
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)
|
||||
@ -332,20 +337,9 @@ namespace MCGalaxy {
|
||||
p.overallBlocks++;
|
||||
SetTile(x, y, z, type);
|
||||
if (b == Block.custom_block && type != Block.custom_block)
|
||||
RevertExtTileNoCheck(x, y, z);
|
||||
RevertExtTileNoCheck(x, y, z);
|
||||
if (type == Block.custom_block)
|
||||
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";
|
||||
if (p.PlayingTntWars && type == Block.smalltnt) AddCheck(PosToInt(x, y, z), false, p);
|
||||
@ -353,6 +347,9 @@ namespace MCGalaxy {
|
||||
|
||||
changed = true;
|
||||
backedup = false;
|
||||
bool diffBlock = b == Block.custom_block ? extB != extType :
|
||||
Block.Convert(b) != Block.Convert(type);
|
||||
return diffBlock;
|
||||
} catch (OutOfMemoryException) {
|
||||
Player.SendMessage(p, "Undo buffer too big! Cleared!");
|
||||
p.UndoBuffer.Clear();
|
||||
@ -363,6 +360,7 @@ namespace MCGalaxy {
|
||||
Chat.GlobalMessageOps("Error location: " + errorLocation);
|
||||
Server.s.Log(p.name + " triggered a non-fatal error on " + name);
|
||||
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) {
|
||||
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.DoorAirs(b) != 0 ) {
|
||||
@ -748,7 +748,7 @@ namespace MCGalaxy {
|
||||
}
|
||||
if ( Block.odoor(b) != Block.Zero ) {
|
||||
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 {
|
||||
RevertBlock(x, y, z);
|
||||
}
|
||||
@ -835,21 +835,19 @@ namespace MCGalaxy {
|
||||
break;
|
||||
|
||||
default:
|
||||
level.Blockchange(this, x, y, z, (byte)( Block.air ));
|
||||
ChangeBlock(x, y, z, Block.air, 0);
|
||||
break;
|
||||
}
|
||||
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);
|
||||
if ((level.physics == 0 || level.physics == 5) && level.GetTile(x, (ushort)(y - 1), z) == Block.dirt)
|
||||
ChangeBlock(x, (ushort)(y - 1), z, Block.grass, 0);
|
||||
}
|
||||
|
||||
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 (modeType != 0) {
|
||||
if (b == modeType)
|
||||
SendBlockchange(x, y, z, b);
|
||||
else
|
||||
level.Blockchange(this, x, y, z, modeType);
|
||||
if (b == modeType) SendBlockchange(x, y, z, b);
|
||||
else ChangeBlock(x, y, z, modeType, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -861,28 +859,35 @@ namespace MCGalaxy {
|
||||
extAbove = level.GetExtTile(x, (ushort)(y + 1), z);
|
||||
|
||||
if (Block.LightPass(above, extAbove, level.CustomBlockDefs))
|
||||
level.Blockchange(this, x, y, z, (byte)Block.grass);
|
||||
ChangeBlock(x, y, z, Block.grass, 0);
|
||||
else
|
||||
level.Blockchange(this, x, y, z, (byte)Block.dirt);
|
||||
ChangeBlock(x, y, z, Block.dirt, 0);
|
||||
break;
|
||||
case Block.staircasestep: //stair handler
|
||||
if ( level.GetTile(x, (ushort)( y - 1 ), z) == Block.staircasestep ) {
|
||||
case 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.
|
||||
//level.Blockchange(this, x, y, z, (byte)(Block.air));
|
||||
level.Blockchange(this, x, (ushort)( y - 1 ), z, (byte)( Block.staircasefull ));
|
||||
ChangeBlock(x, (ushort)( y - 1 ), z, Block.staircasefull, 0);
|
||||
break;
|
||||
}
|
||||
//else
|
||||
level.Blockchange(this, x, y, z, type, extType);
|
||||
ChangeBlock(x, y, z, type, extType);
|
||||
break;
|
||||
default:
|
||||
level.Blockchange(this, x, y, z, type, extType);
|
||||
ChangeBlock(x, y, z, type, extType);
|
||||
break;
|
||||
}
|
||||
} 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) {
|
||||
if ( !loggedIn || trainGrab || following != "" || frozen )
|
||||
|
Loading…
x
Reference in New Issue
Block a user