From 1d042fccaab65f7f4ad21b0a84e52df0155448f4 Mon Sep 17 00:00:00 2001 From: high Date: Tue, 2 Aug 2011 17:16:56 -0400 Subject: [PATCH] Added packet buffering --- TShockAPI/ConfigFile.cs | 2 + TShockAPI/LinqExt.cs | 19 ++++++++ TShockAPI/PacketBufferer.cs | 92 +++++++++++++++++++++++++++++++++++++ TShockAPI/TShock.cs | 9 ++-- TShockAPI/TShockAPI.csproj | 4 +- 5 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 TShockAPI/LinqExt.cs create mode 100644 TShockAPI/PacketBufferer.cs diff --git a/TShockAPI/ConfigFile.cs b/TShockAPI/ConfigFile.cs index e77f4d25..c48d88d3 100644 --- a/TShockAPI/ConfigFile.cs +++ b/TShockAPI/ConfigFile.cs @@ -110,6 +110,8 @@ namespace TShockAPI /// public string HashAlgorithm = "sha512"; + public bool BufferPackets = false; + public static ConfigFile Read(string path) { if (!File.Exists(path)) diff --git a/TShockAPI/LinqExt.cs b/TShockAPI/LinqExt.cs new file mode 100644 index 00000000..b8a891ed --- /dev/null +++ b/TShockAPI/LinqExt.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace TShockAPI +{ + public static class LinqExt + { + public static void ForEach(this IEnumerable source, Action action) + { + if (source == null) throw new ArgumentNullException("source"); + if (action == null) throw new ArgumentNullException("action"); + + foreach (T item in source) + action(item); + } + } +} diff --git a/TShockAPI/PacketBufferer.cs b/TShockAPI/PacketBufferer.cs new file mode 100644 index 00000000..5bdd745f --- /dev/null +++ b/TShockAPI/PacketBufferer.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Net.Sockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Xna.Framework; +using Terraria; +using TerrariaAPI.Hooks; + +namespace TShockAPI +{ + public class PacketBufferer : IDisposable + { + /// + /// Maximum number of bytes to send per update per socket + /// + public int BytesPerUpdate { get; set; } + + PacketBuffer[] buffers = new PacketBuffer[Netplay.serverSock.Length]; + + public PacketBufferer() + { + BytesPerUpdate = 0xFFFF; + buffers.ForEach(p => p = new PacketBuffer()); + + ServerHooks.SendBytes += ServerHooks_SendBytes; + ServerHooks.SocketReset += ServerHooks_SocketReset; + GameHooks.PostUpdate += GameHooks_Update; + } + + public void Dispose() + { + GameHooks.PostUpdate -= GameHooks_Update; + ServerHooks.SendBytes -= ServerHooks_SendBytes; + ServerHooks.SocketReset -= ServerHooks_SocketReset; + } + + + void GameHooks_Update(GameTime obj) + { + for (int i = 0; i < Netplay.serverSock.Length; i++) + { + if (Netplay.serverSock[i] == null || !Netplay.serverSock[i].active) + continue; + + if (!Netplay.serverSock[i].tcpClient.Client.Poll(0, SelectMode.SelectWrite)) + continue; + + byte[] buff = buffers[i].GetBytes(BytesPerUpdate); + Netplay.serverSock[i].networkStream.Write(buff, 0, buff.Length); + } + } + + + void ServerHooks_SocketReset(ServerSock socket) + { + buffers[socket.whoAmI] = new PacketBuffer(); + } + + void ServerHooks_SendBytes(ServerSock socket, byte[] buffer, int offset, int count, HandledEventArgs e) + { + e.Handled = true; + lock (buffers[socket.whoAmI]) + { + buffers[socket.whoAmI].AddRange(new MemoryStream(buffer, offset, count).ToArray()); + } + } + + + } + + public class PacketBuffer : List + { + public byte[] GetBytes(int max) + { + lock (this) + { + if (this.Count < 1) + return null; + + var ret = new byte[Math.Min(max, this.Count)]; + this.CopyTo(0, ret, 0, ret.Length); + this.RemoveRange(0, ret.Length); + return ret; + } + } + } +} diff --git a/TShockAPI/TShock.cs b/TShockAPI/TShock.cs index 4be71218..0639f2a9 100755 --- a/TShockAPI/TShock.cs +++ b/TShockAPI/TShock.cs @@ -61,15 +61,11 @@ namespace TShockAPI public static UserManager Users; public static ItemManager Itembans; public static RemeberedPosManager RememberedPos; - public static ConfigFile Config { get; set; } - public static IDbConnection DB; - - public static Process TShockProcess; public static bool OverridePort; + PacketBufferer bufferer; - public static double ElapsedTime; public override Version Version { @@ -186,6 +182,9 @@ namespace TShockAPI Commands.InitCommands(); //RconHandler.StartThread(); + if (Config.BufferPackets) + bufferer = new PacketBufferer(); + Log.ConsoleInfo("AutoSave " + (Config.AutoSave ? "Enabled" : "Disabled")); Log.ConsoleInfo("Backups " + (Backups.Interval > 0 ? "Enabled" : "Disabled")); } diff --git a/TShockAPI/TShockAPI.csproj b/TShockAPI/TShockAPI.csproj index b81003fc..f62ad74a 100644 --- a/TShockAPI/TShockAPI.csproj +++ b/TShockAPI/TShockAPI.csproj @@ -104,10 +104,12 @@ + + @@ -171,7 +173,7 @@ - +