mirror of
				https://github.com/ClassiCube/ClassiCube.git
				synced 2025-11-03 19:16:45 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			138 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
		
			3.4 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;
 | 
						|
		}
 | 
						|
	}
 | 
						|
} |