2016-09-15 12:02:19 +10:00

138 lines
3.5 KiB
C#

// ClassicalSharp copyright 2014-2016 UnknownShadow200 | Licensed under MIT
using System;
using System.Net.Sockets;
namespace ClassicalSharp.Network {
public class NetReader {
public byte[] buffer = new byte[4096 * 5];
public int index = 0, size = 0;
Socket socket;
public NetReader( Socket socket ) {
this.socket = socket;
}
public void ReadPendingData() {
if( socket.Available == 0 ) return;
// NOTE: Always using a read call that is a multiple of 4096
// (appears to?) improve read performance.
int recv = socket.Receive( buffer, size, 4096 * 4, SocketFlags.None );
size += recv;
}
public void Skip( int byteCount ) {
index += byteCount;
}
public void RemoveProcessed() {
size -= index;
if( size > 0 ) // only copy left over bytes
Buffer.BlockCopy( buffer, index, buffer, 0, size );
index = 0;
// We don't need to zero the old bytes, since they will be overwritten when ReadData() is called.
}
public int ReadInt32() {
int value = buffer[index] << 24 | buffer[index + 1] << 16 |
buffer[index + 2] << 8 | buffer[index + 3];
index += 4;
return value;
}
public short ReadInt16() {
short value = (short)(buffer[index] << 8 | buffer[index + 1]);
index += 2;
return value;
}
public sbyte ReadInt8() {
sbyte value = (sbyte)buffer[index];
index++;
return value;
}
public ushort ReadUInt16() {
ushort value = (ushort)(buffer[index] << 8 | buffer[index + 1]);
index += 2;
return value;
}
public byte ReadUInt8() {
byte value = buffer[index];
index++;
return value;
}
public byte[] ReadBytes( int length ) {
byte[] data = new byte[length];
Buffer.BlockCopy( buffer, index, data, 0, length );
index += length;
return data;
}
public string ReadCp437String() {
int length = GetString( false, Utils.StringLength );
return new String( characters, 0, length );
}
public string ReadAsciiString() {
int length = GetString( true, Utils.StringLength );
return new String( characters, 0, length );
}
public string ReadAsciiString( int maxLength ) {
int length = GetString( true, maxLength );
return new String( characters, 0, length );
}
internal string ReadChatString( ref byte messageType ) {
int length = GetString( false, Utils.StringLength );
int offset = 0;
if( length >= womDetail.Length && IsWomDetailString() ) {
length -= womDetail.Length;
offset = womDetail.Length;
messageType = (byte)MessageType.Status3;
}
return new String( characters, offset, length );
}
static char[] characters = new char[Utils.StringLength];
const string womDetail = "^detail.user=";
static bool IsWomDetailString() {
for( int i = 0; i < womDetail.Length; i++ ) {
if( characters[i] != womDetail[i] )
return false;
}
return true;
}
int GetString( bool ascii, int maxLength ) {
int length = 0;
for( int i = maxLength - 1; i >= 0; i-- ) {
byte code = buffer[index + i];
if( length == 0 && !( code == 0 || code == 0x20 ) )
length = i + 1;
if( ascii ) {
characters[i] = code >= 0x7F ? '?' : (char)code;
continue;
}
// Treat code as an index in code page 437
if( code < 0x20 ) {
characters[i] = Utils.ControlCharReplacements[code];
} else if( code < 0x7F ) {
characters[i] = (char)code;
} else {
characters[i] = Utils.ExtendedCharReplacements[code - 0x7F];
}
}
index += maxLength;
return length;
}
}
}