diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 64fc1322..b67f9e9a 100755 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -181,7 +181,7 @@ namespace TShockAPI int tilex = args.Data.ReadInt32(); int tiley = args.Data.ReadInt32(); - if (size != 3) + if (size > 5) return true; var tiles = new NetTile[size, size]; @@ -220,6 +220,13 @@ namespace TShockAPI tile.type = 0x1; changed = true; } + else if ((tile.type == 0xF && newtile.Type == 0xF) || + (tile.type == 0x4F && newtile.Type == 0x4F)) + { + tile.frameX = newtile.FrameX; + tile.frameY = newtile.FrameY; + changed = true; + } } } @@ -294,7 +301,7 @@ namespace TShockAPI args.Player.SendMessage("Spawn protected from changes.", Color.Red); args.Player.LastTileChangeNotify = DateTime.UtcNow; } - args.Player.SendTileSquare(x, y); + args.Player.SendTileSquare(x, y); return true; } } diff --git a/TShockAPI/Net/WorldInfoMsg.cs b/TShockAPI/Net/WorldInfoMsg.cs new file mode 100644 index 00000000..913b976c --- /dev/null +++ b/TShockAPI/Net/WorldInfoMsg.cs @@ -0,0 +1,87 @@ +/* +TShock, a server mod for Terraria +Copyright (C) 2011 The TShock Team + +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 3 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, see . +*/ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using Terraria; +using TerrariaAPI; +using XNAHelpers; + +namespace TShockAPI.Net +{ + [Flags] + public enum WorldInfoFlag : byte + { + None = 0, + OrbSmashed = 1, + DownedBoss1 = 2, + DownedBoss2 = 4, + DownedBoss3 = 8, + } + public class WorldInfoMsg : IPackable + { + public int Time { get; set; } + public bool DayTime { get; set; } + public byte MoonPhase { get; set; } + public bool BloodMoon { get; set; } + public int MaxTilesX { get; set; } + public int MaxTilesY { get; set; } + public int SpawnX { get; set; } + public int SpawnY { get; set; } + public int WorldSurface { get; set; } + public int RockLayer { get; set; } + public int WorldID { get; set; } + public WorldInfoFlag WorldFlags { get; set; } + public string WorldName { get; set; } + public void PackFull(Stream stream) + { + long start = stream.Position; + stream.WriteInt32(1); + stream.WriteInt8((byte)PacketTypes.WorldInfo); + Pack(stream); + long end = stream.Position; + stream.Position = start; + stream.WriteInt32((int)(end - start) - 4); + stream.Position = end; + } + public void Pack(Stream stream) + { + stream.Write(Time); + stream.Write(DayTime); + stream.Write(MoonPhase); + stream.Write(BloodMoon); + stream.Write(MaxTilesX); + stream.Write(MaxTilesY); + stream.Write(SpawnX); + stream.Write(SpawnY); + stream.Write(WorldSurface); + stream.Write(RockLayer); + stream.Write(WorldID); + stream.Write((byte)WorldFlags); + stream.Write(Encoding.ASCII.GetBytes(WorldName)); + } + + public void Unpack(Stream stream) + { + throw new NotImplementedException(); + } + } +} diff --git a/TShockAPI/Properties/AssemblyInfo.cs b/TShockAPI/Properties/AssemblyInfo.cs index 66169d98..09c15782 100644 --- a/TShockAPI/Properties/AssemblyInfo.cs +++ b/TShockAPI/Properties/AssemblyInfo.cs @@ -35,5 +35,5 @@ using System.Runtime.InteropServices; // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.3.2.0704")] -[assembly: AssemblyFileVersion("2.3.2.0704")] +[assembly: AssemblyVersion("2.3.4.0708")] +[assembly: AssemblyFileVersion("2.3.4.0708")] diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index f6507e50..2974ab4e 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -17,9 +17,11 @@ along with this program. If not, see . */ using System; using System.Collections.Generic; +using System.IO; using Microsoft.Xna.Framework; using Terraria; using TerrariaAPI; +using TShockAPI.Net; namespace TShockAPI { @@ -43,7 +45,6 @@ namespace TShockAPI public Vector2 oldSpawn = Vector2.Zero; public TSPlayer LastWhisper; public int LoginAttempts { get; set; } - public bool Teleporting = false; public Vector2 TeleportCoords = new Vector2(-1, -1); Player FakePlayer = null; @@ -87,17 +88,17 @@ namespace TShockAPI } public float X { - get + get { - return RealPlayer ? TPlayer.position.X : Main.spawnTileX * 16; + return RealPlayer ? TPlayer.position.X : Main.spawnTileX * 16; } } public float Y { - get + get { - return RealPlayer ? TPlayer.position.Y : Main.spawnTileY * 16; + return RealPlayer ? TPlayer.position.Y : Main.spawnTileY * 16; } } public int TileX @@ -148,18 +149,44 @@ namespace TShockAPI SendData(PacketTypes.Disconnect, reason); } - public bool Teleport(int tileX, int tileY) + void SendTeleport(int tilex, int tiley) + { + var msg = new WorldInfoMsg + { + Time = (int)Main.time, + DayTime = Main.dayTime, + MoonPhase = (byte)Main.moonPhase, + BloodMoon = Main.bloodMoon, + MaxTilesX = Main.maxTilesX, + MaxTilesY = Main.maxTilesY, + SpawnX = tilex, + SpawnY = tiley, + WorldSurface = (int)Main.worldSurface, + RockLayer = (int)Main.rockLayer, + WorldID = Main.worldID, + WorldFlags = (WorldGen.shadowOrbSmashed ? WorldInfoFlag.OrbSmashed : WorldInfoFlag.None) | + (NPC.downedBoss1 ? WorldInfoFlag.DownedBoss1 : WorldInfoFlag.None) | + (NPC.downedBoss2 ? WorldInfoFlag.DownedBoss2 : WorldInfoFlag.None) | + (NPC.downedBoss3 ? WorldInfoFlag.DownedBoss3 : WorldInfoFlag.None), + WorldName = Main.worldName + }; + + + var ms = new MemoryStream(); + msg.PackFull(ms); + SendRawData(ms.ToArray()); + } + + public bool Teleport(int tilex, int tiley) { InitSpawn = false; - Teleporting = true; - TeleportCoords = new Vector2(tileX, tileY); - SendData(PacketTypes.WorldInfo); + SendTeleport(tilex, tiley); //150 Should avoid all client crash errors //The error occurs when a tile trys to update which the client hasnt load yet, Clients only update tiles withen 150 blocks //Try 300 if it does not work (Higher number - Longer load times - Less chance of error) - if (!SendTileSquare(tileX, tileY, 150)) + if (!SendTileSquare(tilex, tiley, 150)) { SendMessage("Warning, teleport failed due to being too close to the edge of the map.", Color.Red); return false; @@ -195,23 +222,30 @@ namespace TShockAPI } } - Teleporting = false; - SendData(PacketTypes.WorldInfo); + SendTeleport(Main.spawnTileX, Main.spawnTileY); return true; } public void Spawn() { - SendData(PacketTypes.PlayerSpawn, "", Index, 0.0f, 0.0f, 0.0f); + SendData(PacketTypes.PlayerSpawn, "", Index, 0.0f, 0.0f, 0.0f); } public virtual bool SendTileSquare(int x, int y, int size = 10) { if (x + size >= Main.maxTilesX || y + size >= Main.maxTilesX) return false; - SendData(PacketTypes.TileSendSquare, "", size, (float)(x - (size / 2)), (float)(y - (size / 2)), 0f); - return true; + try + { + SendData(PacketTypes.TileSendSquare, "", size, (float)(x - (size / 2)), (float)(y - (size / 2))); + return true; + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + return false; } public virtual void GiveItem(int type, string name, int width, int height, int stack) @@ -287,17 +321,39 @@ namespace TShockAPI } //Todo: Separate this into a few functions. SendTo, SendToAll, etc - public void SendData(PacketTypes msgType, string text = "", int number = 0, float number2 = 0f, float number3 = 0f, float number4 = 0f, int number5 = 0) + public virtual void SendData(PacketTypes msgType, string text = "", int number = 0, float number2 = 0f, float number3 = 0f, float number4 = 0f, int number5 = 0) { if (RealPlayer && !ConnectionAlive) return; NetMessage.SendData((int)msgType, Index, -1, text, number, number2, number3, number4, number5); } + + public virtual bool SendRawData(byte[] data) + { + if (!RealPlayer || !ConnectionAlive) + return false; + + try + { + if (Netplay.serverSock[Index].tcpClient.Connected) + { + Netplay.serverSock[Index].networkStream.Write(data, 0, data.Length); + return true; + } + + } + catch (Exception ex) + { + Log.Error(ex.ToString()); + } + return false; + } } public class TSServerPlayer : TSPlayer { - public TSServerPlayer() : base("Server") + public TSServerPlayer() + : base("Server") { Group = new SuperAdminGroup(); } @@ -356,7 +412,7 @@ namespace TShockAPI foreach (KeyValuePair entry in destroyedTiles) { Main.tile[(int)entry.Key.X, (int)entry.Key.Y] = entry.Value; - Log.Debug(string.Format("Reverted DestroyedTile(TileXY:{0}_{1}, Type:{2})", + Log.Debug(string.Format("Reverted DestroyedTile(TileXY:{0}_{1}, Type:{2})", entry.Key.X, entry.Key.Y, Main.tile[(int)entry.Key.X, (int)entry.Key.Y].type)); } // Send all players updated tile sqaures diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 2cd61ed6..ba7d5e91 100755 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -80,18 +80,18 @@ namespace TShockAPI { HandleCommandLine(Environment.GetCommandLineArgs()); - ConfigFile.ConfigRead += OnConfigRead; - - Bans = new BanManager(FileTools.BansPath); - Backups = new BackupManager(Path.Combine(SavePath, "backups")); - - FileTools.SetupConfig(); - #if DEBUG Log.Initialize(Path.Combine(SavePath, "log.txt"), LogLevel.All, false); #else Log.Initialize(Path.Combine(SavePath, "log.txt"), LogLevel.All & ~LogLevel.Debug, false); #endif + AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; + + Bans = new BanManager(FileTools.BansPath); + Backups = new BackupManager(Path.Combine(SavePath, "backups")); + + ConfigFile.ConfigRead += OnConfigRead; + FileTools.SetupConfig(); Log.ConsoleInfo(string.Format("TShock Version {0} ({1}) now running.", Version, VersionCodename)); @@ -104,10 +104,8 @@ namespace TShockAPI ServerHooks.Command += ServerHooks_OnCommand; NetHooks.GetData += GetData; NetHooks.GreetPlayer += OnGreetPlayer; - NetHooks.SendData += OnSendData; NpcHooks.StrikeNpc += NpcHooks_OnStrikeNpc; - WorldHooks.SaveWorld += OnSaveWorld; - AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; + Bans.LoadBans(); GetDataHandlers.InitGetDataHandler(); @@ -131,9 +129,7 @@ namespace TShockAPI ServerHooks.Command -= ServerHooks_OnCommand; NetHooks.GetData -= GetData; NetHooks.GreetPlayer -= OnGreetPlayer; - NetHooks.SendData -= OnSendData; NpcHooks.StrikeNpc -= NpcHooks_OnStrikeNpc; - WorldHooks.SaveWorld -= OnSaveWorld; } /// @@ -297,6 +293,8 @@ namespace TShockAPI private void OnLeave(int ply) { var tsplr = Players[ply]; + Players[ply] = null; + if (tsplr != null && tsplr.ReceivedInfo) { Log.Info(string.Format("{0} left.", tsplr.Name)); @@ -309,8 +307,6 @@ namespace TShockAPI RemeberedPosManager.WriteSettings(); } } - - Players[ply] = null; } private void OnChat(messageBuffer msg, int ply, string text, HandledEventArgs e) @@ -452,53 +448,6 @@ namespace TShockAPI } } - private void OnSendData(SendDataEventArgs e) - { - //TODO - Clean this code up - switch (e.MsgID) - { - case PacketTypes.WorldInfo: - if (e.remoteClient >= 0 && Players[e.remoteClient] != null && Players[e.remoteClient].Teleporting) - { - var stream = new MemoryStream(messageBuffer.writeBufferMax); - var writer = new BinaryWriter(stream); - stream.Position = 4; - writer.Write(BitConverter.GetBytes(7), 0, 1); - writer.Write(BitConverter.GetBytes((int)Main.time)); - writer.Write(BitConverter.GetBytes(Main.dayTime)); - writer.Write((byte)Main.moonPhase); - writer.Write(Main.bloodMoon); - writer.Write(BitConverter.GetBytes(Main.maxTilesX)); - writer.Write(BitConverter.GetBytes(Main.maxTilesY)); - writer.Write(BitConverter.GetBytes((int)Players[e.remoteClient].TeleportCoords.X)); - writer.Write(BitConverter.GetBytes((int)Players[e.remoteClient].TeleportCoords.Y)); - writer.Write(BitConverter.GetBytes((int)Main.worldSurface)); - writer.Write(BitConverter.GetBytes((int)Main.rockLayer)); - writer.Write(BitConverter.GetBytes(Main.worldID)); - writer.Write((byte)(0 + (WorldGen.shadowOrbSmashed ? 1 : 0) + (NPC.downedBoss1 ? 2 : 0) + (NPC.downedBoss2 ? 4 : 0) + (NPC.downedBoss3 ? 8 : 0))); - writer.Write(Encoding.ASCII.GetBytes(Main.worldName)); - var length = (int)(stream.Length - 4); - stream.Position = 0; - writer.Write(length); - NetMessage.buffer[e.remoteClient].writeBuffer = stream.GetBuffer(); - try - { - if (Netplay.serverSock[e.remoteClient].tcpClient.Connected) - { - NetMessage.buffer[e.remoteClient].spamCount++; - Netplay.serverSock[e.remoteClient].networkStream.BeginWrite(NetMessage.buffer[e.remoteClient].writeBuffer, 0, (int)stream.Length, new AsyncCallback(Netplay.serverSock[e.remoteClient].ServerWriteCallBack), Netplay.serverSock[e.remoteClient].networkStream); - } - } - catch { } - NetMessage.buffer[e.remoteClient].writeLocked = false; - e.Handled = true; - } - break; - default: - break; - } - } - private void OnGreetPlayer(int who, HandledEventArgs e) { var player = Players[who]; diff --git a/TShockAPI/TShockAPI.csproj b/TShockAPI/TShockAPI.csproj index 9a054663..b16f3565 100644 --- a/TShockAPI/TShockAPI.csproj +++ b/TShockAPI/TShockAPI.csproj @@ -83,6 +83,7 @@ + @@ -145,7 +146,7 @@ - +