From 5e55da2e4cba59723b52010150ef3bcb3703b4bf Mon Sep 17 00:00:00 2001 From: high Date: Wed, 8 Jun 2011 06:09:07 -0400 Subject: [PATCH] Added sexy StreamExt class Split HandleGetData into several methods. --- TShockAPI/StreamExt.cs | 254 ++++++++++++++++++++ TShockAPI/TShock.cs | 476 +++++++++++++++++++------------------ TShockAPI/TShockAPI.csproj | 3 + 3 files changed, 505 insertions(+), 228 deletions(-) create mode 100644 TShockAPI/StreamExt.cs diff --git a/TShockAPI/StreamExt.cs b/TShockAPI/StreamExt.cs new file mode 100644 index 00000000..a1e2a900 --- /dev/null +++ b/TShockAPI/StreamExt.cs @@ -0,0 +1,254 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace StreamBinary +{ + public static class StreamExt + { + public static void FillBuffer(this Stream stream, byte[] buf, int numBytes) + { + int read; + if (numBytes == 0x1) + { + read = stream.ReadByte(); + if (read == -1) + { + throw new EndOfStreamException("End of stream"); + } + buf[0x0] = (byte)read; + } + else + { + int offset = 0x0; + do + { + read = stream.Read(buf, offset, numBytes - offset); + if (read == 0x0) + { + throw new EndOfStreamException("End of stream"); + } + offset += read; + } + while (offset < numBytes); + } + + } + public static void WriteBoolean(this Stream s, bool num) + { + s.WriteByte((byte)(num ? 1 : 0)); + } + public static void WriteInt8(this Stream s, byte num) + { + s.WriteByte(num); + } + public static void WriteInt16(this Stream s, Int16 num) + { + s.WriteInt8((byte)(num & 0xff)); + s.WriteInt8((byte)(num >> 8)); + } + public static void WriteInt32(this Stream s, Int32 num) + { + s.WriteInt16((Int16)(num & 0xffff)); + s.WriteInt16((Int16)(num >> 16)); + } + public static void WriteInt64(this Stream s, Int64 num) + { + s.WriteInt32((Int32)(num & 0xffffffff)); + s.WriteInt32((Int32)(num >> 32)); + } + public static unsafe void WriteSingle(this Stream s, float num) + { + Int32 n1 = *((Int32*)&num); + s.WriteInt32(n1); + } + public static unsafe void WriteDouble(this Stream s, double num) + { + Int64 n1 = *((Int64*)&num); + s.WriteInt64(n1); + } + public static void WriteBytes(this Stream s, byte[] bytes) + { + s.Write(bytes, 0, bytes.Length); + } + public static void WriteBytesWithLength(this Stream s, byte[] bytes) + { + s.WriteInt32(bytes.Length); + s.WriteBytes(bytes); + } + public static void WriteBytes(this Stream s, byte[] bytes, Int32 len) + { + s.Write(bytes, 0, len); + } + public static void WriteString(this Stream s, string str) + { + if (str == null) + str = string.Empty; + + s.WriteEncodedInt((Int32)str.Length); + if (str.Length > 0) + s.WriteBytes(Encoding.UTF8.GetBytes(str)); + } + public static void WriteEncodedInt(this Stream s, int value) + { + uint num = (uint)value; + while (num >= 0x80) + { + s.WriteInt8((byte)(num | 0x80)); + num = num >> 0x7; + } + s.WriteInt8((byte)num); + } + + public static byte ReadInt8(this Stream s) + { + int read = s.ReadByte(); + if (read == -1) + { + throw new EndOfStreamException("End of stream"); + } + return (byte)read; + } + public static bool ReadBoolean(this Stream s) + { + return s.ReadInt8() != 0; + } + + public static Int16 ReadInt16(this Stream s) + { + byte n1 = s.ReadInt8(); + byte n2 = s.ReadInt8(); + return (Int16)(n1 | (n2 << 8)); + } + public static UInt16 ReadUInt16(this Stream s) + { + byte n1 = s.ReadInt8(); + byte n2 = s.ReadInt8(); + return (UInt16)(n1 | (n2 << 8)); + } + + public static Int32 ReadInt32(this Stream s) + { + Int16 n1 = s.ReadInt16(); + Int16 n2 = s.ReadInt16(); + return (Int32)(n1 | (n2 << 16)); + } + public static UInt32 ReadUInt32(this Stream s) + { + UInt16 n1 = s.ReadUInt16(); + UInt16 n2 = s.ReadUInt16(); + return (UInt32)(n1 | (n2 << 16)); + } + + public static Int64 ReadInt64(this Stream s) + { + Int64 n1 = s.ReadInt32(); + Int64 n2 = s.ReadInt32(); + return (Int64)(n1 | (n2 << 32)); + } + public static UInt64 ReadUInt64(this Stream s) + { + UInt64 n1 = s.ReadUInt32(); + UInt64 n2 = s.ReadUInt32(); + return (n1 | (n2 << 32)); + } + public static unsafe float ReadSingle(this Stream s) + { + var ret = (UInt32)s.ReadUInt32(); + return *((float*)&ret); + } + public static unsafe double ReadDouble(this Stream s) + { + var ret = (UInt64)s.ReadUInt64(); + return *((double*)&ret); + } + + public static byte[] ReadBytes(this Stream s) + { + Int32 len = s.ReadInt32(); + return s.ReadBytes(len); + } + public static byte[] ReadBytes(this Stream s, Int32 len) + { + byte[] ret = new byte[len]; + s.FillBuffer(ret, len); + return ret; + } + public static string ReadString(this Stream s) + { + int len = s.ReadEncodedInt(); + if (len > 0) + return Encoding.UTF8.GetString(s.ReadBytes(len)); + return string.Empty; + } + public static int ReadEncodedInt(this Stream s) + { + byte num3; + int num = 0x0; + int num2 = 0x0; + do + { + if (num2 == 0x23) + { + throw new FormatException("Format_Bad7BitInt32"); + } + num3 = s.ReadInt8(); + num |= (num3 & 0x7f) << num2; + num2 += 0x7; + } + while ((num3 & 0x80) != 0x0); + return num; + } + } + public static class MemoryStreamExt + { + public static void Reset(this MemoryStream ms) + { + ms.Position = 0; + } + } +} + +namespace StreamBinary.Generic +{ + public static class StreamGenericExt + { + static Dictionary> WriteFuncs = new Dictionary>() + { + {typeof(bool), (s, o) => s.WriteBoolean((bool)o)}, + {typeof(byte), (s, o) => s.WriteInt8((byte)o)}, + {typeof(Int16), (s, o) => s.WriteInt16((Int16)o)}, + {typeof(Int32), (s, o) => s.WriteInt32((Int32)o)}, + {typeof(Int64), (s, o) => s.WriteInt64((Int64)o)}, + {typeof(byte[]), (s, o) => s.WriteBytes((byte[])o)}, + {typeof(string), (s, o) => s.WriteString((string)o)}, + }; + public static void Write(this Stream stream, T obj) + { + if (WriteFuncs.ContainsKey(typeof(T))) + { + WriteFuncs[typeof(T)](stream, obj); + return; + } + + throw new NotImplementedException(); + } + static Dictionary> ReadFuncs = new Dictionary>() + { + {typeof(bool), s => s.ReadBoolean()}, + {typeof(byte), s => s.ReadInt8()}, + {typeof(Int16), s => s.ReadInt16()}, + {typeof(Int32), s => s.ReadInt32()}, + {typeof(Int64), s => s.ReadInt64()}, + {typeof(string), s => s.ReadString()}, + }; + public static T Read(this Stream stream) + { + if (ReadFuncs.ContainsKey(typeof(T))) + return (T)ReadFuncs[typeof(T)](stream); + + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index df64c85f..93a87950 100755 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -6,6 +6,7 @@ using System.Net; using System.Text; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; +using StreamBinary; using Terraria; using TerrariaAPI; using TerrariaAPI.Hooks; @@ -30,6 +31,9 @@ namespace TShockAPI public static BanManager Bans = new BanManager(Path.Combine(saveDir, "bans.txt")); + delegate bool HandleGetDataD(MemoryStream data, GetDataEventArgs e); + Dictionary GetDataFuncs; + public override Version Version { get { return VersionNum; } @@ -106,6 +110,22 @@ namespace TShockAPI public TShock(Main game) : base(game) { + + GetDataFuncs = new Dictionary + { + {0x4, HandlePlayerInfo}, + {0xA, HandleSendSection}, + {0xD, HandlePlayerUpdate}, + {0x11, HandleTile}, + {0x14, HandleSendTileSquare}, + {0x17, HandleNpcUpdate}, + {0x1A, HandlePlayerDamage}, + {0x1B, HandleProjectileNew}, + {0x1E, HandleTogglePvp}, + {0x22, HandleTileKill}, + {0x2C, HandlePlayerKillMe}, + {0x30, HandleLiquidSet}, + }; } public override void Initialize() @@ -122,6 +142,7 @@ namespace TShockAPI Version.Revision + " (" + VersionCodename + ") now running."); Log.Initialize(FileTools.SaveDir + "log.txt", LogLevel.All, true); Log.Info("Starting..."); + GameHooks.Initialize += OnPreInit; GameHooks.PostInitialize += OnPostInit; GameHooks.Update += OnUpdate; @@ -203,256 +224,255 @@ namespace TShockAPI } private void GetData(GetDataEventArgs e) - { - e.Handled = e.Handled || HandleGetData(e); - } - - private bool HandleGetData(GetDataEventArgs e) { if (!Netplay.serverSock[e.Msg.whoAmI].active || Netplay.serverSock[e.Msg.whoAmI].kill) - return true; + return; if (Main.verboseNetplay) Debug.WriteLine("{0:X} ({2}): {3} ({1:XX})", e.Msg.whoAmI, e.MsgID, Main.player[e.Msg.whoAmI].dead ? "dead " : "alive", MsgNames[e.MsgID]); - if (e.MsgID == 4) + HandleGetDataD func; + if (GetDataFuncs.TryGetValue(e.MsgID, out func)) { - var ban = Bans.GetBanByName(Main.player[e.Msg.whoAmI].name); - if (ban != null) + using (var data = new MemoryStream(e.Msg.readBuffer, e.Index, e.Length)) { - Tools.ForceKick(e.Msg.whoAmI, "You are banned: " + ban.Reason); - return true; - } - string name = Encoding.ASCII.GetString(e.Msg.readBuffer, e.Index + 23, (e.Length - (e.Index + 23)) + e.Index - 1); - if (name.Length > 32) - { - Tools.ForceKick(e.Msg.whoAmI, "Name exceeded 32 characters."); - return true; - } - if (players[e.Msg.whoAmI] == null) - { - Tools.ForceKick(e.Msg.whoAmI, "Player doesn't exist"); - return true; - } - else if (players[e.Msg.whoAmI].receivedInfo) - { - return Tools.HandleGriefer(e.Msg.whoAmI, "Sent client info more than once"); - } - else - { - players[e.Msg.whoAmI].receivedInfo = true; + e.Handled = func(data, e); } } - else if (e.MsgID == 0x14) - { - using (var br = new BinaryReader(new MemoryStream(e.Msg.readBuffer, e.Index, e.Length))) - { - short size = br.ReadInt16(); - int x = br.ReadInt32(); - int y = br.ReadInt32(); - int plyX = Math.Abs((int)Main.player[e.Msg.whoAmI].position.X / 16); - int plyY = Math.Abs((int)Main.player[e.Msg.whoAmI].position.Y / 16); - int tileX = Math.Abs(x); - int tileY = Math.Abs(y); - if (size > 5 || Math.Abs(plyX - tileX) > 12 || Math.Abs(plyY - tileY) > 12) - { - return Tools.HandleGriefer(e.Msg.whoAmI, "Send Tile Square Abuse"); - } - } - } - else if (e.MsgID == 17) - { - using (var br = new BinaryReader(new MemoryStream(e.Msg.readBuffer, e.Index, e.Length))) - { - byte type = br.ReadByte(); - int x = br.ReadInt32(); - int y = br.ReadInt32(); - byte typetile = br.ReadByte(); - if (type == 1 || type == 3) - { - int plyX = Math.Abs((int)Main.player[e.Msg.whoAmI].position.X / 16); - int plyY = Math.Abs((int)Main.player[e.Msg.whoAmI].position.Y / 16); - int tileX = Math.Abs(x); - int tileY = Math.Abs(y); + } - if ((Math.Abs(plyX - tileX) > 8) || (Math.Abs(plyY - tileY) > 8)) + + + + bool HandlePlayerInfo(MemoryStream data, GetDataEventArgs e) + { + var ban = Bans.GetBanByName(Main.player[e.Msg.whoAmI].name); + if (ban != null) + { + Tools.ForceKick(e.Msg.whoAmI, "You are banned: " + ban.Reason); + return true; + } + string name = Encoding.ASCII.GetString(e.Msg.readBuffer, e.Index + 23, (e.Length - (e.Index + 23)) + e.Index - 1); + if (name.Length > 32) + { + Tools.ForceKick(e.Msg.whoAmI, "Name exceeded 32 characters."); + return true; + } + if (players[e.Msg.whoAmI] == null) + { + Tools.ForceKick(e.Msg.whoAmI, "Player doesn't exist"); + return true; + } + if (players[e.Msg.whoAmI].receivedInfo) + { + return Tools.HandleGriefer(e.Msg.whoAmI, "Sent client info more than once"); + } + + players[e.Msg.whoAmI].receivedInfo = true; + return false; + } + + bool HandleSendTileSquare(MemoryStream data, GetDataEventArgs e) + { + short size = data.ReadInt16(); + int x = data.ReadInt32(); + int y = data.ReadInt32(); + int plyX = Math.Abs((int)Main.player[e.Msg.whoAmI].position.X / 16); + int plyY = Math.Abs((int)Main.player[e.Msg.whoAmI].position.Y / 16); + int tileX = Math.Abs(x); + int tileY = Math.Abs(y); + if (size > 5 || Math.Abs(plyX - tileX) > 12 || Math.Abs(plyY - tileY) > 12) + { + return Tools.HandleGriefer(e.Msg.whoAmI, "Send Tile Square Abuse"); + } + return false; + } + bool HandleTile(MemoryStream data, GetDataEventArgs e) + { + byte type = data.ReadInt8(); + int x = data.ReadInt32(); + int y = data.ReadInt32(); + byte typetile = data.ReadInt8(); + if (type == 1 || type == 3) + { + int plyX = Math.Abs((int)Main.player[e.Msg.whoAmI].position.X / 16); + int plyY = Math.Abs((int)Main.player[e.Msg.whoAmI].position.Y / 16); + int tileX = Math.Abs(x); + int tileY = Math.Abs(y); + + if (Main.player[e.Msg.whoAmI].selectedItem == 0x72) //Dirt Rod + { + return Tools.Kick(e.Msg.whoAmI, "Using dirt rod"); + } + + if ((Math.Abs(plyX - tileX) > 8) || (Math.Abs(plyY - tileY) > 8)) + { + return Tools.HandleGriefer(e.Msg.whoAmI, "Placing impossible to place blocks."); + } + } + if (type == 0 || type == 1) + { + if (ConfigurationManager.spawnProtect) + { + if (!players[e.Msg.whoAmI].group.HasPermission("editspawn")) + { + var flag = CheckSpawn(x, y); + if (flag) { - return Tools.HandleGriefer(e.Msg.whoAmI, "Placing impossible to place blocks."); - } - } - if (type == 0 || type == 1) - { - if (ConfigurationManager.spawnProtect) - { - if (!players[e.Msg.whoAmI].group.HasPermission("editspawn")) - { - var flag = CheckSpawn(x, y); - if (flag) - { - Tools.SendMessage(e.Msg.whoAmI, "Spawn protected from changes.", - new[] { 255f, 0f, 0f }); - return true; - } - } - } - } - - if (type == 0 && BlacklistTiles[Main.tile[x, y].type] && Main.player[e.Msg.whoAmI].active) - { - players[e.Msg.whoAmI].tileThreshold++; - players[e.Msg.whoAmI].tilesDestroyed.Add(new Position(x, y), Main.tile[x, y]); - } - } - } - else if (e.MsgID == 0x1e) - { - using (var br = new BinaryReader(new MemoryStream(e.Msg.readBuffer, e.Index, e.Length))) - { - int id = br.ReadByte(); - bool pvp = br.ReadBoolean(); - - Main.player[e.Msg.whoAmI].hostile = pvp; - if (id != e.Msg.whoAmI) - Main.player[e.Msg.whoAmI].hostile = true; - if (ConfigurationManager.permaPvp) - Main.player[e.Msg.whoAmI].hostile = true; - NetMessage.SendData(30, -1, -1, "", e.Msg.whoAmI); - return true; - } - } - else if (e.MsgID == 0x0A) //SendSection - { - return Tools.HandleGriefer(e.Msg.whoAmI, "SendSection abuse."); - } - else if (e.MsgID == 0x17) //Npc Data - { - return Tools.HandleGriefer(e.Msg.whoAmI, "Spawn NPC abuse"); - } - else if (e.MsgID == 0x0D) //Update Player - { - byte plr = e.Msg.readBuffer[e.Index]; - if (plr != e.Msg.whoAmI) - { - return Tools.HandleGriefer(e.Msg.whoAmI, "Update Player abuse"); - } - } - else if (e.MsgID == 0x1B) // New Projectile - { - using (var br = new BinaryReader(new MemoryStream(e.Msg.readBuffer, e.Index, e.Length))) - { - short ident = br.ReadInt16(); - float posx = br.ReadSingle(); - float posy = br.ReadSingle(); - float velx = br.ReadSingle(); - float vely = br.ReadSingle(); - float knockback = br.ReadSingle(); - short dmg = br.ReadInt16(); - byte owner = br.ReadByte(); - byte type = br.ReadByte(); - - if (type == 29 || type == 28 || type == 37) - { - return Tools.HandleExplosivesUser(e.Msg.whoAmI, "Throwing an explosive device."); - } - } - } - else if (e.MsgID == 0x2C) // KillMe - { - using (var br = new BinaryReader(new MemoryStream(e.Msg.readBuffer, e.Index, e.Length))) - { - byte id = br.ReadByte(); - byte hitdirection = br.ReadByte(); - short dmg = br.ReadInt16(); - bool pvp = br.ReadBoolean(); - - if (id != e.Msg.whoAmI) - { - return Tools.HandleGriefer(e.Msg.whoAmI, "Trying to execute KillMe on someone else."); - } - } - } - else if (e.MsgID == 0x1a) //PlayerDamage - { - using (var br = new BinaryReader(new MemoryStream(e.Msg.readBuffer, e.Index, e.Length))) - { - byte playerid = br.ReadByte(); - byte direction = br.ReadByte(); - Int16 damage = br.ReadInt16(); - byte pvp = br.ReadByte(); - - if (!Main.player[playerid].hostile) - return true; - } - } - else if (e.MsgID == 0x30) - { - using (var br = new BinaryReader(new MemoryStream(e.Msg.readBuffer, e.Index, e.Length))) - { - int x = br.ReadInt32(); - int y = br.ReadInt32(); - byte liquid = br.ReadByte(); - bool lava = br.ReadBoolean(); - - //The liquid was picked up. - if (liquid == 0) - return false; - - if (Main.player[e.Msg.whoAmI].selectedItem == 0x72) //Dirt Rod - { - return Tools.Kick(e.Msg.whoAmI, "Using dirt rod"); - } - - int plyX = Math.Abs((int)Main.player[e.Msg.whoAmI].position.X / 16); - int plyY = Math.Abs((int)Main.player[e.Msg.whoAmI].position.Y / 16); - int tileX = Math.Abs(x); - int tileY = Math.Abs(y); - - int lavacount = 0; - int watercount = 0; - - for (int i = 0; i < 44; i++) - { - if (Main.player[e.Msg.whoAmI].inventory[i].name == "Lava Bucket") - lavacount++; - else if (Main.player[e.Msg.whoAmI].inventory[i].name == "Water Bucket") - watercount++; - } - - if (lava && lavacount <= 0) - { - return Tools.HandleGriefer(e.Msg.whoAmI, "Placing lava they didn't have."); ; - } - else if (!lava && watercount <= 0) - { - return Tools.HandleGriefer(e.Msg.whoAmI, "Placing water they didn't have."); - } - if ((Math.Abs(plyX - tileX) > 6) || (Math.Abs(plyY - tileY) > 6)) - { - return Tools.HandleGriefer(e.Msg.whoAmI, "Placing impossible to place liquid."); ; - } - - if (ConfigurationManager.spawnProtect) - { - if (!players[e.Msg.whoAmI].group.HasPermission("editspawn")) - { - var flag = CheckSpawn(x, y); - if (flag) - { - Tools.SendMessage(e.Msg.whoAmI, "The spawn is protected!", new[] { 255f, 0f, 0f }); - return true; - } + Tools.SendMessage(e.Msg.whoAmI, "Spawn protected from changes.", + new[] { 255f, 0f, 0f }); + return true; } } } } - else if (e.MsgID == 0x22) // Client only KillTile + + if (type == 0 && BlacklistTiles[Main.tile[x, y].type] && Main.player[e.Msg.whoAmI].active) { - return true; // Client only uses it for chests, but sends regular 17 as well. + players[e.Msg.whoAmI].tileThreshold++; + players[e.Msg.whoAmI].tilesDestroyed.Add(new Position(x, y), Main.tile[x, y]); } return false; } + bool HandleTogglePvp(MemoryStream data, GetDataEventArgs e) + { + int id = data.ReadByte(); + bool pvp = data.ReadBoolean(); + + Main.player[e.Msg.whoAmI].hostile = pvp; + if (id != e.Msg.whoAmI) + Main.player[e.Msg.whoAmI].hostile = true; + if (ConfigurationManager.permaPvp) + Main.player[e.Msg.whoAmI].hostile = true; + NetMessage.SendData(30, -1, -1, "", e.Msg.whoAmI); + return true; + } + + bool HandleSendSection(MemoryStream data, GetDataEventArgs e) + { + return Tools.HandleGriefer(e.Msg.whoAmI, "SendSection abuse."); + } + + bool HandleNpcUpdate(MemoryStream data, GetDataEventArgs e) + { + return Tools.HandleGriefer(e.Msg.whoAmI, "Spawn NPC abuse"); + } + + bool HandlePlayerUpdate(MemoryStream data, GetDataEventArgs e) + { + byte plr = e.Msg.readBuffer[e.Index]; + if (plr != e.Msg.whoAmI) + { + return Tools.HandleGriefer(e.Msg.whoAmI, "Update Player abuse"); + } + return false; + } + + bool HandleProjectileNew(MemoryStream data, GetDataEventArgs e) + { + short ident = data.ReadInt16(); + float posx = data.ReadSingle(); + float posy = data.ReadSingle(); + float velx = data.ReadSingle(); + float vely = data.ReadSingle(); + float knockback = data.ReadSingle(); + short dmg = data.ReadInt16(); + byte owner = data.ReadInt8(); + byte type = data.ReadInt8(); + + if (type == 29 || type == 28 || type == 37) + { + return Tools.HandleExplosivesUser(e.Msg.whoAmI, "Throwing an explosive device."); + } + return false; + } + + bool HandlePlayerKillMe(MemoryStream data, GetDataEventArgs e) + { + byte id = data.ReadInt8(); + byte hitdirection = data.ReadInt8(); + short dmg = data.ReadInt16(); + bool pvp = data.ReadBoolean(); + + if (id != e.Msg.whoAmI) + { + return Tools.HandleGriefer(e.Msg.whoAmI, "Trying to execute KillMe on someone else."); + } + return false; + } + + bool HandlePlayerDamage(MemoryStream data, GetDataEventArgs e) + { + byte playerid = data.ReadInt8(); + byte direction = data.ReadInt8(); + Int16 damage = data.ReadInt16(); + byte pvp = data.ReadInt8(); + + return !Main.player[playerid].hostile; + } + + bool HandleLiquidSet(MemoryStream data, GetDataEventArgs e) + { + int x = data.ReadInt32(); + int y = data.ReadInt32(); + byte liquid = data.ReadInt8(); + bool lava = data.ReadBoolean(); + + //The liquid was picked up. + if (liquid == 0) + return false; + + int plyX = Math.Abs((int)Main.player[e.Msg.whoAmI].position.X / 16); + int plyY = Math.Abs((int)Main.player[e.Msg.whoAmI].position.Y / 16); + int tileX = Math.Abs(x); + int tileY = Math.Abs(y); + + int lavacount = 0; + int watercount = 0; + + for (int i = 0; i < 44; i++) + { + if (Main.player[e.Msg.whoAmI].inventory[i].name == "Lava Bucket") + lavacount++; + else if (Main.player[e.Msg.whoAmI].inventory[i].name == "Water Bucket") + watercount++; + } + + if (lava && lavacount <= 0) + { + return Tools.HandleGriefer(e.Msg.whoAmI, "Placing lava they didn't have."); ; + } + else if (!lava && watercount <= 0) + { + return Tools.HandleGriefer(e.Msg.whoAmI, "Placing water they didn't have."); + } + if ((Math.Abs(plyX - tileX) > 6) || (Math.Abs(plyY - tileY) > 6)) + { + return Tools.HandleGriefer(e.Msg.whoAmI, "Placing impossible to place liquid."); ; + } + + if (ConfigurationManager.spawnProtect) + { + if (!players[e.Msg.whoAmI].group.HasPermission("editspawn")) + { + var flag = CheckSpawn(x, y); + if (flag) + { + Tools.SendMessage(e.Msg.whoAmI, "The spawn is protected!", new[] { 255f, 0f, 0f }); + return true; + } + } + } + return false; + } + + bool HandleTileKill(MemoryStream data, GetDataEventArgs e) + { + return true; + } + private void OnGreetPlayer(int who, HandledEventArgs e) { if (Main.netMode != 2) diff --git a/TShockAPI/TShockAPI.csproj b/TShockAPI/TShockAPI.csproj index 902236d9..980a61d2 100644 --- a/TShockAPI/TShockAPI.csproj +++ b/TShockAPI/TShockAPI.csproj @@ -21,6 +21,7 @@ DEBUG;TRACE prompt 4 + true pdbonly @@ -29,6 +30,7 @@ TRACE prompt 4 + true @@ -66,6 +68,7 @@ True Resources.resx +