2016-11-13 2 views
-1

Так что я делаю программу, которая предоставляет создателям игры много инструментов для повышения уровня (путем настройки значений игры с использованием передовых алгоритмов с учетом указателей на эти значения), а для ярлыка я создал методы, которые устанавливают/извлекают значения из указатели ввода. Однако игра имеет переменные Int32, Float и Boolean, поэтому мне нужно 3 разных метода для каждого типа данных для одного и того же количества указателей, и у меня также есть 5 перегрузок из каждого, что дает 15 различных методов для извлечения значений из указателей. Вот методы (без кода):Методы общего типа или заданные типы при возврате разных значений типа данных с тем же алгоритмом?

public static int GetIntFromPointers(IntPtr baseAddress, IntPtr offset0) 
public static int GetIntFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1) 
public static int GetIntFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2) 
public static int GetIntFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2, IntPtr offset3) 
public static int GetIntFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2, IntPtr offset3, IntPtr offset4) 
public static float GetFloatFromPointers(IntPtr baseAddress, IntPtr offset0) 
public static float GetFloatFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1) 
public static float GetFloatFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2) 
public static float GetFloatFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2, IntPtr offset3) 
public static float GetFloatFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2, IntPtr offset3, IntPtr offset4) 
public static bool GetBoolFromPointers(IntPtr baseAddress, IntPtr offset0) 
public static bool GetBoolFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1) 
public static bool GetBoolFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2) 
public static bool GetBoolFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2, IntPtr offset3) 
public static bool GetBoolFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2, IntPtr offset3, IntPtr offset4) 

Теперь я не спрашиваю, почему некоторые из них не работают; они действительно работают нормально (я думаю), но я также думал о возможности создания универсального метода обо всех разных типах, но я действительно не знаю, как и я не уверен, что создание таких методов будет полезно вообще ...

Вот код для метода GetIntFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2, IntPtr offset3, IntPtr offset4):

public static int GetIntFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2, IntPtr offset3, IntPtr offset4) 
{ 
    IntPtr baseAddressValue = new IntPtr(BitConverter.ToInt32(MemoryStuff.ReadMemory((int)baseAddress, 4, (int)processHandle), 0)); 
    IntPtr offset0Value = new IntPtr(BitConverter.ToInt32(MemoryStuff.ReadMemory((int)baseAddressValue + (int)offset0, 4, (int)processHandle), 0)); 
    IntPtr offset1Value = new IntPtr(BitConverter.ToInt32(MemoryStuff.ReadMemory((int)offset0Value + (int)offset1, 4, (int)processHandle), 0)); 
    IntPtr offset2Value = new IntPtr(BitConverter.ToInt32(MemoryStuff.ReadMemory((int)offset1Value + (int)offset2, 4, (int)processHandle), 0)); 
    IntPtr offset3Value = new IntPtr(BitConverter.ToInt32(MemoryStuff.ReadMemory((int)offset2Value + (int)offset3, 4, (int)processHandle), 0)); 
    int value = BitConverter.ToInt32(MemoryStuff.ReadMemory((int)offset3Value + (int)offset4, 4, (int)processHandle), 0); 

    return value; 
} 

И в случае, если вам интересно, что это MemoryStuff.ReadMemory вещь, вот код для этого один тоже:

[DllImport("Kernel32.dll", SetLastError = true)] 
public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, ref uint lpNumberOfBytesRead); 

public static byte[] ReadMemory(int address, int processSize, int processHandle) 
{ 
    byte[] buffer = new byte[processSize]; 
    uint sth = 0; 
    ReadProcessMemory(new IntPtr(processHandle), new IntPtr(address), buffer, (uint)processSize, ref sth); 
    return buffer; 
} 

ответ

0

Будет что-то вроде этой работы?

public static T GetFromPointers<T>(IntPtr baseAddress, IntPtr offset0, ...) 
{ 
    return (T)Convert.ChangeType(value, typeof(T)); 
} 

А вы бы доступ как

var myResult = GetFromPointers<int>(baseAddress, offset0, ...); 

Другая вещь, которую вы могли бы сделать, если ваша логика преобразования достаточно специфичны для каждого типа преобразования, вы можете пройти Func наряду с другими параметрами

public static T GetIntFromPointers<T>(IntPtr baseAddress, IntPtr offset0, Func<T, IntPtr, IntPtr> conversionFunc) 
{ 
    // some other generic work that goes on 
    return conversionFunc(baseAddress, offset0,); // specific conversion logic 
} 

Опять же, доступный как

var myResult = GetFromPointers<int>(baseAddress, offset0, ourIntConversionFunction(baseAddress, offset0)); 
+0

Это не так просто, потому что в зависимости от типа я должен изменить длину адреса, чтобы прочитать значение, поэтому я в основном спрашиваю, есть ли способ сделать условие if if else с типом 'T', являющимся параметром условия. – AlFas

+0

Только что обновлено с возможностью использования func ... Это лучше? – Braydie

+0

Вы также можете использовать func для передачи того, какой метод вызывать на «BitConverter» – Braydie

0

Вы могли бы сделать что-то вроде этого:

static unsafe class BinaryStuff 
{ 
    public static TStruct BytesToStructure<TStruct>(byte[] data) where TStruct : struct 
    { 
     fixed (byte* dataPtr = data) 
      return (TStruct)Marshal.PtrToStructure(new IntPtr(dataPtr), typeof(TStruct)); 
    } 

    public static byte[] StructureToBytes<TStruct>(TStruct st) where TStruct : struct 
    { 
     var bytes = new byte[Marshal.SizeOf(st)]; 
     fixed (byte* ptr = bytes) 
     { 
      Marshal.StructureToPtr(st, new IntPtr(ptr), true); 
     } 
     return bytes; 
    } 
} 

И вобще память чтения битов без typemapping, то вам нужно всего лишь сделать пять со смещениями, плюсы этого мало общего картографа.

+0

Все это еще больше ... Суть заключается в том, чтобы найти способ писать меньше строк и с меньшей степенью сложности. Если возиться с общими методами усложняет всю эту задачу, то я действительно не буду беспокоиться. Кстати спасибо за ответ, хотя я действительно не понял, что вы имели в виду. – AlFas

+0

Ну, вы получите меньше кода, а не 15 методов, которые вы получите. 6. Просто получите массив байтов из памяти и пропустите его через BytesToStructure BytesToStructure BytesToStructure Espen

Смежные вопросы