Bramhh

Fundador Evolutionao
Miembro del equipo
Moderador de AO
Moderador
Bueno uno de mis aportes mientras aprendo en el cual solicito a mejores programadores que me digan si cometi errores o si se puede mejorar... gracias.

Se que funciona porque lo probe de mil maneras incluso editando los datos de los paquetes para abusar del sistema y como valido bien en el servidor, no deja hacerlo.

También se puede transferir así ... /TRANSFERIRORO [email protected] (Y por boton en el tirar oro).

Comenzamos....

CLIENTE

Vamos a buscar el formulario "frmCantidad" y adentro le vamos a dibujar agrandando el espacio del mismo... los siguientes componentes.

Un TextBox llamado "txtNombre" y un Label llamado "btnTransferirOro"

Le damos doble click al btnTransferirOro y así debe quedar el Private Sub...

Código:
Private Sub btnTransferirOro_Click()
    Call Audio.PlayWave(SND_CLICK)
    If LenB(txtCantidad.Text) > 0 Then
        If Not IsNumeric(txtCantidad.Text) Then Exit Sub  'Should never happen

        Call WriteTransferirOro(frmCantidad.txtNombre.Text, frmCantidad.txtCantidad.Text)
        frmCantidad.txtCantidad.Text = ""
        frmCantidad.txtNombre.Text = ""
    End If

    Unload Me
End Sub

En el "ClientPacketID" tenemos que declarar lo siguiente dentro....

Código:
TransferirOro           '/TRANSFERIRORO [email protected]

Pueden hacerlo antes del "End Enum" y esto hay que respetar su orden en el servidor tmb, respetando el orden obviamente.

Luego en el ProtocolCmdParse hay que agregar abajo del case donde se declaro...

Código:
Case "/TRANSFERIRORO"
            If notNullArguments Then
                tmpArr = Split(ArgumentosRaw, "@", 2)

                If UBound(tmpArr) = 1 Then
                    If ValidNumber(tmpArr(1), eNumber_Types.ent_Long) Then
                        Call WriteTransferirOro(tmpArr(0), tmpArr(1))
                    Else
                        'Faltan o sobran los parametros con el formato propio
                        Call ShowConsoleMsg("Formato incorrecto. Utilice /TRANSFERIRORO [email protected]")
                    End If
                Else
                    'Faltan o sobran los parametros con el formato propio
                    Call ShowConsoleMsg("Formato incorrecto. Utilice /TRANSFERIRORO [email protected]")
                End If
            Else
                'Faltan los parametros con el formato propio
                Call ShowConsoleMsg("Formato incorrecto. Utilice /TRANSFERIRORO [email protected]")
            End If

y por último en el modulo "Protocol" agregamos abajo del write correspondiente al orden que pusimos...

Código:
Public Sub WriteTransferirOro(ByVal Nombre As String, ByVal cantidad As Long)
    With outgoingData
        Call .WriteByte(ClientPacketID.TransferirOro)
        Call .WriteASCIIString(Nombre)
        Call .WriteLong(cantidad)
    End With
End Sub

AHORA AL SERVIDOR

Ahora identificamos donde declaramos la variable en el "ClientPacketID" del cliente y en el servidor respetamos el orden y agregamos ...

Código:
TransferirOro           '/TRANSFERIRORO [email protected]

Luego tenemos que declarar el CASE en el modulo Protocol

Código:
Case ClientPacketID.TransferirOro           'Transferiroro [email protected]
        Call HandleTransferirOro(UserIndex)

Y por último abajo del handle donde estamos basandonos al ordenar los paquetes enviados y recibidos agregamos.....

En modulo Protocol también...

