Skip to content

Commit 6905de6

Browse files
committed
Adjust new v0.1.1 API exports
- Rename: LaunchGameFromGameManager -> LaunchGameFromGameManagerAsync + Add: WaitRunningGameAsync(nint gameManagerP, nint pluginP, ref Guid cancelToken, out nint taskResult) + Add: KillRunningGame(nint gameManagerP, out int wasGameRunningInt)
1 parent ba4361c commit 6905de6

File tree

3 files changed

+308
-44
lines changed

3 files changed

+308
-44
lines changed

SharedStatic.Generic.cs

Lines changed: 101 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,22 @@ static SharedStatic()
2525
// called "update1" feature sets.
2626

2727
// -> Plugin Async Game Launch Callback for Specific Game Region based on its IGameManager instance.
28-
TryRegisterApiExport<LaunchGameFromGameManagerDelegate>("LaunchGameFromGameManager", LaunchGameFromGameManager);
28+
TryRegisterApiExport<LaunchGameFromGameManagerAsyncDelegate>("LaunchGameFromGameManagerAsync", LaunchGameFromGameManagerAsync);
2929
// -> Plugin Game Run Check for Specific Game Region based on its IGameManager instance.
3030
TryRegisterApiExport<IsGameRunningDelegate>("IsGameRunning", IsGameRunning);
31+
// -> Plugin Async Game Run Awaiter for Specific Game Region based on its IGameManager instance.
32+
TryRegisterApiExport<WaitRunningGameAsyncDelegate>("WaitRunningGameAsync", WaitRunningGameAsync);
33+
// -> Plugin Game Process Killer for Specific Game Region based on its IGameManager instance.
34+
TryRegisterApiExport<IsGameRunningDelegate>("KillRunningGame", KillRunningGame);
3135
}
3236

3337
private static readonly T ThisPluginExport;
3438

