GS-Zone

[ DESTACADO ] Protocolo binario(parte 2) Ir al Indice

Moderadores: Moderadores de Argentum, Especialistas de Argentum, Especialistas de Programación

26

Nota » 05 Nov 2011 02:35

holaa a todos !

primero que nada quisiera aclarar que este post vendría a ser la "segunda parte" de este

protocolo_binario_tcCB.html

este explicaba como enviar un paquete desde el servidor al cliente a un index(usuario, cliente) específico, yo ahora les voy a explicar como enviar un paquete desde el cliente al servidor, de distintas formas, voy a tratar de ser lo más explicativo posible

primero que nada tenemos que saber 2 cosas

1º : Hay un enum donde se guardan todos los ID(Identificadores) de los paquetes que se envian desde el cliente al servidor, el mismo está en ambos lados(cliente-servidor) llamado "Private Enum ClienTpacketid".

2º : La información que enviamos desde el cliente al servidor, se envia por funciones que están dentro de una clase (clsByteQueue) y el cliente la usa como "outgoingdata" para enviar paquetes y "incomingdata" para recibirlos.

vamos a ejemplificar esto, lo primero que debemos hacer es en el enum que aclaré anteriormente agregar un nuevo identificador , para hacer esto nos vamos al cliente y buscaremos



y ahí dentro ubicaremos un nuevo paquete , al cual le pondremos



tiene que ser obviamente antes del "End Enum"

ahora que ya tenemos declarado el identificador, vamos a crear una rutina que envie al servidor datos.

al final del módulo protocol.bas pondremos esto

  1. Public Sub Prueba()
  2. call outgoingdata.writebyte(clientpacketid.Prueba)
  3. call outgoingdata.writeasciistring("Esto es una prueba!")
  4. end sub


NOTA: Por cuestiones de prolijidad se le pone un "Write" adelante del nombre de la rutina y seguido el nombre del paquete, pero podemos usar el que nos guste.

aquí les explicaré más o menos que hicimos en esta rutina(sub)

  1. call outgoingdata.writebyte(clientpacketid.Prueba)


con esto le enviamos al servidor(mediante outgoingdata) el packetID , que el servidor recibirá y hará lo que nosotros le indiquemos.

  1. call outgoingdata.writeasciistring("Esto es una prueba!")


con esto le enviamos una cadena de carácteres (string) al servidor, en este caso sería "Esto es una prueba!"

con esto listo, nos posicionamos en el servidor, y haremos lo siguente.

Buscaremos el enum "Private Enum ClientPacketID", y agregaremos antes del end enum , y presten atención : SIEMPRE TIENE QUE TENER EL MISMO ORDEN TANTO EN CLIENTE-SERVIDOR NUESTRO PAQUETE IDENTIFICADOR, por cuestiones que explicaré más abajo.

bueno, agregamos en el mismo orden que en el cliente



ahora el servidor ya sabrá que hay un nuevo packetID, pero... si ya lo sabe, tiene que realizar una acción cuando lo recibe.. y para lograr esto necesitamos dirigirnos al :

  1. Private Sub HandleIncomingdata(byval userindex as integer)


ahí es donde se "maneja"(handle) , la "información"(data) , "entrante"(incoming), buscaremos donde está el ..



ahí tenemos donde el servidor al recibir 1 "Identificador" realizará lo que nosotros le indiquemos, abajo de el select case agregaremos

  1. case clientpacketid.Prueba
  2.    call prueba(userindex)


NOTA: acá es lo mismo que el cliente , frecuentemente para la comprensión y prolijidad del código se le suele agregar un "Handle" y seguido el nombre del paquete, aunque también podemos usar el nombre que nos guste.

bueno, ahí ya el servidor sabe que al recibir X identificador, tiene que llamar a x rutina, y ahora, nos falta hacer esta rutina(sub) y hacer lo que nos guste, al final del módulo protocol.bas, agregaremos

ATENCIÓN: En los paquetes que tengan "cadenas de carácteres, texto" (strings) se recomienda usar el "buffer auxiliar", para manejar estos datos, pero no se podrá cerrar la rutina sin realizar el copiado del buffer, más información encontraran en este aporte(gracias ArzenaTh)

por_que_nunca_usar_exit_sub_en_paquetes_que_contengan_datos_adicionales_tcJF.html

bueno siguendo con lo que estabamos haciendo , al final del módulo protocol pondremos

acá les dejaré 2 formas de manejar nuestra data.

