Sistema consiste em um modo mais eficiente, por assim dizer, de se enviar e receber informações entre client e server. Eu fiz pelo simples fato de ser algo de certa forma essencial para o desenvolvimento do jogo visto que hoje a maioria dos netplays e jogos online usam ou Regex ou análise de strings, sem exceções.
Mas o que é exatamente?
A classe traduz qualquer tipo de dado (dados numéricos apenas signed) para bytes.
Compatibilidade com outras linguagens
A para ler os dados é necessária uma implementação desses métodos na mesma. Na plataforma .net já existe o BitConverter que pode ler inteiros, long, boolean, short e byte, para strings é necessário usar a codificação de caracteres 1252 (Encoding.GetEncoding (1252)) ou UTF7, só assim os caracteres especiais serão lidos corretamente.
Porque é mais eficiente?
Simples, o uso da Regex para obter informações de um texto recebido é lento pois consiste na análise completa do texto, verificação de tipos e captura de grupos. Outro método usado é a análise de textos usando um separador, que é basicamente o que esse sistema faz porém o ByteBuffer não usa separadores e isso economiza alguns bytes (significantes se o dado for grande). Outro ponto a se observar é que com separação de textos é necessário fazer o cast do valor para o tipo de dado que deseja obter, isso já não existe neste sistema.
O sistema é completo, com suporte a acentuação e caracteres especiais contidos na tabela de codificação ASCII/ISO-8859-1.
Antes que perguntem, o sistema é compatível com RMXP.
Mas o que é exatamente?
A classe traduz qualquer tipo de dado (dados numéricos apenas signed) para bytes.
Compatibilidade com outras linguagens
A para ler os dados é necessária uma implementação desses métodos na mesma. Na plataforma .net já existe o BitConverter que pode ler inteiros, long, boolean, short e byte, para strings é necessário usar a codificação de caracteres 1252 (Encoding.GetEncoding (1252)) ou UTF7, só assim os caracteres especiais serão lidos corretamente.
Porque é mais eficiente?
Simples, o uso da Regex para obter informações de um texto recebido é lento pois consiste na análise completa do texto, verificação de tipos e captura de grupos. Outro método usado é a análise de textos usando um separador, que é basicamente o que esse sistema faz porém o ByteBuffer não usa separadores e isso economiza alguns bytes (significantes se o dado for grande). Outro ponto a se observar é que com separação de textos é necessário fazer o cast do valor para o tipo de dado que deseja obter, isso já não existe neste sistema.
O sistema é completo, com suporte a acentuação e caracteres especiais contidos na tabela de codificação ASCII/ISO-8859-1.
Antes que perguntem, o sistema é compatível com RMXP.
- Código:
#============================================================================================
# ** ByteBuffer
#--------------------------------------------------------------------------------------------
# Autor Paulo Soreto
# Versão 1.3
# Data 15/06/2016
#--------------------------------------------------------------------------------------------
# * Corrigido incompatibilidade com RPG Maker XP
# * Adicionado suporte a caracteres especiais
#============================================================================================
class ByteBuffer
#--------------------------------------------------------------------------------------------
# Tabela ASCII/ISO-8859-1
#--------------------------------------------------------------------------------------------
ISO88591 = {
160 => 'NBSP', 161 => '¡', 162 => '¢', 163 => '£', 164 => '¤', 165 => '¥',
166 => '¦', 167 => '§', 168 => '¨', 169 => '©', 170 => 'ª', 171 => '«',
172 => '¬', 173 => 'SHY', 174 => '®', 175 => '¯', 176 => '°', 177 => '±',
178 => '²', 179 => '³', 180 => '´', 181 => 'µ', 182 => '¶', 183 => '·',
184 => '¸', 185 => '¹', 186 => 'º', 187 => '»', 188 => '¼', 189 => '½',
190 => '¾', 191 => '¿', 192 => 'À', 193 => 'Á', 194 => 'Â', 195 => 'Ã',
196 => 'Ä', 197 => 'Å', 198 => 'Æ', 199 => 'Ç', 200 => 'È', 201 => 'É',
202 => 'Ê', 203 => 'Ë', 204 => 'Ì', 205 => 'Í', 206 => 'Î', 207 => 'Ï',
208 => 'Ð', 209 => 'Ñ', 210 => 'Ò', 211 => 'Ó', 212 => 'Ô', 213 => 'Õ',
214 => 'Ö', 215 => '×', 216 => 'Ø', 217 => 'Ù', 218 => 'Ú', 219 => 'Û',
220 => 'Ü', 221 => 'Ý', 222 => 'Þ', 223 => 'ß', 224 => 'à', 225 => 'á',
226 => 'â', 227 => 'ã', 228 => 'ä', 229 => 'å', 230 => 'æ', 231 => 'ç',
232 => 'è', 233 => 'é', 234 => 'ê', 235 => 'ë', 236 => 'ì', 237 => 'í',
238 => 'î', 239 => 'ï', 240 => 'ð', 241 => 'ñ', 242 => 'ò', 243 => 'ó',
244 => 'ô', 245 => 'õ', 246 => 'ö', 247 => '÷', 248 => 'ø', 249 => 'ù',
250 => 'ú', 251 => 'û', 252 => 'ü', 253 => 'ý', 254 => 'þ', 255 => 'ÿ',
}
attr_accessor :pointer
attr_reader :bytes
def initialize
@pointer = 0
@bytes = []
end
#--------------------------------------------------------------------------------------------
# * Escreve uma string
#--------------------------------------------------------------------------------------------
def write_string(str)
write_int(str.size)
str.unpack('U*').each { |b| @bytes << b }
end
#--------------------------------------------------------------------------------------------
# * Escreve um valor booleano
#--------------------------------------------------------------------------------------------
def write_bool(b)
ntba(b == true ? 1 : 0, 1).each { |b| @bytes << b }
end
#--------------------------------------------------------------------------------------------
# * Escreve long
#--------------------------------------------------------------------------------------------
def write_long(n)
ntba(n, 8).each { |b| @bytes << b }
end
#--------------------------------------------------------------------------------------------
# * Escreve int
#--------------------------------------------------------------------------------------------
def write_int(n)
ntba(n, 4).each { |b| @bytes << b }
end
#--------------------------------------------------------------------------------------------
# * Escreve short
#--------------------------------------------------------------------------------------------
def write_short(n)
ntba(n, 2).each { |b| @bytes << b }
end
#--------------------------------------------------------------------------------------------
# * Escreve byte
#--------------------------------------------------------------------------------------------
def write_byte(n)
ntba(n, 1).each { |b| @bytes << b }
end
#--------------------------------------------------------------------------------------------
# * Lê uma string
#--------------------------------------------------------------------------------------------
def read_string
len = read_int
str = ''
@bytes[@pointer, len].each { |b| str += b >= 160 ? ISO88591[b] : b.chr }
@pointer += len
return str
end
#--------------------------------------------------------------------------------------------
# * Lê um valor booleano
#--------------------------------------------------------------------------------------------
def read_bool
return batn(1) == 1 ? true : false
end
#--------------------------------------------------------------------------------------------
# * Lê long
#--------------------------------------------------------------------------------------------
def read_long
return batn(8)
end
#--------------------------------------------------------------------------------------------
# * Lê um número
#--------------------------------------------------------------------------------------------
def read_int
return batn(4)
end
#--------------------------------------------------------------------------------------------
# * Lê short
#--------------------------------------------------------------------------------------------
def read_short
return batn(2)
end
#--------------------------------------------------------------------------------------------
# * Lê byte
#--------------------------------------------------------------------------------------------
def read_byte
return batn(1)
end
#--------------------------------------------------------------------------------------------
# * Libera a memória usada
#--------------------------------------------------------------------------------------------
def dispose
@pointer = nil
@bytes = nil
end
#--------------------------------------------------------------------------------------------
# * Number to Byte Array
#--------------------------------------------------------------------------------------------
def ntba(n, s)
buff = Array.new(s)
0.upto(s - 1) { |i| buff[i] = (n >> (((s - 1) - i) * 8)) & 0xFF }
return buff
end
#--------------------------------------------------------------------------------------------
# * Byte Array to Number
#--------------------------------------------------------------------------------------------
def batn(s)
b = @bytes[@pointer, s]
@pointer += s
value = 0
0.upto(s - 1) { |i| value += (b[i] & 0xFF) << (((s - 1) - i) * 8)}
return value
end
end