Código:
Public Sub HandleTransferirOro(ByVal UserIndex As Integer)

    If UserList(UserIndex).incomingData.length < 7 Then
        Err.Raise UserList(UserIndex).incomingData.NotEnoughDataErrCode
        Exit Sub
    End If

    On Error GoTo Errhandler
 
    With UserList(UserIndex)
     
        'This packet contains strings, make a copy of the data to prevent losses if it's not complete yet...
        Dim buffer As New clsByteQueue
        Call buffer.CopyBuffer(.incomingData)
     
        'Remove packet ID
        Call buffer.ReadByte

        Dim nombreDestino As String
        Dim cantidadOro As Long
        Dim idUserDestino As Integer
        Dim rutaPath As String
        Dim oroBancoDestino As Long

        nombreDestino = buffer.ReadASCIIString()
        cantidadOro = buffer.ReadLong()
 
        'solo para usuarios...
        If .Flags.Privilegios And (PlayerType.Consejero Or PlayerType.SemiDios Or PlayerType.Dios Or PlayerType.Admin) Then
            Call .incomingData.CopyBuffer(buffer)
            Set buffer = Nothing
            Exit Sub
        End If

        'estas muerto?
        If .Flags.Muerto = 1 Then
            Call WriteConsoleMsg(UserIndex, "¡No puedes transferir oro estando muerto!", FontTypeNames.FONTTYPE_CENTINELA)
            Call .incomingData.CopyBuffer(buffer)
            Set buffer = Nothing
            Exit Sub
        End If
        
        '¿Me queres alterar el campo fracasado? jaja
        If cantidadOro <= 0 Then
            cantidadOro = 0
        End If

        'Estas en un Mapa Seguro?
        If MapInfo(.Pos.map).Pk = True Then
            Call WriteConsoleMsg(UserIndex, "¡Debes estar en un mapa seguro para transferir oro!", FontTypeNames.FONTTYPE_CENTINELA)
            Call .incomingData.CopyBuffer(buffer)
            Set buffer = Nothing
            Exit Sub
        End If

        If .Stats.GLD = 0 Then
            Call WriteConsoleMsg(UserIndex, "¡No puedes transferir oro si no tienes!", FontTypeNames.FONTTYPE_CENTINELA)
            Call .incomingData.CopyBuffer(buffer)
            Set buffer = Nothing
            Exit Sub
        End If

        'Verificamos que no nos editen el oro
     
        If .Stats.GLD < cantidadOro Then
            Call WriteConsoleMsg(UserIndex, "¡No tienes el oro que deseas mandar!", FontTypeNames.FONTTYPE_CENTINELA)
            Call .incomingData.CopyBuffer(buffer)
            Set buffer = Nothing
            Exit Sub
        End If
     
        'tiene campos vacios?
        If nombreDestino = "" Or cantidadOro = 0 Then
            Call WriteConsoleMsg(UserIndex, "Los valores no deben ser nulos ni 0.", FontTypeNames.FONTTYPE_CENTINELA)
            Call .incomingData.CopyBuffer(buffer)
            Set buffer = Nothing
            Exit Sub
        End If
     
        'Obtenemos el usuario
        idUserDestino = NameIndex(nombreDestino)
        rutaPath = CharPath & nombreDestino & ".chr"
     
        'Veamos si el destinatario existe..
        If PersonajeExiste(nombreDestino) Then
            If idUserDestino = UserIndex Then
                Call WriteConsoleMsg(UserIndex, "¡¡No puedes mandarte oro a vos mismo!!, sal de Artemis y consigue amigos, que puedan prestarte dinero.", FontTypeNames.FONTTYPE_CENTINELA)
                Call .incomingData.CopyBuffer(buffer)
                Set buffer = Nothing
                Exit Sub
            Else
                'El personaje destinatario está offline
                If idUserDestino <= 0 Then
                    oroBancoDestino = GetVar(CharPath & nombreDestino & ".chr", "STATS", "BANCO")
                    Call WriteVar(rutaPath, "STATS", "BANCO", oroBancoDestino + val(cantidadOro))
                    Call WriteConsoleMsg(UserIndex, "El destino se encuentra offline, igual se tranfirio a su banco " & cantidadOro & " monedas de oro.", FontTypeNames.FONTTYPE_INFO)
                    .Stats.GLD = .Stats.GLD - cantidadOro
                    Call WriteUpdateGold(UserIndex)
                Else
                    UserList(idUserDestino).Stats.GLD = UserList(idUserDestino).Stats.GLD + cantidadOro
                    .Stats.GLD = .Stats.GLD - cantidadOro
                    Call WriteUpdateGold(UserIndex)
                    Call WriteUpdateGold(idUserDestino)
                    Call WriteConsoleMsg(UserIndex, "Le has transferido " & cantidadOro & " monedas de oro a " & UserList(idUserDestino).Name & ".", FontTypeNames.FONTTYPE_INFO)
                    Call WriteConsoleMsg(idUserDestino, "" & .Name & "  te ha transferido " & cantidadOro & " monedas De oro .", FontTypeNames.FONTTYPE_INFO)
                End If
            End If
        Else
            Call WriteConsoleMsg(UserIndex, "El jugador destinatario no existe, verifique si ingresó el nombre correcto.", FontTypeNames.FONTTYPE_CENTINELA)
            'If we got here then packet is complete, copy data back to original queue
            Call .incomingData.CopyBuffer(buffer)
            Set buffer = Nothing
            Exit Sub
        End If
     
        'If we got here then packet is complete, copy data back to original queue
        Call .incomingData.CopyBuffer(buffer)
        Set buffer = Nothing
    End With
    Exit Sub
 
