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

Support and show scores for Free for All #167

Merged
merged 1 commit into from
Dec 30, 2021
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
65 changes: 65 additions & 0 deletions titanfall2-rp/MpGameStats/FreeForAll.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using Process.NET;

namespace titanfall2_rp.MpGameStats
{
public class FreeForAll : MpStats
{
public FreeForAll(Titanfall2Api tf2Api, ProcessSharp processSharp) : base(tf2Api, processSharp)
{
}

/// <summary>
/// The score of "team 1" is actually just the current user's score
/// </summary>
/// <returns></returns>
public override int GetTeam1Score()
{
return GetScore(GetMyIdOnServer());
}

/// <summary>
/// The score of "team 2" is actually the score of the player with the highest score
/// </summary>
/// <returns></returns>
public override int GetTeam2Score()
{
return GetHighestScoreInGameIgnoringPlayer(GetMyIdOnServer());
}

/// <summary>
/// Get the score of a user.
/// </summary>
/// <param name="playerId">the id of the player, leave blank to use the current player</param>
/// <returns>the user's score</returns>
private int GetScore(int playerId = -1)
{
var id = playerId < 0 ? GetMyIdOnServer() : playerId;
return Sharp.Memory.Read<int>(Tf2Api.EngineDllBaseAddress + MpOffsets.FreeForAll.Score +
(id * MpOffsets.FreeForAll.AttritionStatsPlayerIdOffset));
}

private int GetHighestScoreInGameIgnoringPlayer(int playerIdToIgnore = -1)
{
var currentHighest = int.MinValue;
// Loop through all the score slots
for (var i = 0; i < 64; i++)
{
// Skip the player whose ID we were instructed to ignore
if (i == playerIdToIgnore)
{
continue;
}

var playerScore = GetScore(i);
// If the known highest score turns out to be lower than this player's score...
if (playerScore > currentHighest)
{
// Set the known highest to be that new highest score
currentHighest = playerScore;
}
}

return currentHighest;
}
}
}
25 changes: 16 additions & 9 deletions titanfall2-rp/MpStats.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ namespace titanfall2_rp
/// </summary>
public abstract class MpStats
{
private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod()!.DeclaringType);

private protected const string HelpMeBruh =
"Getting this value is not supported. " +
"If you want this to be possible, you'll need to contribute this yourself or tell me how the heck to get it.";

private protected readonly Titanfall2Api Tf2Api;
private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod()!.DeclaringType);
private protected readonly ProcessSharp Sharp;

private protected readonly Titanfall2Api Tf2Api;

protected MpStats(Titanfall2Api titanfall2Api, ProcessSharp processSharp)
{
Tf2Api = titanfall2Api;
Expand Down Expand Up @@ -202,6 +202,7 @@ public static MpStats Of(Titanfall2Api titanfall2Api, ProcessSharp sharp)
GameMode.fd_master => new FrontierDefense(titanfall2Api, sharp),
GameMode.fd_insane => new FrontierDefense(titanfall2Api, sharp),
GameMode.solo => throw new ArgumentException("Tried to get multiplayer details for the campaign"),
GameMode.ffa => new FreeForAll(titanfall2Api, sharp),
_ => ReportGameModeFailure(gameMode)
};
}
Expand Down Expand Up @@ -310,6 +311,12 @@ internal static class MpOffsets
/// </summary>
internal const int Name = 0x13fa6eb8;

/// <summary>
/// This value (multiplied by the player's ID) is added to the last of the <see cref="NamePointerOffsets"/>
/// when finding a player's name.
/// </summary>
internal const int NamePlayerIdIncrement = 0x58;

/// <summary>
/// The <see cref="Name"/> address is really the address to a pointer. Applying these offsets to that pointer
/// points to the address with the actual desired value.
Expand All @@ -320,18 +327,18 @@ internal static int[] NamePointerOffsets
get { return new[] { 0x18, 0x50, 0x38, 0x38 }; }
}

/// <summary>
/// This value (multiplied by the player's ID) is added to the last of the <see cref="NamePointerOffsets"/>
/// when finding a player's name.
/// </summary>
internal const int NamePlayerIdIncrement = 0x58;

public static class Attrition
{
internal const int Kills = 0x1123D27C;
internal const int MinionKills = 0x1123D384;
internal const int Score = 0x1123D510;
internal const int AttritionStatsPlayerIdOffset = 0x4;
}

public static class FreeForAll
{
internal const int Score = Attrition.Score;
internal const int AttritionStatsPlayerIdOffset = Attrition.AttritionStatsPlayerIdOffset;
}
}
}