/* Thor Server 2.0 Project - Codenamed "Stockholm" Copyright 2008 - 2009 Joe Hegarty This file is part of The Thor Server 2.0 Project - Codenamed "Stockholm". The Thor Server 2.0 Project - Codenamed "Stockholm" is free software: you can redistribute it and/or modify it under the terms of the Microsoft Public License The Thor Server Project 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 Microsoft Public License for more details. You should have received a copy of the Microsoft Public License along with The Thor Server Project. If not, see http://www.opensource.org/licenses/ms-pl.html */ using System; using System.IO; using StockholmLibrary.Util; using StockholmLibrary.Game.Packets.Client; using StockholmLibrary.Game.Packets.Server; namespace StockholmLibrary.Net { //------------------------------------ public class ClientPacketDeserialiser { private Peer _peer; //********************************************** public Peer Peer { get { return _peer; } } //********************************************** public virtual void Deserialise(ClientPacket packet) { _peer = packet.Peer; } } //------------------------------------ public class ClientPacket { public const int LENGTH_HEADER_LENGTH = 3; private const int HEADER_LENGTH = 2; private Peer _peer; private MemoryStream _buffer; private EClientPacket _packetType; //********************************************** public Peer Peer { get { return _peer; } } //********************************************** public EClientPacket PacketType { get { return _packetType; } } //********************************************** public MemoryStream Buffer { get { return _buffer; } } //********************************************** public void InitialisePacket(Peer peer, byte[] packetData) { _peer = peer; _buffer = new MemoryStream(packetData); this.DerialiseHeader(); } //********************************************** private void DerialiseHeader() { int headerNum = B64Encoding.DecodeInt(ReadBytes(HEADER_LENGTH), HEADER_LENGTH); if (Enum.IsDefined(typeof(EClientPacket), headerNum)) { _packetType = (EClientPacket)headerNum; } else { _packetType = EClientPacket.INVALID; Logging.LogEvent("Client Packet", "Unknown packet type " + headerNum, Logging.ELogLevel.WARNING); } } //********************************************** public byte[] ReadBytes(int length) { byte[] result = new byte[length]; _buffer.Read(result, 0, length); return result; } //********************************************** public string ReadString(int length) { return Conversion.ByteToStringArray(ReadBytes(length)); } //********************************************** public string ReadArgumentString() { int stringLength = B64Encoding.DecodeInt(ReadBytes(2)); return ReadString(stringLength); } //********************************************** public int ReadArgumentInt() { return B64Encoding.DecodeInt(ReadBytes(2)); } //********************************************** public int ReadWholePacketAsInt() { return int.Parse(ReadString((int) (_buffer.Length - _buffer.Position))); } //********************************************** public string ReadWholePacketAsString() { return ReadString((int) (_buffer.Length - _buffer.Position)); } //********************************************** public int ReadB64Int(int length = 2) { return B64Encoding.DecodeInt(ReadBytes(length)); } //********************************************** public int ReadWiredInt() { int result = 0; int size = 0; long currentPosition = _buffer.Position; byte[] buffer = ReadBytes(10); result = VL64Encoding.DecodeInt(buffer, out size); _buffer.Seek(currentPosition + size, SeekOrigin.Begin); return result; } } //------------------------------------ public class ServerPacket { private const int HEADER_LENGTH = 2; private const byte PACKET_DELIMITER = (byte)0x01; private object _serialiseLock = new object(); private byte[] _result = null; private MemoryStream _buffer; protected EServerPacket _packetType; //********************************************** public ServerPacket() { } //********************************************** public ServerPacket(EServerPacket packetType) { _packetType = packetType; } //********************************************** public byte[] Serialise() { lock (_serialiseLock) { if (_result == null) { _buffer = new MemoryStream(); SerialiseHeader(); SerialiseBody(); SerialiseFooter(); _result = _buffer.ToArray(); _buffer = null; } } return _result; } //********************************************** protected void SerialiseHeader() { byte[] header = B64Encoding.EncodeInt((int)_packetType, HEADER_LENGTH); WriteBytesRaw(header); } //********************************************** protected virtual void SerialiseBody() { } //********************************************** protected void SerialiseFooter() { _buffer.WriteByte(PACKET_DELIMITER); } //********************************************** protected void WriteBytesRaw(byte[] data) { if (data != null && data.Length > 0) { _buffer.Write(data, 0, data.Length); } } //********************************************** protected void WriteStringRaw(string data) { WriteBytesRaw(Conversion.StringToByteArray(data)); } //********************************************** protected void WriteIntWired(int data) { byte[] dataOut = VL64Encoding.EncodeInt(data); WriteBytesRaw(dataOut); } //********************************************** protected void WriteIntWired(int? data) { int value = data == null ? 0 : (int) data; WriteIntWired(value); } //********************************************** protected void WriteBoolWired(bool data) { int value = data == true ? 1 : 0; WriteIntWired(value); } //********************************************** protected void WriteBoolWired(bool? data) { int value = data == true ? 1 : 0; WriteIntWired(value); } //********************************************** protected void WriteByteRaw(byte data) { _buffer.WriteByte(data); } //********************************************** protected void WriteByte(int data) { _buffer.WriteByte((byte) data); } //********************************************** protected void WriteStringAssignment(string key, string value) { WriteStringRaw(key); WriteByte(0x3D); // = WriteStringRaw(value); WriteByte(0xD); // chr13 } //********************************************** protected void WriteStringAssignment(string key, int value) { WriteStringRaw(key); WriteByte(0x3D); // = WriteStringInt(value); WriteByte(0xD); // chr13 } //********************************************** protected void WriteStringSet(string key, string value) { WriteStringRaw(key); WriteByte(0x3A); // : WriteStringRaw(value); WriteByte(0xD); // chr13 } //********************************************** protected void WriteStringSet(string key, int value) { WriteStringRaw(key); WriteByte(0x3A); // : WriteStringInt(value); WriteByte(0xD); // chr13 } //********************************************** protected void WriteStringInt(int value) { WriteStringRaw(value.ToString()); } //********************************************** protected void WriteStringFloat(float value) { WriteStringRaw(value.ToString().Replace(",", ".")); } //********************************************** protected void WriteListDelimiter() { _buffer.WriteByte((byte)0x02); } //********************************************** protected void WriteDelimitedString(string value, byte delimiter) { WriteStringRaw(value); WriteByte(delimiter); } } }