Core: Fix being able to noclip into solid portals/message blocks

This commit is contained in:
UnknownShadow200 2016-10-24 17:10:36 +11:00
parent 761e105e94
commit 9fc8d8841a
7 changed files with 172 additions and 99 deletions

View File

@ -37,7 +37,7 @@ namespace MCGalaxy.Blocks {
public static class BlockBehaviour {
internal static HandleDelete[] deleteHandlers = new HandleDelete[256];
internal static HandlePlace[] placeHandlers = new HandlePlace[256];
internal static HandlePlace[] placeHandlers = new HandlePlace[256];
internal static HandleWalkthrough[] walkthroughHandlers = new HandleWalkthrough[256];
internal static HandlePhysics[] physicsHandlers = new HandlePhysics[256];
internal static HandlePhysics[] physicsDoorsHandlers = new HandlePhysics[256];
@ -69,16 +69,15 @@ namespace MCGalaxy.Blocks {
walkthroughHandlers[Block.custom_block] = WalkthroughBehaviour.CustomBlock;
for (int i = 0; i < 256; i++) {
bool walkthrough = Block.Walkthrough(Block.Convert((byte)i));
if (Block.Props[i].IsMessageBlock) {
walkthroughHandlers[i] = (p, block, x, y, z) =>
WalkthroughBehaviour.MessageBlock(p, block, x, y, z, true);
deleteHandlers[i] = (p, block, x, y, z) =>
WalkthroughBehaviour.MessageBlock(p, block, x, y, z, false);
if (walkthrough)
walkthroughHandlers[i] = WalkthroughBehaviour.DoMessageBlock;
deleteHandlers[i] = DeleteBehaviour.DoMessageBlock;
} else if (Block.Props[i].IsPortal) {
walkthroughHandlers[i] = (p, block, x, y, z) =>
WalkthroughBehaviour.Portal(p, block, x, y, z, true);
deleteHandlers[i] = (p, block, x, y, z) =>
WalkthroughBehaviour.Portal(p, block, x, y, z, false);
if (walkthrough)
walkthroughHandlers[i] = WalkthroughBehaviour.DoPortal;
deleteHandlers[i] = DeleteBehaviour.DoPortal;
}
if (Block.Props[i].IsTDoor) {

View File

@ -16,6 +16,7 @@
permissions and limitations under the Licenses.
*/
using System;
using MCGalaxy.Blocks.Extended;
using MCGalaxy.Blocks.Physics;
namespace MCGalaxy.Blocks {
@ -99,13 +100,23 @@ namespace MCGalaxy.Blocks {
}
return true;
}
internal static bool DoPortal(Player p, byte block, ushort x, ushort y, ushort z) {
Portal.Handle(p, x, y, z);
return true;
}
internal static bool DoMessageBlock(Player p, byte block, ushort x, ushort y, ushort z) {
MessageBlock.Handle(p, x, y, z);
return true;
}
internal static bool CustomBlock(Player p, byte block, ushort x, ushort y, ushort z) {
byte extBlock = p.level.GetExtTile(x, y, z);
if (p.level.CustomBlockProps[extBlock].IsPortal) {
return WalkthroughBehaviour.Portal(p, block, x, y, z, false);
return DoPortal(p, block, x, y, z);
} else if (p.level.CustomBlockProps[extBlock].IsMessageBlock) {
return WalkthroughBehaviour.MessageBlock(p, block, x, y, z, false);
return DoMessageBlock(p, block, x, y, z);
} else if (p.level.CustomBlockProps[extBlock].IsTDoor) {
return RevertDoor(p, block, x, y, z);
} else if (p.level.CustomBlockProps[extBlock].IsDoor) {

View File

@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Data;
using MCGalaxy.Blocks.Extended;
using MCGalaxy.Blocks.Physics;
using MCGalaxy.SQL;
@ -45,80 +46,28 @@ namespace MCGalaxy.Blocks {
internal static bool CustomBlock(Player p, byte block, ushort x, ushort y, ushort z) {
byte extBlock = p.level.GetExtTile(x, y, z);
if (p.level.CustomBlockDefs[extBlock].CollideType == 2) return false;
if (p.level.CustomBlockProps[extBlock].IsPortal) {
return Portal(p, block, x, y, z, true);
return DoPortal(p, block, x, y, z);
} else if (p.level.CustomBlockProps[extBlock].IsMessageBlock) {
return MessageBlock(p, block, x, y, z, true);
} else if (p.level.CustomBlockProps[extBlock].IsDoor
&& p.level.CustomBlockDefs[extBlock].CollideType != 0) {
return DoMessageBlock(p, block, x, y, z);
} else if (p.level.CustomBlockProps[extBlock].IsDoor) {
return Door(p, block, x, y, z);
}
return false;
}
internal static bool Portal(Player p, byte block, ushort x, ushort y, ushort z, bool checkPos) {
if (checkPos && p.level.PosToInt(x, y, z) == p.lastWalkthrough) return true;
p.RevertBlock(x, y, z);
try {
DataTable Portals = Database.Backend.GetRows("Portals" + p.level.name, "*",
"WHERE EntryX=@0 AND EntryY=@1 AND EntryZ=@2", x, y, z);
int last = Portals.Rows.Count - 1;
if (last == -1) { Portals.Dispose(); return true; }
byte rotX = p.rot[0], rotY = p.rot[1];
DataRow row = Portals.Rows[last];
string map = row["ExitMap"].ToString();
if (p.level.name != map) {
if (p.level.permissionvisit > p.Rank) {
Player.Message(p, "You do not have the adequate rank to visit this map!"); return true;
}
Level curLevel = p.level;
PlayerActions.ChangeMap(p, map, true);
if (curLevel == p.level) { Player.Message(p, "The map the portal goes to isn't loaded."); return true; }
p.BlockUntilLoad(10);
}
x = ushort.Parse(row["ExitX"].ToString());
y = ushort.Parse(row["ExitY"].ToString());
z = ushort.Parse(row["ExitZ"].ToString());
PlayerActions.MoveCoords(p, x, y, z, rotX, rotY);
Portals.Dispose();
} catch {
Player.Message(p, "Portal had no exit.");
}
internal static bool DoPortal(Player p, byte block, ushort x, ushort y, ushort z) {
if (p.level.PosToInt(x, y, z) == p.lastWalkthrough) return true;
Portal.Handle(p, x, y, z);
return true;
}
internal static bool MessageBlock(Player p, byte block, ushort x, ushort y, ushort z, bool checkPos) {
if (checkPos && p.level.PosToInt(x, y, z) == p.lastWalkthrough) return true;
p.RevertBlock(x, y, z);
try {
DataTable Messages = Database.Backend.GetRows("Messages" + p.level.name, "*",
"WHERE X=@0 AND Y=@1 AND Z=@2", x, y, z);
int last = Messages.Rows.Count - 1;
if (last == -1) { Messages.Dispose(); return true; }
string message = Messages.Rows[last]["Message"].ToString().Trim();
message = message.Replace("\\'", "\'");
message = message.Replace("@p", p.name);
if (message != p.prevMsg || Server.repeatMessage) {
string text;
List<string> cmds = ParseMB(message, out text);
if (text != null) Player.Message(p, text);
if (cmds.Count == 1) {
string[] parts = cmds[0].SplitSpaces(2);
p.HandleCommand(parts[0], parts.Length > 1 ? parts[1] : "");
} else if (cmds.Count > 0) {
p.HandleCommands(cmds);
}
p.prevMsg = message;
}
} catch {
Player.Message(p, "No message was stored.");
}
internal static bool DoMessageBlock(Player p, byte block, ushort x, ushort y, ushort z) {
if (p.level.PosToInt(x, y, z) == p.lastWalkthrough) return true;
MessageBlock.Handle(p, x, y, z);
return true;
}
@ -135,29 +84,5 @@ namespace MCGalaxy.Blocks {
}
return true;
}
static string[] sep = { " |/" };
const StringSplitOptions opts = StringSplitOptions.RemoveEmptyEntries;
static List<string> empty = new List<string>();
internal static List<string> ParseMB(string message, out string text) {
if (message.IndexOf('|') == -1) return ParseSingle(message, out text);
string[] parts = message.Split(sep, opts);
List<string> cmds = ParseSingle(parts[0], out text);
if (parts.Length == 1) return cmds;
if (text != null) cmds = new List<string>();
for (int i = 1; i < parts.Length; i++)
cmds.Add(parts[i]);
return cmds;
}
static List<string> ParseSingle(string message, out string text) {
if (message[0] == '/') {
text = null; return new List<string>(){ message.Substring(1) };
} else {
text = message; return empty;
}
}
}
}

View File

@ -0,0 +1,79 @@
/*
Copyright 2011 MCForge
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.Data;
using MCGalaxy.SQL;
namespace MCGalaxy.Blocks.Extended {
public static class MessageBlock {
public static void Handle(Player p, ushort x, ushort y, ushort z) {
p.RevertBlock(x, y, z);
try {
DataTable Messages = Database.Backend.GetRows("Messages" + p.level.name, "*",
"WHERE X=@0 AND Y=@1 AND Z=@2", x, y, z);
int last = Messages.Rows.Count - 1;
if (last == -1) { Messages.Dispose(); return; }
string message = Messages.Rows[last]["Message"].ToString().Trim();
message = message.Replace("\\'", "\'");
message = message.Replace("@p", p.name);
if (message != p.prevMsg || Server.repeatMessage) {
string text;
List<string> cmds = GetParts(message, out text);
if (text != null) Player.Message(p, text);
if (cmds.Count == 1) {
string[] parts = cmds[0].SplitSpaces(2);
p.HandleCommand(parts[0], parts.Length > 1 ? parts[1] : "");
} else if (cmds.Count > 0) {
p.HandleCommands(cmds);
}
p.prevMsg = message;
}
} catch {
Player.Message(p, "No message was stored.");
}
}
static string[] sep = { " |/" };
const StringSplitOptions opts = StringSplitOptions.RemoveEmptyEntries;
static List<string> empty = new List<string>();
internal static List<string> GetParts(string message, out string text) {
if (message.IndexOf('|') == -1) return ParseSingle(message, out text);
string[] parts = message.Split(sep, opts);
List<string> cmds = ParseSingle(parts[0], out text);
if (parts.Length == 1) return cmds;
if (text != null) cmds = new List<string>();
for (int i = 1; i < parts.Length; i++)
cmds.Add(parts[i]);
return cmds;
}
static List<string> ParseSingle(string message, out string text) {
if (message[0] == '/') {
text = null; return new List<string>(){ message.Substring(1) };
} else {
text = message; return empty;
}
}
}
}

View File

@ -0,0 +1,55 @@
/*
Copyright 2011 MCForge
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.Data;
using MCGalaxy.SQL;
namespace MCGalaxy.Blocks.Extended {
public static class Portal {
public static void Handle(Player p, ushort x, ushort y, ushort z) {
p.RevertBlock(x, y, z);
try {
DataTable Portals = Database.Backend.GetRows("Portals" + p.level.name, "*",
"WHERE EntryX=@0 AND EntryY=@1 AND EntryZ=@2", x, y, z);
int last = Portals.Rows.Count - 1;
if (last == -1) { Portals.Dispose(); return; }
byte rotX = p.rot[0], rotY = p.rot[1];
DataRow row = Portals.Rows[last];
string map = row["ExitMap"].ToString();
if (p.level.name != map) {
if (!p.level.VisitAccess.CheckDetailed(p, false)) return;
Level curLevel = p.level;
PlayerActions.ChangeMap(p, map, true);
if (curLevel == p.level) { Player.Message(p, "The map the portal goes to isn't loaded."); return; }
p.BlockUntilLoad(10);
}
x = ushort.Parse(row["ExitX"].ToString());
y = ushort.Parse(row["ExitY"].ToString());
z = ushort.Parse(row["ExitZ"].ToString());
PlayerActions.MoveCoords(p, x, y, z, rotX, rotY);
Portals.Dispose();
} catch {
Player.Message(p, "Portal had no exit.");
}
}
}
}

View File

@ -19,6 +19,7 @@ using System;
using System.Collections.Generic;
using System.Data;
using MCGalaxy.Blocks;
using MCGalaxy.Blocks.Extended;
using MCGalaxy.SQL;
namespace MCGalaxy.Commands.Building {
@ -51,7 +52,7 @@ namespace MCGalaxy.Commands.Building {
}
string text;
List<string> cmds = WalkthroughBehaviour.ParseMB(data.Message, out text);
List<string> cmds = MessageBlock.GetParts(data.Message, out text);
foreach (string cmd in cmds) {
if (!CheckCommand(p, cmd)) return;
}

View File

@ -98,6 +98,8 @@
<Compile Include="Blocks\Block.Permissions.cs" />
<Compile Include="Blocks\BlockDefinitions.cs" />
<Compile Include="Blocks\BlockProperties.cs" />
<Compile Include="Blocks\Extended\MessageBlock.cs" />
<Compile Include="Blocks\Extended\Portal.cs" />
<Compile Include="Bots\BotsFile.cs" />
<Compile Include="Bots\Instructions\FunInstructions.cs" />
<Compile Include="Bots\Instructions\MoveInstructions.cs" />
@ -690,6 +692,7 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Blocks\Behaviour" />
<Folder Include="Blocks\Extended" />
<Folder Include="Bots\Instructions" />
<Folder Include="Commands" />
<Folder Include="Commands\building" />