[Ayuda] Mi Class Overlay para Cheats genera un Alto Consumo de Ram.

Iniciado por **Aincrad**, 16 Septiembre 2020, 16:20 PM

0 Miembros y 1 Visitante están viendo este tema.

**Aincrad**

Hola, soy yo de nuevo pidiendo una ayudita....

Mi clase que hice ya hace un tiempo me esta dando problema al laggear la PC , en proyectos medianamente grandes.

Por ende necesito algunos consejos. para restructurar el codigo y que consuma poca ram.

La clase Overlay es la que uso para que el cheat se mantenga Junto a la ventana del juego .
y tambien monitoriza cuando el juego se cierra. todo Asincronico.

Pero consume mucha ram , haber si alguien con mas conocimientos sobre optimizar codigo me podria ayudar :

Elektro otra ayudita porfa..

Uso:
'ProcessGame Nombre del proceso del juego
'Me El form el cual se va a superponer encima del juego.
Código (vbnet) [Seleccionar]
Private AttachClienGame As New Overlay(ProcessGame, Me)

Overlay.vb

Código (vbnet) [Seleccionar]
Imports System.Runtime.InteropServices
Imports System.Net.Mail
Imports System.Text


Public Class Overlay

#Region " P/Invokes "

    <DllImport("user32.dll")> _
    Public Shared Function GetWindowRect(ByVal hWnd As IntPtr, ByRef lpRect As RECT) As Boolean
    End Function

    <DllImport("user32.dll", SetLastError:=True)> _
    Private Shared Function GetForegroundWindow() As IntPtr
    End Function

    <DllImport("user32.dll", SetLastError:=True)> _
    Private Shared Function GetWindowThreadProcessId(ByVal hWnd As IntPtr, ByRef lpdwProcessId As UInteger) As Integer
    End Function

    Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal Classname As String, ByVal WindowName As String) As IntPtr
    Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As IntPtr, ByRef lpdwProcessId As Integer) As Integer
    Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Integer, ByVal bInheritHandle As Integer, ByVal dwProcessId As Integer) As IntPtr
    Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As IntPtr) As Integer

#End Region

#Region " Properties "

    Private Shared Monitor As Boolean = True
    Public Property ActivateMonitoring As Boolean
        Get
            Return Monitor
        End Get
        Set(value As Boolean)
            Monitor = value
        End Set
    End Property

    Private Shared GameWindowsTitle As String = String.Empty
    Public ReadOnly Property GetWindowsTitle As String
        Get
            Return GameWindowsTitle
        End Get
    End Property

    Private Shared GameHandle As IntPtr = Nothing
    Public ReadOnly Property GetGameHandle As IntPtr
        Get
            Return GameHandle
        End Get
    End Property

    Private Shared GameLocation As Point = Nothing
    Public ReadOnly Property GetGameLocation As Point
        Get
            Return GameLocation
        End Get
    End Property

    Private Shared GameSize As Size = Nothing
    Public ReadOnly Property GetGameSize As Size
        Get
            Return GameSize
        End Get
    End Property

#End Region

#Region " Structures "

    Public Structure RECT
        Public Left As Integer
        Public Top As Integer
        Public Right As Integer
        Public Bottom As Integer
    End Structure

#End Region

#Region " Declare's "

    Public window_loc As RECT
    Public screencenter(1) As Integer
    Public hWnd As IntPtr = Nothing
    Public pHandle As IntPtr = Nothing
    Public processID As Integer = Nothing
    Private ProcessName As String = String.Empty
    Public Const PROCESS_VM_ALL As Integer = &H1F0FFF
    Private MyAppProcess As String = Process.GetCurrentProcess().ProcessName
    Private FormManagement As Form = Nothing

#End Region

#Region " Public Methods "

    Public Sub New(ByVal ProcName As String, Optional ByVal FormC As Form = Nothing)
        ProcessName = ProcName
        If ProcessName.ToLower.EndsWith(".exe") Then ProcessName = ProcessName.Substring(0, ProcessName.Length - 4)
        FormManagement = FormC
        Dim tsk As New Task(AddressOf AttachtClient, TaskCreationOptions.LongRunning)
        tsk.Start()
    End Sub

#End Region

