1
1
using System ;
2
+ using System . Collections . Generic ;
3
+ using System . Diagnostics ;
4
+ using System . Globalization ;
2
5
using System . Numerics ;
6
+ using System . Threading . Tasks ;
3
7
using Memory ;
4
8
5
9
namespace WriteAPI
6
10
{
7
11
public static class GameInterface
8
12
{
9
- private static string gameExe = "echovr.exe" ;
10
- private static string gameName = "Echo VR" ;
11
-
12
13
public static CameraTransform CameraTransform
13
14
{
14
15
get => GetTransform ( ) ;
@@ -18,82 +19,97 @@ public static CameraTransform CameraTransform
18
19
public static float LoneEchoSpeed => GetLoneEchoSpeed ( ) ;
19
20
public static float LoneEcho2Speed => GetLoneEcho2Speed ( ) ;
20
21
21
- private static readonly Mem echoVRMem = new Mem ( ) ;
22
- private static readonly Mem loneEchoMem = new Mem ( ) ;
23
- private static readonly Mem loneEcho2Mem = new Mem ( ) ;
22
+ private enum Game
23
+ {
24
+ EchoVR ,
25
+ LoneEcho ,
26
+ LoneEcho2
27
+ }
24
28
25
- public static void Hook ( )
29
+ private static readonly Dictionary < Game , Mem > mems = new Dictionary < Game , Mem > ( )
26
30
{
27
- gameName = Program . game switch
28
- {
29
- "echovr" => "Echo VR" ,
30
- "loneecho" => "Lone Echo" ,
31
- "loneecho2" => "Lone Echo 2" ,
32
- } ;
33
- gameExe = Program . game switch
34
- {
35
- "echovr" => "echovr.exe" ,
36
- "loneecho" => "loneecho.exe" ,
37
- "loneecho2" => "loneecho2.exe" ,
38
- } ;
39
-
40
- Console . WriteLine ( $ "Hooking { gameName } ...") ;
31
+ { Game . EchoVR , new Mem ( ) } ,
32
+ { Game . LoneEcho , new Mem ( ) } ,
33
+ { Game . LoneEcho2 , new Mem ( ) } ,
34
+ } ;
35
+
36
+ private static readonly Dictionary < Game , bool > hooked = new Dictionary < Game , bool > ( )
37
+ {
38
+ { Game . EchoVR , false } ,
39
+ { Game . LoneEcho , false } ,
40
+ { Game . LoneEcho2 , false } ,
41
+ } ;
42
+
43
+ private static readonly Dictionary < Game , string > exes = new Dictionary < Game , string > ( )
44
+ {
45
+ { Game . EchoVR , "echovr.exe" } ,
46
+ { Game . LoneEcho , "loneecho.exe" } ,
47
+ { Game . LoneEcho2 , "loneecho2.exe" } ,
48
+ } ;
49
+
50
+ private static void HookIfNotHooked ( Game game )
51
+ {
52
+ if ( ! hooked [ game ] ) Hook ( game ) ;
53
+ }
41
54
42
- bool hooked = false ;
43
- while ( true )
55
+ private static void Hook ( Game game )
56
+ {
57
+ bool hookedNow = mems [ game ] . OpenProcess ( exes [ game ] ) ;
58
+ if ( hookedNow && ! hooked [ game ] )
44
59
{
45
- if ( ! echoVRMem . OpenProcess ( gameExe ) )
46
- {
47
- if ( hooked )
48
- {
49
- Console . WriteLine ( $ "Could not find { gameName } process, make sure { gameName } is running") ;
50
- }
51
-
52
- hooked = false ;
53
- }
54
- else
55
- {
56
- if ( ! hooked )
57
- {
58
- Console . WriteLine ( $ "Found { gameName } Process") ;
59
- }
60
- hooked = true ;
61
- }
62
- System . Threading . Thread . Sleep ( 1000 ) ;
60
+ Console . WriteLine ( $ "Found { game } Process") ;
63
61
}
62
+
63
+ hooked [ game ] = hookedNow ;
64
64
}
65
65
66
66
private static void UpdateTransform ( CameraTransform transform )
67
67
{
68
+ HookIfNotHooked ( Game . EchoVR ) ;
69
+
68
70
transform . rotation = Quaternion . Normalize ( transform . rotation ) ;
69
- WriteVector ( echoVRMem , ConfigurationManager . config . cameraPositionAddress , transform . position ) ;
70
- WriteQuaternion ( echoVRMem , ConfigurationManager . config . cameraRotationAddress , transform . rotation ) ;
71
+ WriteVector ( mems [ Game . EchoVR ] , ConfigurationManager . config . cameraPositionAddress , transform . position ) ;
72
+ WriteQuaternion ( mems [ Game . EchoVR ] , ConfigurationManager . config . cameraRotationAddress , transform . rotation ) ;
71
73
#if DEBUG
72
74
Console . WriteLine ( $ "Wrote new camera transform: { transform } ") ;
73
75
#endif
76
+
77
+ // if we became unhooked, rehook for the next request
78
+ Task . Run ( ( ) => { Hook ( Game . EchoVR ) ; } ) ;
74
79
}
75
80
76
- static CameraTransform GetTransform ( )
81
+ private static CameraTransform GetTransform ( )
77
82
{
78
- Vector3 position = ReadVector ( echoVRMem , ConfigurationManager . config . cameraPositionAddress ) ;
79
- Quaternion rotation = ReadQuaternion ( echoVRMem , ConfigurationManager . config . cameraRotationAddress ) ;
83
+ HookIfNotHooked ( Game . EchoVR ) ;
84
+
85
+ Vector3 position = ReadVector ( mems [ Game . EchoVR ] , ConfigurationManager . config . cameraPositionAddress ) ;
86
+ Quaternion rotation = ReadQuaternion ( mems [ Game . EchoVR ] , ConfigurationManager . config . cameraRotationAddress ) ;
87
+
88
+ // if we became unhooked, rehook for the next request
89
+ Task . Run ( ( ) => { Hook ( Game . EchoVR ) ; } ) ;
90
+
80
91
return new CameraTransform ( position , rotation ) ;
81
92
}
82
93
83
94
private static float GetLoneEchoSpeed ( )
84
95
{
85
- if ( loneEchoMem . OpenProcess ( "loneecho" ) )
96
+ HookIfNotHooked ( Game . LoneEcho ) ;
97
+
98
+ if ( mems [ Game . LoneEcho ] . OpenProcess ( "loneecho" ) )
86
99
{
87
- return loneEchoMem . ReadFloat ( ConfigurationManager . config . loneEchoSpeedAddress , round : false ) ;
100
+ return mems [ Game . LoneEcho ] . ReadFloat ( ConfigurationManager . config . loneEchoSpeedAddress , round : false ) ;
88
101
}
89
102
90
103
return - 1 ;
91
104
}
105
+
92
106
private static float GetLoneEcho2Speed ( )
93
107
{
94
- if ( loneEcho2Mem . OpenProcess ( "loneecho2" ) )
108
+ HookIfNotHooked ( Game . LoneEcho2 ) ;
109
+
110
+ if ( mems [ Game . LoneEcho2 ] . OpenProcess ( "loneecho2" ) )
95
111
{
96
- return loneEcho2Mem . ReadFloat ( ConfigurationManager . config . loneEcho2SpeedAddress , round : false ) ;
112
+ return mems [ Game . LoneEcho2 ] . ReadFloat ( ConfigurationManager . config . loneEcho2SpeedAddress , round : false ) ;
97
113
}
98
114
99
115
return - 1 ;
@@ -102,23 +118,26 @@ private static float GetLoneEcho2Speed()
102
118
103
119
private static string AddressWithOffset ( string address , int offset )
104
120
{
105
- int preOffset = Convert . ToInt32 ( address , 16 ) ;
106
- return address [ ..^ 3 ] + ( preOffset + offset ) . ToString ( "X2" ) ;
121
+ string baseString = address [ ..^ 3 ] ;
122
+ string end = address [ ^ 2 ..] ;
123
+
124
+ int preOffset = Convert . ToInt32 ( $ "0x{ end } ", 16 ) ;
125
+ return baseString + ( preOffset + offset ) . ToString ( "X2" ) ;
107
126
}
108
-
127
+
109
128
private static void WriteVector ( Mem mem , string address , Vector3 vector )
110
129
{
111
- mem . WriteMemory ( AddressWithOffset ( address , 0 ) , "float" , vector . X . ToString ( ) ) ;
112
- mem . WriteMemory ( AddressWithOffset ( address , 4 ) , "float" , vector . Y . ToString ( ) ) ;
113
- mem . WriteMemory ( AddressWithOffset ( address , 8 ) , "float" , vector . Z . ToString ( ) ) ;
130
+ mem . WriteMemory ( AddressWithOffset ( address , 0 ) , "float" , vector . X . ToString ( CultureInfo . InvariantCulture ) ) ;
131
+ mem . WriteMemory ( AddressWithOffset ( address , 4 ) , "float" , vector . Y . ToString ( CultureInfo . InvariantCulture ) ) ;
132
+ mem . WriteMemory ( AddressWithOffset ( address , 8 ) , "float" , vector . Z . ToString ( CultureInfo . InvariantCulture ) ) ;
114
133
}
115
134
116
135
private static void WriteQuaternion ( Mem mem , string address , Quaternion quaternion )
117
136
{
118
- mem . WriteMemory ( AddressWithOffset ( address , 0 ) , "float" , quaternion . X . ToString ( ) ) ;
119
- mem . WriteMemory ( AddressWithOffset ( address , 4 ) , "float" , quaternion . Y . ToString ( ) ) ;
120
- mem . WriteMemory ( AddressWithOffset ( address , 8 ) , "float" , quaternion . Z . ToString ( ) ) ;
121
- mem . WriteMemory ( AddressWithOffset ( address , 12 ) , "float" , quaternion . W . ToString ( ) ) ;
137
+ mem . WriteMemory ( AddressWithOffset ( address , 0 ) , "float" , quaternion . X . ToString ( CultureInfo . InvariantCulture ) ) ;
138
+ mem . WriteMemory ( AddressWithOffset ( address , 4 ) , "float" , quaternion . Y . ToString ( CultureInfo . InvariantCulture ) ) ;
139
+ mem . WriteMemory ( AddressWithOffset ( address , 8 ) , "float" , quaternion . Z . ToString ( CultureInfo . InvariantCulture ) ) ;
140
+ mem . WriteMemory ( AddressWithOffset ( address , 12 ) , "float" , quaternion . W . ToString ( CultureInfo . InvariantCulture ) ) ;
122
141
}
123
142
124
143
private static Vector3 ReadVector ( Mem mem , string address )
@@ -138,4 +157,4 @@ private static Quaternion ReadQuaternion(Mem mem, string address)
138
157
return new Quaternion ( x , y , z , w ) ;
139
158
}
140
159
}
141
- }
160
+ }
0 commit comments