primera forma y más recomendada en paquetes qe contienen strings

  1. Private Sub Prueba(byval Indice as integer)
  2. Dim Bufer as new clsbytequeue  'declaramos el buffer auxiliar que usaremos
  3.  
  4. call bufer.copybuffer(userlist(indice).incomingdata) 'acá hacemos un copiado de nuestros datos
  5.  
  6. call bufer.readbyte    'acá borraremos de la memoria el byte identificador.
  7.  
  8. dim MiCadena as string    'en esta variable guardaremos el string que nos mandó el cliente.
  9.  
  10. micadena = bufer.readasciistring       'borramos de la memoria el string que envió el cliente, y lo guardamos en una variable para utilizarlo.
  11.  
  12. 'LISTO, Ya tenemos la memoria del bufer vacia, a partir de acá haremos lo que quisieramos con nuestro string recibido
  13.  
  14. '******************* esto tiene que estar antes del end sub
  15.  
  16. call userlist(indice).incomingdata.copybuffer(bufer) 'si llegó el paquete entero, y no hubo error alguno, destruiremos el bufer.
  17.  
  18. end sub


de esa forma(la más recomendada) lograremos recibir nuestros datos, ahora la segunda opción

  1. Private Sub Prueba(byval userIndex as integer)
  2.  
  3. call userlist(userindex).incomingdata.readbyte  'borraremos de la memoria el byte identificador.
  4.  
  5. dim cadena as string 'en esa variable nos guardamos lo que nos envió el cliente.
  6.  
  7. cadena = userlist(userindex).incomingdata.readasciistring  'guardamos en la variable, y removemos de la memoria el string
  8.  
  9. ' APARTIR DE ACA HASTA EL END SUB, HAREMOS LO QUE NOS GUSTE.
  10. end sub


con las 2 formas lograremos lo mismo, pero la primera se recomienda más por que si hay un error(no llegan completos los datos , etc) no revienta todo, cosa que sí pasaría con la segunda(opción).

listo, tan simple como eso ya tenemos una comunicación entre un cliente y el servidor :D

ahora voy a aclarar diversas cosas :

1 : para enviar datos de diferente tipo, byte/integer/long/double/single, en el cliente usaremos

call outgoingdata.writeTIPODEDATO(valor)

cambiando tipodedato por byte/integer/long/double/single y "valor" por lo que queremos enviarle al servidor.

2 : Esto es muy importante, jamás , de ninguna forma podemos tener siquiera 1 PAQUETE que no esté en la misma posición(en el enum) tanto en cliente-servidor, por esto que voy a explicar.

calculemos que tenemos esto así

En el clientpacketid del cliente tenemos

abajo de este paquete

  1.    LoginNewChar            'NLOGIN


tenemos el nuestro



y en el servidor en el enum clientpacketid

tenemos arriba de este paquete

  1.    LoginNewChar            'NLOGIN


el nuestro



entonces, que pasaría si hacemos esto?, fácil, el enum clientpacketid(como todos los ENUMs que no inician desde un valor) , el primer paquete es 0, el segundo es 1 el tercero 2 y así.

entonces tenemos en el cliente

  1. Private Enum ClientPacketID
  2.     LoginExistingChar       'OLOGIN
  3.     ThrowDices              'TIRDAD
  4.     LoginNewChar            'NLOGIN
  5.     Prueba


y en el servidor

  1. Private Enum ClientPacketID
  2.     LoginExistingChar       'OLOGIN
  3.     ThrowDices              'TIRDAD
  4.     Prueba
  5.     LoginNewChar            'NLOGIN


entonces quedaria así

cliente :

loginexistingchar = identificador 0
throwdices = identificador 1
loginnewchar = identificador 2
prueba(nuestro paquete id) = identificador 3


servidor:

loginexistingchar = identificador 0
throwdices = identificador 1
prueba(nuestro paquete id) = identificador 2
loginnewchar = identificador 3


ahora cuando nosotros hacemos esto

  1. call outgoingdata.writebyte(clientpacketid.prueba)


le estamos enviando al servidor un identificador(numero) que sería un 3, hasta acá todo bárbaro, el problema radica cuando...

el servidor recibe ese "3" y lo maneja como si fuera el "loginexistingchar"(que es el 3 para el servidor), osea , esto ocurre cuando hay un desorden y el cliente al enviar un 3 y el server recibirlo y manejarlo como un paquete que no es el que se espera, el protocolo revienta(si se escriben más/menos datos de los que el servidor espera) o simplemente si no enviamos datos adicionales, hará lo inverso, calculemos que tenemos invertido en el cliente y servidor el paquete de meditar, al enviar nuestro paquete "prueba", el servidor nos expulsará , dado a que el servidor no está esperando un "string"

bueno, espero que les halla gustado ^^