Errhandler:

    Dim error As Long

    error = Err.Number

    On Error GoTo 0

    'Destroy auxiliar buffer
    Set buffer = Nothing

    If error <> 0 Then Err.Raise error
End Sub

Por favor, vean si me falto algo, aunque se que funciona correctamente sin errores.
Cambien el "FONTTYPE_CENTINELA" a su gusto.

Saludos!

Espero que les sea de utilidad, se que lo habia aportado Lauti de DSAO pero éste lo hice independiente a su método, tiene cosas similares pero es diferente.
 
Última edición:

Bramhh

Fundador Evolutionao
Miembro del equipo
Moderador de AO
Moderador
Qué pasa si yo intento transferir una cantidad de oro negativa?
Código:
If .Stats.GLD < cantidadOro Then

            Call WriteConsoleMsg(UserIndex, "¡No tienes el oro que deseas mandar!", FontTypeNames.FONTTYPE_CENTINELA)

            Call .incomingData.CopyBuffer(buffer)

            Set buffer = Nothing

            Exit Sub

        End If

Debería pasar eso aunque no se como lo maneja internamente Vb6, capas alguno se pone la gorra y lo comenta.
 

Facu Chamas

Córdoba Capital
Pensé que quedaría mas completo si al querer transferir oro a X usuario; tu billetera no cumple con la cantidad, pero el en banco si tienes esa cantidad, que al teclear el comando o transferir desde el frmcantidad, se descuente billetera y el resto del banco. Creo que seria mucho lio xD
 

Bramhh

Fundador Evolutionao
Miembro del equipo
Moderador de AO
Moderador
Pensé que quedaría mas completo si al querer transferir oro a X usuario; tu billetera no cumple con la cantidad, pero el en banco si tienes esa cantidad, que al teclear el comando o transferir desde el frmcantidad, se descuente billetera y el resto del banco. Creo que seria mucho lio xD
La verdad que no, osea vos decis que desde el banco y la billetera se hagan los giros? podría es retocar un poco nomas, pero no lo veo necesario, yo en mi vida usaba el banco jaja
 

Feer~

Oráculo Lvl 3
Colaborador
Pensé que quedaría mas completo si al querer transferir oro a X usuario; tu billetera no cumple con la cantidad, pero el en banco si tienes esa cantidad, que al teclear el comando o transferir desde el frmcantidad, se descuente billetera y el resto del banco. Creo que seria mucho lio xD

Si te la rebuscas un poquito, lo haces.
Guardas el oro en una variable temporal para hacer los cálculos

Código:
if (.stats.gld < oroATransferir)
    tmpVar = oroATransferir - .stats.gld
    if .stats.banco >= tmpVar
       .stats.gld = 0
       .stats.banco -= tmpVar
       // Aca le sumas el oro al otro usuario, mandas los mensajes, etc

más o menos así sería la lógica, no me acuerdo bien las variables del oro ni el de la boveda :p
 

Bramhh

Fundador Evolutionao
Miembro del equipo
Moderador de AO
Moderador
Si te la rebuscas un poquito, lo haces.
Guardas el oro en una variable temporal para hacer los cálculos

Código:
if (.stats.gld < oroATransferir)
    tmpVar = oroATransferir - .stats.gld
    if .stats.banco >= tmpVar
       .stats.gld = 0
       .stats.banco -= tmpVar
       // Aca le sumas el oro al otro usuario, mandas los mensajes, etc