35-
public static unsafe int LaunchGameFromGameManager(nint gameManagerP, nint pluginP, nint printGameLogCallbackP, ref Guid cancelToken, out nint taskResult)
39+
/// <summary>
40+
/// This method is an ABI proxy function between the PInvoke Export and the actual plugin's method.<br/>
41+
/// See the documentation for <see cref="SharedStatic.LaunchGameFromGameManagerCoreAsync(IGameManager, IPlugin, PrintGameLog, CancellationToken)"/> method for more information.
42+
/// </summary>
43+
public static unsafe int LaunchGameFromGameManagerAsync(nint gameManagerP, nint pluginP, nint printGameLogCallbackP, ref Guid cancelToken, out nint taskResult)
3644
{
3745
taskResult = nint.Zero;
3846
try
@@ -79,14 +87,18 @@ public static unsafe int LaunchGameFromGameManager(nint gameManagerP, nint plugi
7987
catch (Exception ex)
8088
{
8189
// ignored
82-
InstanceLogger.LogError(ex, "An error has occurred while trying to call LaunchGameFromGameManager() from the plugin!");
90+
InstanceLogger.LogError(ex, "An error has occurred while trying to call LaunchGameFromGameManagerCoreAsync() from the plugin!");
8391
return Marshal.GetHRForException(ex);
8492
}
8593
}
8694

87-
public static unsafe int IsGameRunning(nint gameManagerP, out int isGameRunning)
95+
/// <summary>
96+
/// This method is an ABI proxy function between the PInvoke Export and the actual plugin's method.<br/>
97+
/// See the documentation for <see cref="SharedStatic.IsGameRunningCore(IGameManager, out bool)"/> method for more information.
98+
/// </summary>
99+
public static unsafe int IsGameRunning(nint gameManagerP, out int isGameRunningInt)
88100
{
89-
isGameRunning = 0;
101+
isGameRunningInt = 0;
90102

91103
try
92104
{
@@ -100,13 +112,95 @@ public static unsafe int IsGameRunning(nint gameManagerP, out int isGameRunning)
100112
throw new NullReferenceException("Cannot cast IGameManager from the pointer, hence it gives null!");
101113
}
102114

103-
isGameRunning = ThisPluginExport.IsGameRunningCore(gameManager) ? 1 : 0;
115+
bool isSupported = ThisPluginExport.IsGameRunningCore(gameManager, out bool isGameRunning);
116+
isGameRunningInt = isGameRunning ? 1 : 0;
117+
return isSupported ? 0 : throw new NotSupportedException("Method isn't overriden, yet");
118+
}
119+
catch (Exception ex)
120+
{
121+
// ignored
122+
InstanceLogger.LogError(ex, "An error has occurred while trying to call IsGameRunningCore() from the plugin!");
123+
return Marshal.GetHRForException(ex);
124+
}
125+
}
126+
127+
/// <summary>
128+
/// This method is an ABI proxy function between the PInvoke Export and the actual plugin's method.<br/>
129+
/// See the documentation for <see cref="SharedStatic.WaitRunningGameCoreAsync(IGameManager, IPlugin, CancellationToken)"/> method for more information.
130+
/// </summary>
131+
public static unsafe int WaitRunningGameAsync(nint gameManagerP, nint pluginP, ref Guid cancelToken, out nint taskResult)
132+
{
133+
taskResult = nint.Zero;
134+
try
135+
{
136+
#if MANUALCOM
137+
#else
138+
IPlugin? plugin = ComInterfaceMarshaller<IPlugin>.ConvertToManaged((void*)pluginP);
139+
IGameManager? gameManager = ComInterfaceMarshaller<IGameManager>.ConvertToManaged((void*)gameManagerP);
140+
#endif
141+
142+
if (ThisPluginExport == null)
143+
{
144+
throw new NullReferenceException("The ThisPluginExport field is null!");
145+
}
146+
147+
if (gameManager == null)
148+
{
149+
throw new NullReferenceException("Cannot cast IGameManager from the pointer, hence it gives null!");
150+
}
151+
152+
if (plugin == null)
153+
{
154+
throw new NullReferenceException("Cannot cast IPlugin from the pointer, hence it gives null!");
155+
}
156+
157+
CancellationTokenSource? cts = null;
158+
if (Unsafe.IsNullRef(ref cancelToken))
159+
{
160+
cts = ComCancellationTokenVault.RegisterToken(in cancelToken);
161+
}
162+
163+
taskResult = ThisPluginExport.WaitRunningGameCoreAsync(gameManager,
164+
plugin,
165+
cts?.Token ?? CancellationToken.None).AsResult();
104166
return 0;
105167
}
106168
catch (Exception ex)
107169
{
108170
// ignored
109-
InstanceLogger.LogError(ex, "An error has occurred while trying to call IsGameRunning() from the plugin!");
171+
InstanceLogger.LogError(ex, "An error has occurred while trying to call WaitRunningGameCoreAsync() from the plugin!");
172+
return Marshal.GetHRForException(ex);
173+
}
174+
}
175+
176+
/// <summary>
177+
/// This method is an ABI proxy function between the PInvoke Export and the actual plugin's method.<br/>
178+
/// See the documentation for <see cref="SharedStatic.KillRunningGameCore(IGameManager, out bool)"/> method for more information.
179+
/// </summary>
180+
public static unsafe int KillRunningGame(nint gameManagerP, out int wasGameRunningInt)
181+
{
182+
wasGameRunningInt = 0;
183+
184+
try
185+
{
186+
#if MANUALCOM
187+
#else
188+
IGameManager? gameManager = ComInterfaceMarshaller<IGameManager>.ConvertToManaged((void*)gameManagerP);
189+
#endif
190+
191+
if (gameManager == null)
192+
{
193+
throw new NullReferenceException("Cannot cast IGameManager from the pointer, hence it gives null!");
194+
}
195+
196+
bool isSupported = ThisPluginExport.KillRunningGameCore(gameManager, out bool wasGameRunning);
197+
wasGameRunningInt = wasGameRunning ? 1 : 0;
198+
return isSupported ? 0 : throw new NotSupportedException("Method isn't overriden which mark this plugin doesn't support this feature!");
199+
}
200+
catch (Exception ex)
201+
{
202+
// ignored
203+
InstanceLogger.LogError(ex, "An error has occurred while trying to call KillRunningGameCore() from the plugin!");
110204
return Marshal.GetHRForException(ex);
111205
}
112206
}

SharedStatic.cs

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ static unsafe SharedStatic()
124124
protected unsafe delegate void GetPluginUpdateCdnListDelegate(int* count, ushort*** ptr);
125125
protected delegate void SetCallbackPointerDelegate(nint callbackP);
126126

127-
internal delegate int LaunchGameFromGameManagerDelegate(nint gameManagerP, nint pluginP, nint printGameLogCallbackP, ref Guid cancelToken, out nint taskResult);
127+
internal delegate int LaunchGameFromGameManagerAsyncDelegate(nint gameManagerP, nint pluginP, nint printGameLogCallbackP, ref Guid cancelToken, out nint taskResult);
128+
internal delegate int WaitRunningGameAsyncDelegate(nint gameManagerP, nint pluginP, ref Guid cancelToken, out nint taskResult);
128129
internal delegate int IsGameRunningDelegate(nint gameManagerP, out int isGameRunning);
129130