#Region " Private Methods "

    Private Sub AttachtClient()
        'On Error Resume Next
        Do While True
            If Monitor = True Then
                If Not ProcessName = String.Empty Then

                    Dim proc() As Process = Process.GetProcessesByName(ProcessName)

                    If Not proc.Length = 0 Then

                        If IsGameAppFocus() = True Then

                            Dim windowname As String = proc(0).MainWindowTitle
                            GameWindowsTitle = windowname

                            hWnd = FindWindow(vbNullString, windowname)

                            GetWindowThreadProcessId(hWnd, processID)

                            pHandle = OpenProcess(PROCESS_VM_ALL, 0, processID)
                            GameHandle = pHandle

                            If hWnd = 0 Then Exit Do

                            GetWindowRect(hWnd, window_loc)

                            GameLocation = New Point((window_loc.Left + 10), (window_loc.Top + 35))

                            GameSize = New Point(((window_loc.Right - window_loc.Left) - 25), ((window_loc.Bottom - window_loc.Top) - 45))

                            If Not (FormManagement Is Nothing) Then

                                If FormManagement.Visible = True Then

                                    FormManagement.BeginInvoke(Sub()
                                                                   FormManagement.Location = GameLocation
                                                                   FormManagement.Size = GameSize
                                                               End Sub)

                                End If

                            End If

                        Else

                            If FormManagement.Visible = True Then

                                FormManagement.BeginInvoke(Sub()
                                                               FormManagement.Hide()
                                                           End Sub)

                            End If

                        End If

                    Else

                        is_active(True)

                    End If
                End If
            End If
        Loop
    End Sub

    Private Function IsGameAppFocus() As Boolean
        Dim ActiveProcess As Process = GetActiveProcess()
        Dim IsFocusGame As Boolean = False
        If ActiveProcess IsNot Nothing Then
            Dim CurrentProcName As String = ActiveProcess.ProcessName

            If LCase(CurrentProcName) = LCase(MyAppProcess) Then
                IsFocusGame = True
            End If

            If LCase(CurrentProcName) = LCase(ProcessName) Then
                IsFocusGame = True
            End If


            Return IsFocusGame

        End If

        Return IsFocusGame
    End Function

    Private Function GetActiveProcess() As Process
        Dim FocusedWindow As IntPtr = GetForegroundWindow()
        If FocusedWindow = IntPtr.Zero Then Return Nothing

        Dim FocusedWindowProcessId As UInteger = 0
        GetWindowThreadProcessId(FocusedWindow, FocusedWindowProcessId)

        If FocusedWindowProcessId = 0 Then Return Nothing
        Return Process.GetProcessById(CType(FocusedWindowProcessId, Integer))
    End Function

    Private Sub is_active(Optional ByVal exit_ As Boolean = True)
        Dim p As Process() = Process.GetProcessesByName(ProcessName)
        If p.Length = 0 And exit_ Then
            Environment.Exit(0)
        End If
    End Sub

#End Region

End Class





Eleкtro

He probado el código con varios procesos (y juegos) y a mi no me da ningún tipo de problema, practicamente no aumenta el consumo de memoria, con o sin form superpuesto a la ventana.

De todas formas tienes un bucle "infinito" sin ningún tipo de intervalo para dejar descansar a la CPU, además en cada iteración del bucle solicitas el open-handle del proceso y no liberas los recursos nativos en memoria... ¿para que tienes declarada la función CloseHandle en tu código si no la usas?. Empieza por ahí.

Además deberías eliminar todas esas declaraciones al estilo de VB6 y adaptarlas al estilo .NET. El valor de retorno de la función "OpenProcess" debería ser del tipo SafeAccessTokenHandle, aunque es perfectamente válido que uses la función CloseHandle para liberar los recursos, pero si lo haces como te digo basta con usar la instrucción Using o el método SafeAccessTokenHandle.Close(). Precisamente tienes un ejemplo de esto en el testamento de código que compartí contigo ayer en el otro tema que abriste (aunque con la función OpenThread).

Saludos!








**Aincrad**

Perfecto. reduje en mas del 50% de lo que consumía.  gracias de nuevo bro.
También actualice los Pinvokes.

;-)