más o menos así sería la lógica, no me acuerdo bien las variables del oro ni el de la boveda :p
La lógica es siempre verificar si primero en la bille tiene lo necesario, sino preguntar en el banco y sino sumar lo q tenes en banco y bille y restarlo primero de la bille o banco, es todo muy dependiendo el gusto de cada quien pero es literalmente ifs y sumas y retas
 

Alkair

Dragón Ancestral Lvl 4
Ex-Staff
Código:
If .Stats.GLD < cantidadOro Then

            Call WriteConsoleMsg(UserIndex, "¡No tienes el oro que deseas mandar!", FontTypeNames.FONTTYPE_CENTINELA)

            Call .incomingData.CopyBuffer(buffer)

            Set buffer = Nothing

            Exit Sub

        End If

Debería pasar eso aunque no se como lo maneja internamente Vb6, capas alguno se pone la gorra y lo comenta.
Era una pregunta retórica, si yo pongo una cantidad negativa (cantidadOro = -1000) y tengo 0 o más de oro (.Stats.GLD >= 0) ese chequeo va a ser falso (porque 0 < -1000 es falso).
Así como está, puedo robarle oro a otro personaje que me cae mal.
 

Bramhh

Fundador Evolutionao
Miembro del equipo
Moderador de AO
Moderador
Era una pregunta retórica, si yo pongo una cantidad negativa (cantidadOro = -1000) y tengo 0 o más de oro (.Stats.GLD >= 0) ese chequeo va a ser falso (porque 0 < -1000 es falso).
Así como está, puedo robarle oro a otro personaje que me cae mal.
Si no se como lo maneja Visual Basic 6, en .net no deberia pasar eso, tampoco entra en la logica en si, vos que aconsejarías?
|
Posible solucion sino....
Código:
'estas muerto?
        If .Flags.Muerto = 1 Then
            Call WriteConsoleMsg(UserIndex, "¡No puedes transferir oro estando muerto!", FontTypeNames.FONTTYPE_SERVER)
            Call .incomingData.CopyBuffer(buffer)
            Set buffer = Nothing
            Exit Sub
        End If
        
        If cantidadOro <= 0 Then
            cantidadOro = 0
        End If
 
Última edición:

Alkair

Dragón Ancestral Lvl 4
Ex-Staff
Si no se como lo maneja Visual Basic 6, en .net no deberia pasar eso, tampoco entra en la logica en si, vos que aconsejarías?
|
Posible solucion sino....
Código:
'estas muerto?
        If .Flags.Muerto = 1 Then
            Call WriteConsoleMsg(UserIndex, "¡No puedes transferir oro estando muerto!", FontTypeNames.FONTTYPE_SERVER)
            Call .incomingData.CopyBuffer(buffer)
            Set buffer = Nothing
            Exit Sub
        End If
       
        If cantidadOro <= 0 Then
            cantidadOro = 0
        End If
Es independiente del lenguaje lo que te digo, pasaría lo mismo en .NET, C, Java, lo que se te ocurra (menos Ada quizás (?)).
Lo aconsejable es hacer eso que hiciste vos, o simplemente devolverle un mensaje de que la cantidad es inválida.
 

Mermas

Aprendiendo
Si te la rebuscas un poquito, lo haces.
Guardas el oro en una variable temporal para hacer los cálculos

Código:
if (.stats.gld < oroATransferir)
    tmpVar = oroATransferir - .stats.gld
    if .stats.banco >= tmpVar
       .stats.gld = 0
       .stats.banco -= tmpVar
       // Aca le sumas el oro al otro usuario, mandas los mensajes, etc

más o menos así sería la lógica, no me acuerdo bien las variables del oro ni el de la boveda :p
Mmm no creo que sea buena idea, imaginate que ticleas un 0 de más, o no queres sacar de la bobe
 

Bramhh

Fundador Evolutionao
Miembro del equipo
Moderador de AO
Moderador
Si, se lo agrego hoy, algo que diga si de verdad quiere tranferir ese oro.
No se si lo implementaria, pero podría consultarle al usuario si quiere utilizarlo porque no le alcanza, onda confirmar - cancelar
 

NicolasRz

Newbie Lvl 5
El código esta medio des prolijo pero cumple su función, lo que haria yo es mandar cantidades fijas entonces te ahorras el long de la cantidad y mandas un byte
 
Arriba