mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-10-06 04:25:05 -04:00
138 lines
3.5 KiB
C#
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;
|
|
}
|
|
}
|
|
} |