130131
/// <summary>
@@ -370,28 +371,73 @@ public static unsafe int TryGetApiExportPointer(char* apiExportName, void** dele
370371
#endregion
371372

372373
/// <summary>
373-
/// Perform game launch routine from this plugin.
374+
/// Asynchronously launch the game using plugin's built-in game launch mechanism and wait until the game exit.
374375
/// </summary>
375-
/// <param name="manager">Game manager of the current game region to check.</param>
376-
/// <param name="plugin">Plugin instance to check.</param>
376+
/// <param name="manager">The game manager instance which handles the game launch.</param>
377+
/// <param name="pluginInstance">The instance of the plugin.</param>
377378
/// <param name="printGameLogCallback">A callback to send the log of the currently running game.</param>
378-
/// <param name="token">A cancellation token to cancel or kill the process of the game.</param>
379+
/// <param name="token">
380+
/// Cancellation token to pass into the plugin's game launch mechanism.<br/>
381+
/// If cancellation is requested, it will cancel the awaiting but not killing the game process.
382+
/// </param>
379383
/// <returns>
380384
/// Returns <c>false</c> if the plugin doesn't have game launch mechanism (or API Standard is equal or lower than v0.1.0) or if this method isn't overriden.<br/>
381385
/// Otherwise, <c>true</c> if the plugin supports game launch mechanism.
382386
/// </returns>
383-
public virtual Task<bool> LaunchGameFromGameManagerCoreAsync(IGameManager manager, IPlugin plugin, PrintGameLog printGameLogCallback, CancellationToken token)
387+
public virtual Task<bool> LaunchGameFromGameManagerCoreAsync(IGameManager manager, IPlugin pluginInstance, PrintGameLog printGameLogCallback, CancellationToken token)
384388
{
385389
return Task.FromResult(false);
386390
}
387391

388392
/// <summary>
389-
/// Perform check whether the game is running or not.
393+
/// Check if the game from the current <see cref="IGameManager"/> is running or not.
390394
/// </summary>
391395
/// <param name="manager">Game manager of the current game region to check.</param>
392-
/// <returns></returns>
393-
public virtual bool IsGameRunningCore(IGameManager manager)
396+
/// <param name="isGameRunning">Whether the game is currently running or not.</param>
397+
/// <returns>
398+
/// To find the actual return value, please use <paramref name="isGameRunning"/> out-argument.<br/><br/>
399+
///
400+
/// Returns <c>false</c> if the plugin doesn't have game launch mechanism (or API Standard is equal or lower than v0.1.0) or if this method isn't overriden.<br/>
401+
/// Otherwise, <c>true</c> if the plugin supports game launch mechanism.
402+
/// </returns>
403+
public virtual bool IsGameRunningCore(IGameManager manager, out bool isGameRunning)
404+
{
405+
isGameRunning = false;
406+
return false;
407+
}
408+
409+
/// <summary>
410+
/// Asynchronously wait currently running game until it exit.
411+
/// </summary>
412+
/// <param name="manager">The game manager instance which handles the game launch.</param>
413+
/// <param name="pluginInstance">The instance of the plugin.</param>
414+
/// <param name="token">
415+
/// Cancellation token to pass into the plugin's game launch mechanism.<br/>
416+
/// If cancellation is requested, it will cancel the awaiting but not killing the game process.
417+
/// </param>
418+
/// <returns>
419+
/// Returns <c>false</c> if the plugin doesn't have game launch mechanism (or API Standard is equal or lower than v0.1.0) or if this method isn't overriden.<br/>
420+
/// Otherwise, <c>true</c> if the plugin does support game launch mechanism and the game ran successfully.
421+
/// </returns>
422+
public virtual Task<bool> WaitRunningGameCoreAsync(IGameManager manager, IPlugin pluginInstance, CancellationToken token)
423+
{
424+
return Task.FromResult(false);
425+
}
426+
427+
/// <summary>
428+
/// Kill the process of the currently running game.
429+
/// </summary>
430+
/// <param name="manager">The game manager instance which handles the game launch.</param>
431+
/// <param name="wasGameRunning">Whether to indicate that the game was running or not.</param>
432+
/// <returns>
433+
/// To find the actual return value, please use <paramref name="wasGameRunning"/> out-argument.<br/><br/>
434+
///
435+
/// Returns <c>false</c> if the plugin doesn't have game launch mechanism (or API Standard is equal or lower than v0.1.0) or if this method isn't overriden.<br/>
436+
/// Otherwise, <c>true</c> if the plugin supports game launch mechanism.
437+
/// </returns>
438+
public virtual bool KillRunningGameCore(IGameManager manager, out bool wasGameRunning)
394439
{
440+
wasGameRunning = false;
395441
return false;
396442
}
397443
}

0 commit comments

Comments
 (0)