cualquier crítica/comentario/correción que sea productivo para el tema es totalmente aceptado!

LyRan escribió:Buenos Dias amigos y programadores de Gs Zone, Me gustaria pedirle la amabilidad de una ayuda con un cliente editado para mi Ao casero, Osea me explico, yo juego Ao con varios amigos y ellos todos usan cheat y no me gusta eso me gustaria que alguien me ayudara a crear un cliente editado con auto poteo de ambas potas a la ves ya sea que se alla gastado Mana lanzando algun hechis y comienze a potear solo hasta estar completamente el Mana, igual para la salud y poteo rapido para ambos.
mAnco programEr
801 (+2)
Dragon Ancestral [1]
Registrado: Años de membresíaAños de membresía
Ubicación: Bolivia
Mensajes: 2305
Aportes: 109

Nota » 05 Nov 2011 08:53

ZARPADOOOOOOOOOOOOOOO APORTEEEEEEEEEEEE!! LO VOY A LEEER MINIMO 10 VECES HASTA QUE ME QUEDE TODO BIEN GRABADO JAJAJA =D GRACIAS!!!!! ^^ ^^ ^^ ^^

_______________________________________________________________________

Suelo soñar =)
Usuario Registrado
173
Aprendiz [2]
Registrado: Años de membresíaAños de membresía
Mensajes: 279
Aportes: 2

Nota » 05 Nov 2011 18:54

Muy buen aporte maTih.-

Sos tremendo programer :D (protocolo :P)

Imagen

Imagen

TE AMO SKYFUN SOS MI FANNNNNNNNNNNNNNNNNNNNN
HAO Staff
409
Dragon Ancestral [2]
Registrado: Años de membresía
Ubicación: Buenos Aires
Mensajes: 2745
Aportes: 28
Premios: 1
Embajador (1)

Nota » 05 Nov 2011 21:35

Genial matih , a muchos le vendrá de 10 ;)

Imagen
378
Destructor de Mentes [3]
Registrado: Años de membresía
Ubicación: Mar Del Plata
Mensajes: 636
Aportes: 9

Nota » 06 Nov 2011 16:28

No entendí un carajo.

Maxi
368
Destructor de Mentes [12]
Registrado: Años de membresía
Mensajes: 1081
Aportes: 11
Premios: 1
Campeón de Diseño Gráfico (1)

Nota » 06 Nov 2011 16:42

No te faltaron los with userlist(userindex) y cerrar el with ?

Imagen
@lautamarino
531
Oraculo [5]
Registrado: Octubre 2011
Mensajes: 2036
Aportes: 46
Premios: 1
Embajador (1)

Nota » 06 Nov 2011 22:23

pampiro escribió:No entendí un carajo.


Digamos que si no sabes un carajo , no vas a lograr mucho con esto..

Shak escribió:No te faltaron los with userlist(userindex) y cerrar el with ?


donde ? xD no creo :P

lo escribí todo aca en el foro ni abrí los códigos :P
Última edición por maTih.- el 06 Nov 2011 22:23, editado 1 vez en total

LyRan escribió:Buenos Dias amigos y programadores de Gs Zone, Me gustaria pedirle la amabilidad de una ayuda con un cliente editado para mi Ao casero, Osea me explico, yo juego Ao con varios amigos y ellos todos usan cheat y no me gusta eso me gustaria que alguien me ayudara a crear un cliente editado con auto poteo de ambas potas a la ves ya sea que se alla gastado Mana lanzando algun hechis y comienze a potear solo hasta estar completamente el Mana, igual para la salud y poteo rapido para ambos.
mAnco programEr
801 (+2)
Dragon Ancestral [1]
Registrado: Años de membresíaAños de membresía
Ubicación: Bolivia
Mensajes: 2305
Aportes: 109

Nota » 07 Nov 2011 23:13

Hago un anexo en el destacado (asi no hay dos).

Buen aporte ^^
Aguante River Plate ! ! !
909
Moderador
Registrado: Años de membresíaAños de membresíaAños de membresía
Ubicación: Villa adelina, Vicente Lopez.
Mensajes: 14428
Aportes: 305
Premios: 10
Señor Moderador (3) Señor Reglamento (1) Aportes (2) Embajador (3) Detector de Bugs (1)

Nota » 08 Nov 2011 00:57

Franeg95 escribió:Hago un anexo en el destacado (asi no hay dos).

Buen aporte ^^


perfect ^^

