Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

+ Added OmsiStructPtr and OmsiStruct attributes for complex structs … #9

Merged
merged 1 commit into from
Apr 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[*.cs]

# IDE0055: Fix formatting
dotnet_diagnostic.IDE0055.severity = silent
10 changes: 5 additions & 5 deletions OmsiExtensions.sln
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31205.134
# Visual Studio Version 17
VisualStudioVersion = 17.1.32407.343
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmsiHook", "OmsiHook\OmsiHook.csproj", "{2E750CBE-F868-4AB7-96C2-27560F53E06B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OmsiHook", "OmsiHook\OmsiHook.csproj", "{2E750CBE-F868-4AB7-96C2-27560F53E06B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmsiExtensionsUI", "OmsiExtensionsUI\OmsiExtensionsUI.csproj", "{28DA0165-EAA7-4171-A065-319409682BD1}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OmsiExtensionsUI", "OmsiExtensionsUI\OmsiExtensionsUI.csproj", "{28DA0165-EAA7-4171-A065-319409682BD1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmsiExtensionsCLI", "OmsiExtensionsCLI\OmsiExtensionsCLI.csproj", "{FDA9A525-9722-46D3-B80C-8D2A76ABCA2D}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OmsiExtensionsCLI", "OmsiExtensionsCLI\OmsiExtensionsCLI.csproj", "{FDA9A525-9722-46D3-B80C-8D2A76ABCA2D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
76 changes: 75 additions & 1 deletion OmsiHook/CustomAttributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,43 @@

namespace OmsiHook
{
/// <summary>
/// Marks a field to be converted from an internal struct to a struct.<para/>
/// Used by Memory.MarshalStruct()
/// </summary>
[System.AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
sealed class OmsiStructAttribute : Attribute
{
// See the attribute guidelines at
// http://go.microsoft.com/fwlink/?LinkId=85236
readonly Type objType;
readonly Type internalType;
readonly bool requiresExtraMarshalling;

/// <summary>
///
/// </summary>
/// <param name="objType">The type of the object to convert to</param>
/// <param name="internalType">The intermidiate type to convert through
/// (in case Marshal.PtrToStruct doesn't support all the fields in objType).
/// Leave null to default to objType</param>
public OmsiStructAttribute(Type objType, Type internalType = null)
{
if (!objType.IsValueType)
throw new ArgumentException("OmsiStructPtr must be a pointer to a struct/value!");
if ((!internalType?.IsValueType) ?? false)
throw new ArgumentException("OmsiStructPtr must be a pointer to a struct/value!");

this.objType = objType;
this.requiresExtraMarshalling = internalType != null;
this.internalType = internalType ?? objType;
}

public Type ObjType => objType;
public Type InternalType => internalType;
public bool RequiresExtraMarshalling => requiresExtraMarshalling;
}

/// <summary>
/// Marks a field to be converted from an int to a string.<para/>
/// Used by Memory.MarshalStruct()
Expand Down Expand Up @@ -31,6 +68,43 @@ sealed class OmsiPtrAttribute : Attribute

}

/// <summary>
/// Marks a field to be converted from an int to a struct.<para/>
/// Used by Memory.MarshalStruct()
/// </summary>
[System.AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
sealed class OmsiStructPtrAttribute : Attribute
{
// See the attribute guidelines at
// http://go.microsoft.com/fwlink/?LinkId=85236
readonly Type objType;
readonly Type internalType;
readonly bool requiresExtraMarshalling;

/// <summary>
///
/// </summary>
/// <param name="objType">The type of the object to convert to</param>
/// <param name="internalType">The intermidiate type to convert through
/// (in case Marshal.PtrToStruct doesn't support all the fields in objType).
/// Leave null to default to objType</param>
public OmsiStructPtrAttribute(Type objType, Type internalType = null)
{
if (!objType.IsValueType)
throw new ArgumentException("OmsiStructPtr must be a pointer to a struct/value!");
if ((!internalType?.IsValueType) ?? false)
throw new ArgumentException("OmsiStructPtr must be a pointer to a struct/value!");

this.objType = objType;
this.requiresExtraMarshalling = internalType != null;
this.internalType = internalType ?? objType;
}

public Type ObjType => objType;
public Type InternalType => internalType;
public bool RequiresExtraMarshalling => requiresExtraMarshalling;
}

/// <summary>
/// Marks a field to be converted from an int to an OmsiObject.<para/>
/// Used by Memory.MarshalStruct()
Expand Down Expand Up @@ -76,7 +150,7 @@ public OmsiObjArrayPtrAttribute(Type objType)
}

/// <summary>
/// Marks a field to be converted from an int to an OmsiObject[].<para/>
/// Marks a field to be converted from an int to a struct[].<para/>
/// Used by Memory.MarshalStruct()
/// </summary>
[System.AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
Expand Down
2 changes: 1 addition & 1 deletion OmsiHook/D3DMeshObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
public class D3DMeshObject : D3DTransformObject
{
internal D3DMeshObject(Memory omsiMemory, int baseAddress) : base(omsiMemory, baseAddress) { }
internal D3DMeshObject() : base() { }
public D3DMeshObject() : base() { }
}
}
2 changes: 1 addition & 1 deletion OmsiHook/D3DObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
public class D3DObject : OmsiObject
{
internal D3DObject(Memory omsiMemory, int baseAddress) : base(omsiMemory, baseAddress) { }
internal D3DObject() : base() { }
public D3DObject() : base() { }
}
}
2 changes: 1 addition & 1 deletion OmsiHook/D3DTransformObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
public class D3DTransformObject : D3DObject
{
internal D3DTransformObject(Memory omsiMemory, int baseAddress) : base(omsiMemory, baseAddress) { }
internal D3DTransformObject() : base() { }
public D3DTransformObject() : base() { }
}
}
18 changes: 18 additions & 0 deletions OmsiHook/Memory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,13 @@ public OutStruct MarshalStruct<OutStruct, InStruct>(InStruct obj)
// Based on which kind of attribute the field has, perform special marshalling operations
switch (attr)
{
case OmsiStructAttribute a:
if (a.RequiresExtraMarshalling)
val = typeof(Memory).GetMethod(nameof(MarshalStruct))
.MakeGenericMethod(a.ObjType, a.InternalType)
.Invoke(this, new object[] { val });
break;

case OmsiStrPtrAttribute a:
val = ReadMemoryString((int)val, a.Wide);
break;
Expand All @@ -252,6 +259,17 @@ public OutStruct MarshalStruct<OutStruct, InStruct>(InStruct obj)
val = new IntPtr((int)val);
break;

case OmsiStructPtrAttribute a:
val = typeof(Memory).GetMethod(nameof(ReadMemory))
.MakeGenericMethod(a.InternalType)
.Invoke(this, new object[] { val });
// Perform extra marshalling if needed
if (a.RequiresExtraMarshalling)
val = typeof(Memory).GetMethod(nameof(MarshalStruct))
.MakeGenericMethod(a.ObjType, a.InternalType)
.Invoke(this, new object[] { val });
break;

case OmsiObjPtrAttribute a:
int addr = (int)val;
val = Activator.CreateInstance(a.ObjType, true);
Expand Down
2 changes: 1 addition & 1 deletion OmsiHook/OmsiComplMapObjInst.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
public class OmsiComplMapObjInst : OmsiPhysObjInst
{
internal OmsiComplMapObjInst(Memory omsiMemory, int baseAddress) : base(omsiMemory, baseAddress) { }
internal OmsiComplMapObjInst() : base() { }
public OmsiComplMapObjInst() : base() { }
}
}
11 changes: 11 additions & 0 deletions OmsiHook/OmsiComplMapSceneObjInst.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace OmsiHook
{
public class OmsiComplMapSceneObjInst : OmsiComplMapObjInst
{
public OmsiComplMapSceneObjInst() : base() { }

internal OmsiComplMapSceneObjInst(Memory omsiMemory, int baseAddress) : base(omsiMemory, baseAddress) { }

//TODO: OmsiComplMapSceneObjInst
}
}
9 changes: 9 additions & 0 deletions OmsiHook/OmsiFileObject.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace OmsiHook
{
public class OmsiFileObject : OmsiObject
{
public OmsiFileObject() : base() { }

internal OmsiFileObject(Memory memory, int address) : base(memory, address) { }
}
}
11 changes: 11 additions & 0 deletions OmsiHook/OmsiFileSpline.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace OmsiHook
{
public class OmsiFileSpline : OmsiObject
{
public OmsiFileSpline() : base() { }

internal OmsiFileSpline(Memory memory, int address) : base(memory, address) { }

//TODO: OmsiFileSpline
}
}
41 changes: 41 additions & 0 deletions OmsiHook/OmsiFileTerrain.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
namespace OmsiHook
{
public class OmsiFileTerrain : OmsiObject
{
public OmsiFileTerrain() : base() { }

internal OmsiFileTerrain(Memory memory, int address) : base(memory, address) { }

/*TODO: This looks like a 61x61 array of floats representing height + an additional float/int
* It's not correctly defined in IDR so dissassembly is required to work out how to use it.
public float[] Elevs
{
get => Memory.ReadMemoryStruct<float[]>(Address + 0x4);
}*/
/*public ? Inactive
{
get => Memory.ReadMemory<?>(Address + 0x3a2c);
set => Memory.WriteMemory(Address + 0x3a2c, value);
}*/
public short Count_Inactive
{
get => Memory.ReadMemory<short>(Address + 0x483c);
set => Memory.WriteMemory(Address + 0x483c, value);
}
public float Width_S
{
get => Memory.ReadMemory<float>(Address + 0x4840);
set => Memory.WriteMemory(Address + 0x4840, value);
}
public float Width_N
{
get => Memory.ReadMemory<float>(Address + 0x4844);
set => Memory.WriteMemory(Address + 0x4844, value);
}
public int MyKachel
{
get => Memory.ReadMemory<int>(Address + 0x4848);
set => Memory.WriteMemory(Address + 0x4848, value);
}
}
}
11 changes: 11 additions & 0 deletions OmsiHook/OmsiFileWater.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace OmsiHook
{
public class OmsiFileWater : OmsiObject
{
public OmsiFileWater() : base() { }

internal OmsiFileWater(Memory memory, int address) : base(memory, address) { }

//TODO: OmsiFileWater
}
}
24 changes: 7 additions & 17 deletions OmsiHook/OmsiHook.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ public class OmsiHook
{
private Memory omsiMemory;
private Process process;
private int baseOffset = 0;

/// <summary>
/// Gets the vehicle instance being driven by the player.
Expand All @@ -38,12 +37,10 @@ public async void AttachToOMSI()
{
await Task.Delay(250);
(found, process) = omsiMemory.Attach("omsi");
Console.WriteLine("Waiting for OMSI.exe...");
}

Console.WriteLine("Connected succesfully! Logging data:");
int baseAddr = 0x461500;
int moduleBase = GetModuleOffset("Omsi.exe");
baseOffset = omsiMemory.ReadMemory<int>(baseAddr + moduleBase);
Console.WriteLine("Connected succesfully!");
}

public OmsiRoadVehicleInst GetRoadVehicleInst(int index)
Expand All @@ -64,23 +61,14 @@ private int GetListItem(int addr, int index)
return omsiMemory.ReadMemory<int>(omsiMemory.ReadMemory<int>(omsiMemory.ReadMemory<int>(omsiMemory.ReadMemory<int>(addr) + 0x28) + 0x4) + index * 4);
}

private int GetModuleOffset(string name)
{
foreach (ProcessModule m in process.Modules)
{
if (m.ModuleName == name)
return m.BaseAddress.ToInt32();
}
return -1;
}

/// <summary>
/// Finds and returns the value of a named float variable.
/// </summary>
/// <param name="varName">Name of variable to look for</param>
/// <param name="baseAddr">Value of *(baseAddr + moduleBase)</param>
/// <returns></returns>
private float FindVar(string varName, int baseAddr)
[Obsolete("This API is going to be moved into the OmsiRoadVehicleInst class in future!")]
public float FindVar(string varName, int baseAddr)
{
//Offsets used in these lookups are derived from the dissassembly of omsi at 0x642205
int varNameAddr = omsiMemory.ReadMemory<int>(omsiMemory.ReadMemory<int>(baseAddr + 0x710) + 0x1ec);
Expand All @@ -100,7 +88,8 @@ private float FindVar(string varName, int baseAddr)
/// <param name="varName">Name of variable to look for</param>
/// <param name="baseAddr">Value of *(baseAddr + moduleBase)</param>
/// <returns></returns>
private string FindStringVar(string varName, int baseAddr)
[Obsolete("This API is going to be moved into the OmsiRoadVehicleInst class in future!")]
public string FindStringVar(string varName, int baseAddr)
{
//Offsets used in these lookups are derived from the dissassembly of omsi at 0x642205
int varNameAddr = omsiMemory.ReadMemory<int>(omsiMemory.ReadMemory<int>(baseAddr + 0x710) + 0x1f0);
Expand All @@ -119,6 +108,7 @@ private string FindStringVar(string varName, int baseAddr)
/// </summary>
/// <param name="addr"></param>
/// <returns></returns>
[Obsolete("Use `Memory.ReadMemoryString()` instead")]
private string ReadString(int addr, bool wide = false)
{
var sb = new StringBuilder();
Expand Down
12 changes: 6 additions & 6 deletions OmsiHook/OmsiHook.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@
<Copyright>Copyright Thomas Mathieson 2022 all rights reserved</Copyright>
<PackageProjectUrl>https://github.com/space928/Omsi-Extensions</PackageProjectUrl>
<RepositoryUrl>https://github.com/space928/Omsi-Extensions</RepositoryUrl>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageLicenseFile></PackageLicenseFile>
<Description>OmsiHook is a simple library for hooking into Omsi's memory for modding.</Description>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<AssemblyVersion>1.0.1.0</AssemblyVersion>
<FileVersion>1.0.1.0</FileVersion>
<Version>1.0.1</Version>
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
</PropertyGroup>

<ItemGroup>
<None Include="..\LICENSE">
<Pack>True</Pack>
<PackagePath></PackagePath>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="..\.editorconfig" Link=".editorconfig" />
</ItemGroup>

</Project>
Loading