Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Copyright (C) Paul Becker, - All Rights Reserved
- // Unauthorized copying of this file, via any medium is strictly prohibited
- // Proprietary and confidential
- // Written by Paul Becker <paul.becker1@gmx.de>, 08:13
- #region usings
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Net;
- using System.Net.Sockets;
- using Assets.Model.Player;
- using Assets.Network.Packets;
- #endregion
- namespace Assets.Network
- {
- public class Connection : IDisposable
- {
- private readonly Queue<PacketToServer> PacketSendQueue = new Queue<PacketToServer>();
- private readonly MemoryStream ReceiveStream;
- private long AverageUpstream;
- protected DateTime LastUpdate;
- private bool ReadInterestEnabled;
- protected bool Ready = false;
- protected byte[] ReceiveBuffer;
- protected DateTime RevDate = DateTime.Now;
- private bool WriteInterestEnabled;
- protected TcpClient client;
- public Player owner;
- public Connection(TcpClient c)
- {
- client = c;
- ReceiveBuffer = new byte[8192];
- ReceiveStream = new MemoryStream(8192*4);
- }
- public long OldValue { get; set; }
- public void SetClient(TcpClient client)
- {
- this.client = client;
- }
- public string GetRemoteIP()
- {
- return ((IPEndPoint) client.Client.RemoteEndPoint).Address.ToString();
- }
- public void Close()
- {
- OnDisconnect();
- client.Close();
- }
- public virtual void OnConnect()
- {
- BeginRead();
- UnityEngine.Debug.Log("New Connection from " + GetRemoteIP());
- }
- private void BeginRead()
- {
- if (client != null && client.Client != null && client.Connected)
- {
- try
- {
- UnityEngine.Debug.Log("BeginRead");
- client.Client.BeginReceive(ReceiveBuffer, 0, 8192, SocketFlags.None, EndRead, ReceiveBuffer);
- }
- catch (Exception)
- {
- Close();
- UnityEngine.Debug.Log("Close BeginRead");
- }
- }
- else
- {
- UnityEngine.Debug.Log("Readíng wont work due no Connection");
- }
- }
- public virtual void OnDisconnect()
- {
- }
- private void EnableReadInterest()
- {
- if (ReadInterestEnabled)
- return;
- lock (ReceiveStream)
- {
- ReadInterestEnabled = true;
- UnityEngine.Debug.Log("EnableReadInterest");
- // Read First Packet Size then go back at initial position.
- var size =
- BitConverter.ToUInt16(new[] {(byte) ReceiveStream.ReadByte(), (byte) ReceiveStream.ReadByte()}, 0);
- ReceiveStream.Position -= 2;
- while (size > 0 && size <= (ReceiveStream.Length - ReceiveStream.Position))
- {
- //UnityEngine.Debug.Log("Read: " + size + "-byte packet.");
- // Read Packet Data including length
- var data = new byte[size];
- ReceiveStream.Read(data, 0, size);
- // Process packet.
- using (var stream = new MemoryStream(data, 2, data.Length - 2, false))
- {
- using (var rd = new BinaryReader(stream))
- {
- var opcode = 0;
- opcode = rd.ReadByte() & 0xff;
- Type packetType = null;
- PacketHolder.PacketsFromServer.TryGetValue(opcode, out packetType);
- if (packetType == null)
- {
- UnityEngine.Debug.Log("Unknown packet received from AION client, opcode: " +
- string.Format("{0:X}", opcode) + " - size: " + (size - 2));
- }
- else
- {
- var pkt = (PacketFromServer) Activator.CreateInstance(packetType);
- pkt.Write(stream.ToArray(), (int) stream.Position,
- (int) (stream.Length - stream.Position));
- pkt.Position = 0;
- stream.Close();
- UnityEngine.Debug.Log("PktRecv " + GetRemoteIP() + ": " + pkt.GetType().Name + "(" +
- pkt.Length +
- ")");
- pkt.Connection = this;
- pkt.Opcode = opcode;
- try
- {
- pkt.ProcessPacket();
- }
- catch (Exception e)
- {
- UnityEngine.Debug.Log(
- String.Format("Cannot process client packet!\nException -> {0}", e));
- }
- pkt.Close();
- }
- if (ReceiveStream.Length - ReceiveStream.Position > 2)
- {
- size =
- BitConverter.ToUInt16(
- new[] {(byte) ReceiveStream.ReadByte(), (byte) ReceiveStream.ReadByte()}, 0);
- ReceiveStream.Position -= 2;
- }
- else
- size = 0;
- }
- var remaining = (int) (ReceiveStream.Length - ReceiveStream.Position);
- if (remaining > 0)
- {
- // Read Latest Bytes
- var remdata = new byte[remaining];
- ReceiveStream.Read(remdata, 0, remaining);
- ReceiveStream.Position = 0;
- ReceiveStream.Write(remdata, 0, remdata.Length);
- }
- else
- ReceiveStream.Position = 0;
- }
- ReadInterestEnabled = false;
- }
- }
- }
- private void EndRead(IAsyncResult result)
- {
- lock (ReceiveBuffer)
- {
- try
- {
- var received = 0;
- try
- {
- UnityEngine.Debug.Log("EndRead");
- received = client.Client.EndReceive(result);
- }
- catch (Exception)
- {
- OnDisconnect();
- return;
- }
- if (received <= 0)
- {
- OnDisconnect();
- return;
- }
- if (!Ready)
- {
- UnityEngine.Debug.Log("Received a " + received +
- "-byte packet while connection not ready to accept packets.");
- return;
- }
- // This is the full set of data.
- // May contain several packets.
- var data = (byte[]) result.AsyncState;
- lock (ReceiveStream)
- {
- ReceiveStream.Write(data, 0, received);
- }
- if (!ReadInterestEnabled)
- {
- ReceiveStream.SetLength(ReceiveStream.Position);
- ReceiveStream.Position = 0;
- EnableReadInterest();
- }
- }
- catch (Exception e)
- {
- UnityEngine.Debug.Log("Error while processing client data! Exception " + e.Message);
- }
- BeginRead();
- }
- }
- public void SendPacket(PacketToServer packet)
- {
- if (client == null)
- {
- UnityEngine.Debug.LogWarning("Tried to send Pkt without Connection to the Masterserver");
- return;
- }
- lock (PacketSendQueue)
- {
- PacketSendQueue.Enqueue(packet);
- if (!WriteInterestEnabled)
- EnableWriteInterest();
- }
- }
- public void SendPacket(PacketToServer packet, bool closeAfterPacket)
- {
- SendPacket(packet);
- if (closeAfterPacket)
- SendPacket(null);
- }
- private void EnableWriteInterest()
- {
- WriteInterestEnabled = true;
- while (PacketSendQueue.Count > 0)
- {
- var pkt = PacketSendQueue.Dequeue();
- if (pkt == null)
- {
- Close();
- UnityEngine.Debug.LogWarning("Closing Connection");
- return;
- }
- BeginWrite(pkt);
- }
- WriteInterestEnabled = false;
- }
- protected void BeginWrite(PacketToServer packet)
- {
- if (packet == null)
- return;
- try
- {
- // Here, packet is ready to be sent
- packet.Connection = this;
- packet.Position = 0;
- if (!PacketHolder.PacketsToServer.ContainsKey(packet.GetType()))
- {
- UnityEngine.Debug.Log("No opcode defined for " + packet.GetType().Name);
- return;
- }
- var opcode = 0;
- PacketHolder.PacketsToServer.TryGetValue(packet.GetType(), out opcode);
- packet.Opcode = opcode;
- packet.WriteShort(0); // Future length
- packet.WriteByte((byte) opcode); // Opcode
- packet.WritePacket(); // Write contents of packet
- var length = (int) packet.Position;
- byte[] result;
- result = new byte[length];
- Array.Copy(packet.ToArray(), 0, result, 0, length);
- packet.Position = 0;
- packet.WriteShort((short) length);
- packet.Write(result, 2, length - 2);
- // Send in socket
- lock (client)
- {
- client.Client.BeginSend(packet.ToArray(), 0, length, SocketFlags.None, EndWrite, packet);
- }
- if (!Ready)
- Ready = true;
- }
- catch (Exception e)
- {
- UnityEngine.Debug.Log(DateTime.Now.ToLongTimeString() + " : Error while writing to data sink!" +
- e.Message);
- UnityEngine.Debug.LogWarning(client.Connected);
- }
- }
- private void EndWrite(IAsyncResult result)
- {
- UnityEngine.Debug.Log(DateTime.Now.ToLongTimeString() + " : Entering EndWrite Area");
- if (client != null && client.Client != null && client.Client.Connected)
- {
- var sent = client.Client.EndSend(result);
- var pkt = (PacketToServer) result.AsyncState;
- if (owner.ShowNetworkStat)
- {
- LastUpdate = DateTime.Now;
- AverageUpstream += pkt.Length;
- var interval = LastUpdate - RevDate;
- if (interval.TotalSeconds >= owner.ShowStatIntervall)
- {
- RevDate = DateTime.Now;
- AverageUpstream = 0;
- OldValue = AverageUpstream;
- }
- }
- UnityEngine.Debug.Log(DateTime.Now.ToLongTimeString() + " : PktSend " + GetRemoteIP() + ": " +
- pkt.GetType().Name + " (" + pkt.Length +
- ") Opcode: " +
- pkt.Opcode);
- }
- else
- {
- UnityEngine.Debug.Log(String.Format("{0},{1},{2}", client != null, client.Client != null,
- client.Client.Connected));
- }
- }
- public void PrintUpstreamToServer(int intervall)
- {
- UnityEngine.Debug.Log(String.Format("{0} -> {1}bytes Upstream in the last {2} seconds",
- DateTime.Now.ToLongTimeString(), OldValue, intervall));
- }
- #region IDisposable Member
- public void Dispose()
- {
- ReceiveStream.Dispose();
- PacketSendQueue.Clear();
- }
- #endregion
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement