UnknownShadow200 98d435b110 fix licensing
2017-01-20 09:12:04 +11:00

138 lines
3.4 KiB
C#

// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
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;
}
}
}