using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using RWF;
using UnboundLib;
using UnboundLib.Extensions;
using UnboundLib.GameModes;
using UnboundLib.Networking;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace Scoreboard
{
[HarmonyPatch(typeof(HealthHandler), "DoDamage")]
internal static class DoDamagePatch
{
private static void Prefix(HealthHandler __instance, Vector2 damage, Player damagingPlayer, bool ignoreBlock, CharacterData ___data)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
if (!(damage == Vector2.zero) && ___data.isPlaying && !___data.dead && (!___data.block.IsBlocking() || ignoreBlock) && !__instance.isRespawning)
{
StatsTracker.OnDamage(___data.player, damagingPlayer, ((Vector2)(ref damage)).magnitude);
}
}
}
[HarmonyPatch(typeof(HealthHandler), "RPCA_Die")]
internal static class DiePatch
{
private static void Prefix(CharacterData ___data)
{
if (___data.isPlaying && !___data.dead)
{
StatsTracker.OnDeath(___data.player);
}
}
}
[HarmonyPatch(typeof(HealthHandler), "RPCA_Die_Phoenix")]
internal static class DiePhoenixPatch
{
private static void Prefix(CharacterData ___data)
{
if (___data.isPlaying && !___data.dead)
{
StatsTracker.OnDeath(___data.player);
}
}
}
[HarmonyPatch(typeof(HealthHandler), "Revive")]
internal static class RevivePatch
{
private static void Prefix(CharacterData ___data)
{
StatsTracker.OnRevive(___data.player);
}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("com.stinkybussybois.rounds.scoreboard", "Scoreboard", "1.0.0")]
[BepInProcess("Rounds.exe")]
public class ScoreboardPlugin : BaseUnityPlugin
{
public const string ModId = "com.stinkybussybois.rounds.scoreboard";
public const string ModName = "Scoreboard";
public const string Version = "1.0.0";
internal static ConfigEntry<KeyCode> ShowKey;
private void Awake()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
ShowKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ShowKey", (KeyCode)9, "Hold this key to show the scoreboard.");
new Harmony("com.stinkybussybois.rounds.scoreboard").PatchAll();
}
private void Start()
{
Unbound.RegisterHandshake("com.stinkybussybois.rounds.scoreboard", (Action)delegate
{
});
Unbound.RegisterCredits("Scoreboard", new string[1] { "Hold Tab for kills, deaths, round wins and more." }, new string[0], new string[0]);
GameModeManager.AddHook("GameStart", (Func<IGameModeHandler, IEnumerator>)((IGameModeHandler _) => StatsTracker.ResetAll()));
((Component)this).gameObject.AddComponent<ScoreboardUI>();
}
}
public class ScoreboardUI : MonoBehaviour
{
private static readonly string[] Headers = new string[7] { "Player", "Rounds", "Kills", "Deaths", "K/D", "Self-kills", "Biggest hit" };
private static readonly float[] ColumnWidths = new float[7] { 300f, 110f, 100f, 100f, 100f, 130f, 150f };
private const float RowHeight = 44f;
private const float Padding = 24f;
private GUIStyle cellStyle;
private GUIStyle nameStyle;
private GUIStyle headerStyle;
private GUIStyle titleStyle;
private Texture2D background;
private Texture2D rowShade;
private void OnGUI()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_0116: Unknown result type (might be due to invalid IL or missing references)
//IL_0170: Unknown result type (might be due to invalid IL or missing references)
//IL_019e: Unknown result type (might be due to invalid IL or missing references)
//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
//IL_0325: Unknown result type (might be due to invalid IL or missing references)
//IL_0220: Unknown result type (might be due to invalid IL or missing references)
//IL_0308: Unknown result type (might be due to invalid IL or missing references)
if (!Input.GetKey(ScoreboardPlugin.ShowKey.Value))
{
return;
}
List<Player> list = PlayerManager.instance?.players?.Where((Player p) => (Object)(object)p != (Object)null).ToList();
if (list == null || list.Count == 0)
{
return;
}
EnsureStyles();
List<(Player, PlayerStats, int)> list2 = (from p in list
select (player: p, stats: StatsTracker.Get(p.playerID), rounds: RoundWins(p)) into r
orderby r.rounds descending, r.stats.Kills descending, r.stats.Deaths
select r).ToList();
float num = (float)Screen.height / 1080f;
GUI.matrix = Matrix4x4.Scale(new Vector3(num, num, 1f));
float num2 = (float)Screen.width / num;
float num3 = ColumnWidths.Sum();
float num4 = num3 + 48f;
float num5 = 108f + 44f * (float)(list2.Count + 1);
Rect val = default(Rect);
((Rect)(ref val))..ctor((num2 - num4) / 2f, 140f, num4, num5);
GUI.DrawTexture(val, (Texture)(object)background);
GUI.Label(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y + 24f - 6f, num4, 50f), "SCOREBOARD", titleStyle);
float num6 = ((Rect)(ref val)).y + 24f + 60f;
DrawRow(((Rect)(ref val)).x + 24f, num6, Headers, headerStyle, headerStyle, Color.white);
for (int num7 = 0; num7 < list2.Count; num7++)
{
num6 += 44f;
if (num7 % 2 == 0)
{
GUI.DrawTexture(new Rect(((Rect)(ref val)).x + 24f, num6, num3, 44f), (Texture)(object)rowShade);
}
(Player, PlayerStats, int) tuple = list2[num7];
Player item = tuple.Item1;
PlayerStats item2 = tuple.Item2;
int item3 = tuple.Item3;
string text = ((item2.Deaths == 0) ? ((float)item2.Kills) : ((float)item2.Kills / (float)item2.Deaths)).ToString("0.00");
string[] cells = new string[7]
{
PlayerName(item),
item3.ToString(),
item2.Kills.ToString(),
item2.Deaths.ToString(),
text,
item2.SelfKills.ToString(),
Mathf.RoundToInt(item2.BiggestHit).ToString()
};
DrawRow(((Rect)(ref val)).x + 24f, num6, cells, nameStyle, cellStyle, PlayerColor(item));
}
GUI.matrix = Matrix4x4.identity;
}
private static void DrawRow(float x, float y, string[] cells, GUIStyle firstStyle, GUIStyle style, Color nameColor)
{
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
Rect val = default(Rect);
for (int i = 0; i < cells.Length; i++)
{
((Rect)(ref val))..ctor(x, y, ColumnWidths[i], 44f);
if (i == 0)
{
Color contentColor = GUI.contentColor;
GUI.contentColor = nameColor;
GUI.Label(new Rect(((Rect)(ref val)).x + 12f, ((Rect)(ref val)).y, ((Rect)(ref val)).width - 12f, ((Rect)(ref val)).height), cells[i], firstStyle);
GUI.contentColor = contentColor;
}
else
{
GUI.Label(val, cells[i], style);
}
x += ColumnWidths[i];
}
}
private static int RoundWins(Player player)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
try
{
IGameModeHandler currentHandler = GameModeManager.CurrentHandler;
return (currentHandler != null) ? currentHandler.GetTeamScore(player.teamID).rounds : 0;
}
catch
{
return 0;
}
}
private static string PlayerName(Player player)
{
LobbyCharacter character = PlayerExtensions.GetAdditionalData(player).character;
string text = ((character != null) ? character.NickName : null);
if (!string.IsNullOrEmpty(text))
{
return text;
}
return $"Player {player.playerID + 1}";
}
private static Color PlayerColor(Player player)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
try
{
return PlayerSkinBank.GetPlayerSkinColors(PlayerExtensions.colorID(player)).color;
}
catch
{
return Color.white;
}
}
private void EnsureStyles()
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Expected O, but got Unknown
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Expected O, but got Unknown
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Expected O, but got Unknown
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Expected O, but got Unknown
if (cellStyle == null)
{
background = SolidTexture(new Color(0.05f, 0.05f, 0.08f, 0.88f));
rowShade = SolidTexture(new Color(1f, 1f, 1f, 0.05f));
cellStyle = new GUIStyle(GUI.skin.label)
{
fontSize = 24,
alignment = (TextAnchor)4
};
cellStyle.normal.textColor = Color.white;
nameStyle = new GUIStyle(cellStyle)
{
alignment = (TextAnchor)3,
fontStyle = (FontStyle)1,
clipping = (TextClipping)1
};
headerStyle = new GUIStyle(cellStyle)
{
fontSize = 20,
fontStyle = (FontStyle)1
};
headerStyle.normal.textColor = new Color(0.7f, 0.7f, 0.75f);
titleStyle = new GUIStyle(cellStyle)
{
fontSize = 34,
fontStyle = (FontStyle)1
};
}
}
private static Texture2D SolidTexture(Color color)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
Texture2D val = new Texture2D(1, 1);
val.SetPixel(0, 0, color);
val.Apply();
return val;
}
}
public class PlayerStats
{
public int Kills;
public int Deaths;
public int SelfKills;
public float BiggestHit;
}
public static class StatsTracker
{
private const float KillCreditWindow = 10f;
private static readonly Dictionary<int, PlayerStats> stats = new Dictionary<int, PlayerStats>();
private static readonly Dictionary<int, (Player attacker, float time)> lastHit = new Dictionary<int, (Player, float)>();
public static bool IsHost
{
get
{
if (!PhotonNetwork.OfflineMode)
{
return PhotonNetwork.IsMasterClient;
}
return true;
}
}
public static PlayerStats Get(int playerID)
{
if (!stats.TryGetValue(playerID, out var value))
{
value = new PlayerStats();
stats[playerID] = value;
}
return value;
}
public static IEnumerator ResetAll()
{
stats.Clear();
lastHit.Clear();
yield break;
}
public static void OnDamage(Player victim, Player attacker, float amount)
{
if (!IsHost || (Object)(object)victim == (Object)null || (Object)(object)attacker == (Object)null)
{
return;
}
lastHit[victim.playerID] = (attacker, Time.time);
if ((Object)(object)attacker != (Object)(object)victim)
{
PlayerStats playerStats = Get(attacker.playerID);
if (amount > playerStats.BiggestHit)
{
playerStats.BiggestHit = amount;
Broadcast();
}
}
}
public static void OnRevive(Player player)
{
if ((Object)(object)player != (Object)null)
{
lastHit.Remove(player.playerID);
}
}
public static void OnDeath(Player victim)
{
if (!IsHost || (Object)(object)victim == (Object)null)
{
return;
}
Get(victim.playerID).Deaths++;
if (lastHit.TryGetValue(victim.playerID, out (Player, float) value) && (Object)(object)value.Item1 != (Object)null && Time.time - value.Item2 <= 10f)
{
if ((Object)(object)value.Item1 == (Object)(object)victim)
{
Get(victim.playerID).SelfKills++;
}
else
{
Get(value.Item1.playerID).Kills++;
}
}
lastHit.Remove(victim.playerID);
Broadcast();
}
private static void Broadcast()
{
if (!PhotonNetwork.OfflineMode && PhotonNetwork.CurrentRoom != null)
{
int[] array = stats.Keys.ToArray();
NetworkingManager.RPC_Others(typeof(StatsTracker), "RPC_Sync", new object[5]
{
array,
array.Select((int id) => stats[id].Kills).ToArray(),
array.Select((int id) => stats[id].Deaths).ToArray(),
array.Select((int id) => stats[id].SelfKills).ToArray(),
array.Select((int id) => stats[id].BiggestHit).ToArray()
});
}
}
[UnboundRPC]
private static void RPC_Sync(int[] ids, int[] kills, int[] deaths, int[] selfKills, float[] biggestHits)
{
stats.Clear();
for (int i = 0; i < ids.Length; i++)
{
stats[ids[i]] = new PlayerStats
{
Kills = kills[i],
Deaths = deaths[i],
SelfKills = selfKills[i],
BiggestHit = biggestHits[i]
};
}
}
}
}