late-java-core 2.2.9

A Rust library for launching Minecraft Java Edition
use crate::error::{Result, LateJavaCoreError};
use std::io::{Read, Write};

/// Buffer para leer datos de red
pub struct Buffer {
    data: Vec<u8>,
    position: usize,
}

impl Buffer {
    /// Crear un nuevo buffer
    pub fn new() -> Self {
        Self {
            data: Vec::new(),
            position: 0,
        }
    }

    /// Crear buffer con datos
    pub fn from_data(data: Vec<u8>) -> Self {
        Self {
            data,
            position: 0,
        }
    }

    /// Leer byte
    pub fn read_byte(&mut self) -> Result<u8> {
        if self.position >= self.data.len() {
            return Err(LateJavaCoreError::Minecraft("Buffer underflow".to_string()));
        }
        let byte = self.data[self.position];
        self.position += 1;
        Ok(byte)
    }

    /// Leer bytes
    pub fn read_bytes(&mut self, count: usize) -> Result<Vec<u8>> {
        if self.position + count > self.data.len() {
            return Err(LateJavaCoreError::Minecraft("Buffer underflow".to_string()));
        }
        let bytes = self.data[self.position..self.position + count].to_vec();
        self.position += count;
        Ok(bytes)
    }

    /// Leer entero de 16 bits
    pub fn read_short(&mut self) -> Result<i16> {
        let bytes = self.read_bytes(2)?;
        Ok(i16::from_be_bytes([bytes[0], bytes[1]]))
    }

    /// Leer entero de 32 bits
    pub fn read_int(&mut self) -> Result<i32> {
        let bytes = self.read_bytes(4)?;
        Ok(i32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]))
    }

    /// Leer entero de 64 bits
    pub fn read_long(&mut self) -> Result<i64> {
        let bytes = self.read_bytes(8)?;
        Ok(i64::from_be_bytes([
            bytes[0], bytes[1], bytes[2], bytes[3],
            bytes[4], bytes[5], bytes[6], bytes[7]
        ]))
    }

    /// Leer string
    pub fn read_string(&mut self) -> Result<String> {
        let length = self.read_varint()? as usize;
        let bytes = self.read_bytes(length)?;
        String::from_utf8(bytes)
            .map_err(|_| LateJavaCoreError::Minecraft("Invalid UTF-8 string".to_string()))
    }

    /// Leer varint
    pub fn read_varint(&mut self) -> Result<i32> {
        let mut value = 0i32;
        let mut position = 0;
        
        loop {
            let byte = self.read_byte()?;
            value |= ((byte & 0x7F) as i32) << position;
            
            if (byte & 0x80) == 0 {
                break;
            }
            
            position += 7;
            if position >= 32 {
                return Err(LateJavaCoreError::Minecraft("VarInt too long".to_string()));
            }
        }
        
        Ok(value)
    }

    /// Escribir byte
    pub fn write_byte(&mut self, byte: u8) {
        self.data.push(byte);
    }

    /// Escribir bytes
    pub fn write_bytes(&mut self, bytes: &[u8]) {
        self.data.extend_from_slice(bytes);
    }

    /// Escribir entero de 16 bits
    pub fn write_short(&mut self, value: i16) {
        self.write_bytes(&value.to_be_bytes());
    }

    /// Escribir entero de 32 bits
    pub fn write_int(&mut self, value: i32) {
        self.write_bytes(&value.to_be_bytes());
    }

    /// Escribir entero de 64 bits
    pub fn write_long(&mut self, value: i64) {
        self.write_bytes(&value.to_be_bytes());
    }

    /// Escribir string
    pub fn write_string(&mut self, value: &str) -> Result<()> {
        let bytes = value.as_bytes();
        self.write_varint(bytes.len() as i32)?;
        self.write_bytes(bytes);
        Ok(())
    }

    /// Escribir varint
    pub fn write_varint(&mut self, mut value: i32) -> Result<()> {
        loop {
            let mut byte = (value & 0x7F) as u8;
            value >>= 7;
            
            if value != 0 {
                byte |= 0x80;
            }
            
            self.write_byte(byte);
            
            if value == 0 {
                break;
            }
        }
        
        Ok(())
    }

    /// Obtener datos
    pub fn data(&self) -> &[u8] {
        &self.data
    }

    /// Obtener posición actual
    pub fn position(&self) -> usize {
        self.position
    }

    /// Establecer posición
    pub fn set_position(&mut self, position: usize) {
        self.position = position;
    }

    /// Obtener longitud
    pub fn len(&self) -> usize {
        self.data.len()
    }

    /// Verificar si está vacío
    pub fn is_empty(&self) -> bool {
        self.data.is_empty()
    }

    /// Limpiar buffer
    pub fn clear(&mut self) {
        self.data.clear();
        self.position = 0;
    }
}

impl Default for Buffer {
    fn default() -> Self {
        Self::new()
    }
}