Removed the onsenddata hook and added a raw send command.

Added WorldInfoMsg for constructing the world info packet.
This commit is contained in:
high 2011-07-08 03:42:42 -04:00
parent 2a212629dc
commit 27adb98b6f
4 changed files with 135 additions and 70 deletions

View file

@ -18,12 +18,70 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Terraria;
using TerrariaAPI;
using XNAHelpers;
namespace TShockAPI.Net
{
class WorldInfoMsg
[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();
}
}
}

View file

@ -35,5 +35,5 @@ using System.Runtime.InteropServices;
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.3.2.0707")]
[assembly: AssemblyFileVersion("2.3.2.0707")]
[assembly: AssemblyVersion("2.3.4.0708")]
[assembly: AssemblyFileVersion("2.3.4.0708")]

View file

@ -17,9 +17,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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)
@ -260,17 +294,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();
}
@ -329,7 +385,7 @@ namespace TShockAPI
foreach (KeyValuePair<Vector2, Tile> 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

View file

@ -104,7 +104,6 @@ namespace TShockAPI
ServerHooks.Command += ServerHooks_OnCommand;
NetHooks.GetData += GetData;
NetHooks.GreetPlayer += OnGreetPlayer;
NetHooks.SendData += OnSendData;
NpcHooks.StrikeNpc += NpcHooks_OnStrikeNpc;
@ -130,7 +129,6 @@ namespace TShockAPI
ServerHooks.Command -= ServerHooks_OnCommand;
NetHooks.GetData -= GetData;
NetHooks.GreetPlayer -= OnGreetPlayer;
NetHooks.SendData -= OnSendData;
NpcHooks.StrikeNpc -= NpcHooks_OnStrikeNpc;
}
@ -450,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];