2016-11-13 9 views
-1

그래서 게임의 제작자에게 더 많은 수준의 편집기 도구 (이 값에 대한 포인터가있는 고급 알고리즘을 사용하여 게임 값을 조정하여)를 제공하는 프로그램을 만들고 있습니다. 바로 가기에 대한 값을 설정/검색하는 방법을 만들었습니다. 입력 포인터. 그러나 게임에는 Int32, Float 및 Boolean 변수가 있으므로 동일한 수의 포인터에 대해 각 데이터 유형마다 3 가지 방법이 필요하며 포인터에서 값을 검색하는 데 총 15 가지 방법을 제공하는 각각 5 가지 오버로드가 있습니다. 코드가없는 메소드는 다음과 같습니다.동일한 알고리즘으로 다른 데이터 형식 값을 반환 할 때 일반 형식 메서드 또는 지정된 형식 알고리즘?

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) 

이제는 그 중 일부가 작동하지 않는 이유를 묻지 않습니다. 그들은 실제로 잘 작동합니다 (저는 생각합니다).하지만 모든 다른 유형에 대한 일반적인 방법을 만들 가능성에 대해서도 생각해 봤습니다. 그러나 실제로 방법을 알지 못하고 그런 방법을 만드는 것에 대해 확신하지 못합니다.

[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; 
} 
:
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 일이 무엇인지 궁금

이 여기에 너무 하나의 코드입니다 : 유용한 모든 ... 여기

GetIntFromPointers(IntPtr baseAddress, IntPtr offset0, IntPtr offset1, IntPtr offset2, IntPtr offset3, IntPtr offset4) 방법에 대한 코드는

답변

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 ... 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; 
    } 
} 

을 그리고 단지, 당신 만이 작은 일반 매퍼 PLUSS, 오프셋 (offset) 다섯을 할 필요가 typemapping없이 비트를 읽고 기억을한다.

+0

이것은 훨씬 더 복잡합니다 ... 요점은 더 적은 선을 그리고 덜 복잡하게 작성하는 방법을 찾는 것입니다. 제네릭 메서드를 사용하는 것이 전체 작업을 복잡하게 만들면 난별로 신경 쓰지 않을 것입니다. BTW는 대답을 주셔서 감사합니다. – AlFas

+0

음, 코드가 적어지면 15 가지 방법을 사용할 수 있습니다. 6. 바이트 배열을 메모리에서 꺼내서 넣으십시오. BytesToStructure BytesToStructure BytesToStructure Espen