LyRan escribió:Buenos Dias amigos y programadores de Gs Zone, Me gustaria pedirle la amabilidad de una ayuda con un cliente editado para mi Ao casero, Osea me explico, yo juego Ao con varios amigos y ellos todos usan cheat y no me gusta eso me gustaria que alguien me ayudara a crear un cliente editado con auto poteo de ambas potas a la ves ya sea que se alla gastado Mana lanzando algun hechis y comienze a potear solo hasta estar completamente el Mana, igual para la salud y poteo rapido para ambos.
mAnco programEr
801 (+2)
Dragon Ancestral [1]
Registrado: Años de membresíaAños de membresía
Ubicación: Bolivia
Mensajes: 2305
Aportes: 109

Nota » 10 Ene 2012 01:20

Excelente aporte, te manejás muy bien en el protocolo binario.

Esto lo aprendi hace poquito :p

Master123500 escribió:Pero como tendria q buscarlo??? osea..prosediment Font_Create ??

miqueas150 dijo:
Es un sub :lol:


Chateando con LuuQ escribió:Anzhel dice:
franeg95_no_es_igual_a_tkF5-15.html
JAJAJAJAJAJAJAJAJAJAJ
MIRA ESO
' Simplemente Luuq dice:
el q canta
esta ardiente

Imagen
Mystery 8.0 - Anzhetra: The lost imperium
http://www.MysteryAO.tk
MysteryAO Staff
338 (+3)
Destructor de Mentes [6]
Registrado: Años de membresía
Ubicación: En mi casa.
Mensajes: 796
Aportes: 20

Nota » 10 Ene 2012 01:25

Matih.-

Public Sub Prueba()
call outgoingdata.writebyte(clientpacketid.Prueba)
call outgoingdata.writeasciistring("Esto es una prueba!")
end sub


no sería mejor usar With o no cambia mucho? :P

Imagen
@lautamarino
531
Oraculo [5]
Registrado: Octubre 2011
Mensajes: 2036
Aportes: 46
Premios: 1
Embajador (1)

Nota » 11 Ene 2012 13:52

Shak escribió:Matih.-

Public Sub Prueba()
call outgoingdata.writebyte(clientpacketid.Prueba)
call outgoingdata.writeasciistring("Esto es una prueba!")
end sub


no sería mejor usar With o no cambia mucho? :P

Para que si en definitiva es lo mismo;

  1. Public Sub WritePrueba()
  2.       With outgoingData
  3.             .WriteByte(ClientPacketID.ID_Paquete)
  4.             .WriteASCIIString(String)
  5.       End With
  6. End Sub


Solo lo hace más estructurado que digamos pero no cambia nada xd... (Aunque en un procedimiento más largo te ahorra tiempo)

Está bueno para los que comienzan a programar después del 11.5 y no entienden mucho, se agradece.

Adiós.

Director del Proyecto IndeX - AO
Mannakia escribió:Closed moderhipocradores , tema ya solucionado, jesus me ilumino en un sueño, y programamos junto, la verdad un genio, sabe lenguaje V** (V Multiply Multiply) que es sobre como programaron las primeras microcelulas.

Dunkan escribió:Chiters?, Pero esto no tenía la "Samke Security" ?

Imagen
Imagen
Programador
356
Dragon Ancestral [6]
Registrado: Años de membresíaAños de membresíaAños de membresíaAños de membresía
Mensajes: 4551
Aportes: 46
Premios: 2
Usuario superado (2)

Nota » 26 Ene 2012 13:33

Muy bueno, esto es para qe la gente se de cuenta qe empezar a programar en binario es facil.

Imagen

Imagen

Imagen
Staff Tierras Legendarias AO
594
Oraculo [2]
Registrado: Años de membresía
Ubicación: Cordobá
Mensajes: 1337
Aportes: 12
Premios: 2
Campeón de Truco (1) Embajador (1)

Nota » 24 Mar 2012 14:42

Faltan cosas importantes. No estas hablando ni del NotEnoughDataErrCode, ni del NotEnoughSpaceErrCode.
Usuario Registrado
107
Newbie [5]
Registrado: 5 Años de membresía!Años de membresía
Mensajes: 151
Aportes: 6

Nota » 18 Abr 2012 15:56

Quería saber bien en detalle para que función y como puedo usarla:

If UserList(UserIndex).incomingData.length < 2 Then
err.Raise UserList(UserIndex).incomingData.NotEnoughDataErrCode
Exit Sub
End If


(sospecho que es como una verificación del tamaño del paquete... pero no se bien para que sirve y como se saca el numero 2. Creo es la cantidad de bytes, pero no se la cuenta matemática xD)

PD: En la guía no se habla de esto!
Usuario Registrado
50
Newbie [1]
Registrado: Años de membresíaAños de membresíaAños de membresía
Mensajes: 19

Siguiente

Volver a AO 0.13.x

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados