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.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DG.Tweening;
using DG.Tweening.Core;
using DG.Tweening.Plugins.Options;
using HarmonyLib;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using Zorro.Core;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("\u200b\u200bPeakTeamRace")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("\u200b\u200bPeakTeamRace")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("bffd4bcb-a83c-4d1f-a0f8-44899c7289b0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace _PeakTeamRace;
[BepInPlugin("com.xiaohai.peakteamrace", "\u200b\u200bPeakTeamRace", "1.0.2")]
public class Plugin : BaseUnityPlugin
{
public const string PluginGUID = "com.xiaohai.peakteamrace";
public const string PluginName = "\u200b\u200bPeakTeamRace";
public const string PluginVersion = "1.0.2";
public ConfigEntry<float> rewardMultiplier;
public ConfigEntry<float> penaltyMax;
public ConfigEntry<bool> useTeamColor;
public ConfigEntry<bool> useChain;
public static Plugin Instance { get; private set; }
public static ManualLogSource Log { get; private set; }
public void Awake()
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Expected O, but got Unknown
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin \u200b\u200bPeakTeamRace v 1.0.2is loaded!");
new Harmony("com.xiaohai.peakteamrace").PatchAll();
rewardMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "RewardMultiplier", 1f, "Multiplier for the extra stamina reward after winning(0-1).获胜方获得额外体力奖励的倍率(0 到 1)");
penaltyMax = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "PenaltyFloor", 0.65f, "Maximum penalty for losing (0 - 0.9),失败惩罚异常状态最大值(0 - 0.9)");
useTeamColor = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "useTeamColor/是否使用队伍颜色", false, "true =Sets the team's color for all players. 如果填写true,则将所有玩家的颜色设置成队伍颜色..");
useChain = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "useChain/是否使用链条", true, "true =Players on the same team are connected by chains. 如果填写true,则同队玩家之间会被链条连接.");
GameObject val = new GameObject("TeamChainSystem");
TeamChainSystem teamChainSystem = val.AddComponent<TeamChainSystem>();
Object.DontDestroyOnLoad((Object)(object)val);
}
}
public class TeamRaceManager : Singleton<TeamRaceManager>
{
[CompilerGenerated]
private sealed class <>c__DisplayClass32_0
{
public Random rng;
internal int <RandomlyAssignTeamsCoroutine>b__1(int x)
{
return rng.Next();
}
}
[CompilerGenerated]
private sealed class <RandomlyAssignTeamsCoroutine>d__32 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public TeamRaceManager <>4__this;
private List<Character> <allPlayers>5__1;
private TeamChainSystem <system>5__2;
private object[] <serializedData>5__3;
private List<Character>.Enumerator <>s__4;
private Character <player>5__5;
private <>c__DisplayClass32_0 <>8__6;
private List<int> <indices>5__7;
private int <teamSplitIndex>5__8;
private int <i>5__9;
private int <playerId>5__10;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <RandomlyAssignTeamsCoroutine>d__32(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<allPlayers>5__1 = null;
<system>5__2 = null;
<serializedData>5__3 = null;
<>s__4 = default(List<Character>.Enumerator);
<player>5__5 = null;
<>8__6 = null;
<indices>5__7 = null;
<>1__state = -2;
}
private bool MoveNext()
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
if (!PhotonNetwork.IsMasterClient)
{
return false;
}
<>2__current = <>4__this.WaitForResultProcessing();
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
<>4__this.PlayerTeams.Clear();
<allPlayers>5__1 = Character.AllCharacters.Where((Character p) => (Object)(object)p != (Object)null && (Object)(object)((MonoBehaviourPun)p).photonView != (Object)null).ToList();
if (<allPlayers>5__1.Count < 2)
{
<>s__4 = <allPlayers>5__1.GetEnumerator();
try
{
while (<>s__4.MoveNext())
{
<player>5__5 = <>s__4.Current;
<>4__this.PlayerTeams[((MonoBehaviourPun)<player>5__5).photonView.ViewID] = 0;
<player>5__5 = null;
}
}
finally
{
((IDisposable)<>s__4).Dispose();
}
<>s__4 = default(List<Character>.Enumerator);
}
else
{
<>8__6 = new <>c__DisplayClass32_0();
<indices>5__7 = Enumerable.Range(0, <allPlayers>5__1.Count).ToList();
<>8__6.rng = new Random();
<indices>5__7 = <indices>5__7.OrderBy((int x) => <>8__6.rng.Next()).ToList();
<teamSplitIndex>5__8 = <allPlayers>5__1.Count / 2;
<i>5__9 = 0;
while (<i>5__9 < <indices>5__7.Count)
{
<playerId>5__10 = ((MonoBehaviourPun)<allPlayers>5__1[<indices>5__7[<i>5__9]]).photonView.ViewID;
<>4__this.PlayerTeams[<playerId>5__10] = ((<i>5__9 >= <teamSplitIndex>5__8) ? 1 : 0);
<i>5__9++;
}
<>8__6 = null;
<indices>5__7 = null;
}
<system>5__2 = TeamChainSystem.Instance;
if ((Object)(object)<system>5__2 != (Object)null)
{
<system>5__2.ClearAllChains();
}
if (Plugin.Instance.useChain.Value)
{
<>4__this.CreateTeamChains();
}
<serializedData>5__3 = <>4__this.SerializeTeamsForRPC();
<>4__this._photonView.RPC("RPC_AssignTeams", (RpcTarget)0, <serializedData>5__3);
<>4__this.DebugLogTeamAssignments(<allPlayers>5__1);
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <WaitForResultProcessing>d__33 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public TeamRaceManager <>4__this;
private float <timeout>5__1;
private float <startTime>5__2;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <WaitForResultProcessing>d__33(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<timeout>5__1 = 10f;
<startTime>5__2 = Time.time;
break;
case 1:
<>1__state = -1;
break;
}
if (<>4__this.IsProcessingResults)
{
if (Time.time - <startTime>5__2 > <timeout>5__1)
{
return false;
}
<>2__current = (object)new WaitForSeconds(0.5f);
<>1__state = 1;
return true;
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
public readonly Dictionary<int, float> PlayerFinishTimes = new Dictionary<int, float>();
public readonly Dictionary<int, int> PlayerScores = new Dictionary<int, int>();
public readonly int[] TeamScores = new int[2];
private PhotonView _photonView;
private HashSet<int> _activePlayersAtStart;
public readonly Color[] TeamColors = (Color[])(object)new Color[2]
{
new Color(1f, 0.3f, 0.3f),
new Color(0.3f, 0.3f, 1f)
};
private bool reachedCampfire = false;
public STATUSTYPE shouldStatus;
public float shouldStatusValue = -1f;
public Dictionary<int, int> PlayerTeams { get; private set; } = new Dictionary<int, int>();
public float FirstPlaceTime { get; private set; } = float.MaxValue;
public int LocalPlayerTeamId { get; private set; } = -1;
public bool IsProcessingResults { get; private set; }
private TeamRaceTimer timer => TeamRaceTimer.Instance;
public bool isChinese => (int)LocalizedText.CURRENT_LANGUAGE == 9;
protected override void Awake()
{
base.Awake();
_photonView = ((Component)this).GetComponentInChildren<PhotonView>();
if ((Object)(object)_photonView == (Object)null)
{
_photonView = ((Component)this).gameObject.AddComponent<PhotonView>();
PhotonNetwork.AllocateViewID(_photonView);
}
PlayerTeams = new Dictionary<int, int>();
}
private void Update()
{
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)Character.localCharacter == (Object)null || (Object)(object)((MonoBehaviourPun)Character.localCharacter).photonView == (Object)null)
{
return;
}
if ((Object)(object)Patch.nextCampfire != (Object)null)
{
float num = Vector3.Distance(Character.localCharacter.Center, ((Component)Patch.nextCampfire).transform.position);
if (num < 3f && !reachedCampfire)
{
PlayerReachedCampfire();
}
return;
}
_ = Patch.nextPoint;
if (true)
{
float num2 = Vector3.Distance(Character.localCharacter.Center, Patch.nextPoint);
if (num2 <= 1f && !reachedCampfire)
{
PlayerReachedCampfire();
}
}
}
public void StartTeamAssignment()
{
((MonoBehaviour)this).StartCoroutine(RandomlyAssignTeamsCoroutine());
}
[IteratorStateMachine(typeof(<RandomlyAssignTeamsCoroutine>d__32))]
private IEnumerator RandomlyAssignTeamsCoroutine()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <RandomlyAssignTeamsCoroutine>d__32(0)
{
<>4__this = this
};
}
[IteratorStateMachine(typeof(<WaitForResultProcessing>d__33))]
private IEnumerator WaitForResultProcessing()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <WaitForResultProcessing>d__33(0)
{
<>4__this = this
};
}
private object[] SerializeTeamsForRPC()
{
return new object[3]
{
PlayerTeams.Count,
PlayerTeams.Keys.ToArray(),
PlayerTeams.Values.ToArray()
};
}
[PunRPC]
private void RPC_AssignTeams(object[] data)
{
PlayerTeams.Clear();
PlayerFinishTimes.Clear();
PlayerScores.Clear();
Array.Clear(TeamScores, 0, TeamScores.Length);
FirstPlaceTime = float.MaxValue;
reachedCampfire = false;
_activePlayersAtStart = new HashSet<int>(PlayerTeams.Keys);
int num = (int)data[0];
int[] array = (int[])data[1];
int[] array2 = (int[])data[2];
for (int i = 0; i < num; i++)
{
PlayerTeams[array[i]] = array2[i];
}
UpdateLocalPlayerTeam();
}
public void UpdateLocalPlayerTeam()
{
if (!((Object)(object)Character.localCharacter != (Object)null) || !((Object)(object)((MonoBehaviourPun)Character.localCharacter).photonView != (Object)null))
{
return;
}
int viewID = ((MonoBehaviourPun)Character.localCharacter).photonView.ViewID;
if (PlayerTeams.TryGetValue(viewID, out var value))
{
LocalPlayerTeamId = value;
Plugin.Log.LogInfo((object)$"你的队伍ID是: Team{LocalPlayerTeamId} (红队0/蓝队1)");
string text = (isChinese ? ("你的队伍是: " + ((value == 0) ? "<color=red>红队</color>" : "<color=blue>蓝队</color>")) : ("Your team is: " + ((value == 0) ? "<color=red>Red Team</color>" : "<color=blue>Blue Team</color>")));
TeamRaceTimer.SetMessage("<size=40>" + text + "</size>", 15f);
ResultUI.ShowResultUI("<size=45>" + text + "</size>", 15f);
if (!timer.isRunning)
{
timer.StartTimer();
}
if (Plugin.Instance.useTeamColor.Value)
{
SetTeamColor(value);
}
}
else
{
Plugin.Log.LogWarning((object)"本地玩家未分配到队伍!");
}
}
private void SetTeamColor(int teamID)
{
//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)
Singleton<Customization>.Instance.skins[1].color = TeamColors[teamID];
CharacterCustomization.SetCharacterSkinColor(1);
}
public int GetPlayerTeam(int playerViewId)
{
int value;
return PlayerTeams.TryGetValue(playerViewId, out value) ? value : (-1);
}
public List<int> GetTeammates(int playerViewId)
{
if (!PlayerTeams.TryGetValue(playerViewId, out var myTeamId))
{
return new List<int>();
}
return (from pair in PlayerTeams
where pair.Value == myTeamId
select pair.Key).ToList();
}
private void PlayerReachedCampfire()
{
reachedCampfire = true;
float num = timer.StopTimer();
_photonView.RPC("RPC_SyncPlayerReachedCampfire", (RpcTarget)2, new object[2]
{
((MonoBehaviourPun)Character.localCharacter).photonView.ViewID,
num
});
string msg = (isChinese ? ("<size=30><color=green>你到达了篝火! 完成时间: " + timer.FormatTime(num) + "</size></color>") : ("<size=30><color=green>You reached the campfire! Finish time: " + timer.FormatTime(num) + "</size></color>"));
TeamRaceTimer.SetMessage(msg, 5f);
}
[PunRPC]
private void RPC_SyncPlayerReachedCampfire(int playerViewId, float finishTime)
{
if (PhotonNetwork.IsMasterClient)
{
IsProcessingResults = true;
HandleResult(GetCharacterByViewId(playerViewId), finishTime);
}
}
[PunRPC]
private void RPC_SyncResult(object[] data)
{
//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
//IL_0336: Unknown result type (might be due to invalid IL or missing references)
//IL_031c: Unknown result type (might be due to invalid IL or missing references)
IsProcessingResults = true;
FirstPlaceTime = (float)data[0];
TeamScores[0] = (int)data[1];
TeamScores[1] = (int)data[2];
int num = (int)data[3];
int[] array = (int[])data[4];
float[] array2 = (float[])data[5];
PlayerFinishTimes.Clear();
for (int i = 0; i < num; i++)
{
PlayerFinishTimes[array[i]] = array2[i];
}
int num2 = (int)data[6];
int[] array3 = (int[])data[7];
int[] array4 = (int[])data[8];
PlayerScores.Clear();
for (int j = 0; j < num2; j++)
{
PlayerScores[array3[j]] = array4[j];
}
bool flag = false;
string text = "";
if ((TeamScores[0] > TeamScores[1] && LocalPlayerTeamId == 0) || (TeamScores[0] < TeamScores[1] && LocalPlayerTeamId == 1))
{
flag = true;
}
else if (TeamScores[0] == TeamScores[1])
{
flag = true;
}
int value;
int num3 = (PlayerScores.TryGetValue(((MonoBehaviourPun)Character.localCharacter).photonView.ViewID, out value) ? value : 0);
if (flag)
{
float num4 = num3 / 100;
if (Character.localCharacter.data.dead)
{
shouldStatusValue = num4;
shouldStatus = (STATUSTYPE)7;
}
else
{
Character.localCharacter.AddExtraStamina(num4 * Plugin.Instance.rewardMultiplier.Value);
}
text = (isChinese ? $"<size=35><color=green>你赢了! 获得额外耐力: {num4 * 100f:F2}%</color></size>" : $"<size=35><color=green>You win! Add extra stamina: {num4 * 100f:F2}%</color></size>");
}
else
{
List<STATUSTYPE> list = new List<STATUSTYPE>
{
(STATUSTYPE)8,
(STATUSTYPE)2,
(STATUSTYPE)6,
(STATUSTYPE)3
};
int index = Random.Range(0, list.Count);
float num5 = 1f - (float)(num3 / 100);
num5 = Mathf.Clamp(num5, 0f, Plugin.Instance.penaltyMax.Value);
if (Character.localCharacter.refs.afflictions.statusSum + num5 >= 1f)
{
num5 = 0.9f - Character.localCharacter.refs.afflictions.statusSum;
}
if (Character.localCharacter.data.dead)
{
shouldStatus = list[index];
shouldStatusValue = num5;
}
else
{
Character.localCharacter.refs.afflictions.AddStatus(list[index], num5, false);
}
text = (isChinese ? $"<size=35><color=red>你输了! 获得负面状态: {list[index]}</color></size>" : $"<size=35><color=red>You lose! Add Affliction: {list[index]}</color></size>");
}
Plugin.Log.LogInfo((object)$"已同步比赛结果: 第一名时间={FirstPlaceTime:F2}s, 红队={TeamScores[0]}, 蓝队={TeamScores[1]}");
string result = GenerateResultText(text);
ResultUI.ShowResultUI(result, 15f, useEffects: false);
IsProcessingResults = false;
}
public void HandleResult(Character player, float finishTime)
{
if (PhotonNetwork.IsMasterClient && !((Object)(object)player == (Object)null))
{
int viewID = ((MonoBehaviourPun)player).photonView.ViewID;
PlayerFinishTimes[viewID] = finishTime;
if (finishTime < FirstPlaceTime)
{
FirstPlaceTime = finishTime;
}
int num = CalculatePlayerScore(viewID, finishTime);
PlayerScores[viewID] = num;
if (PlayerTeams.TryGetValue(viewID, out var value))
{
TeamScores[value] += num;
}
Plugin.Log.LogInfo((object)$"玩家{player.characterName}完成! 时间: {timer.FormatTime(finishTime)}, 积分: {num}");
if (CheckAllPlayersFinished())
{
object[] array = SerializeResultsForRPC();
_photonView.RPC("RPC_SyncResult", (RpcTarget)0, array);
}
}
}
private bool CheckAllPlayersFinished()
{
HashSet<int> second = PhotonNetwork.CurrentRoom.Players.Values.Select((Player p) => p.ActorNumber).ToHashSet();
IEnumerable<int> source = _activePlayersAtStart.Intersect(second);
return source.All((int playerId) => PlayerFinishTimes.ContainsKey(playerId));
}
private int CalculatePlayerScore(int playerViewId, float finishTime)
{
List<float> list = PlayerFinishTimes.Values.ToList();
if (list.Count == 1)
{
return 100;
}
int num = 1;
foreach (float item in list)
{
if (item < finishTime)
{
num++;
}
}
int count = list.Count;
int num2 = 0;
int num3 = 100;
int num4 = num3 - (num - 1) * (num3 - num2) / (count - 1);
return Mathf.Clamp(num4, num2, num3);
}
private object[] SerializeResultsForRPC()
{
int[] array = PlayerFinishTimes.Keys.ToArray();
float[] array2 = PlayerFinishTimes.Values.ToArray();
int[] array3 = PlayerScores.Keys.ToArray();
int[] array4 = PlayerScores.Values.ToArray();
return new object[9]
{
FirstPlaceTime,
TeamScores[0],
TeamScores[1],
array.Length,
array,
array2,
array3.Length,
array3,
array4
};
}
private Character GetCharacterByViewId(int viewId)
{
foreach (Character allCharacter in Character.AllCharacters)
{
if ((Object)(object)allCharacter != (Object)null && (Object)(object)((MonoBehaviourPun)allCharacter).photonView != (Object)null && ((MonoBehaviourPun)allCharacter).photonView.ViewID == viewId)
{
return allCharacter;
}
}
return null;
}
private string GenerateResultText(string extraText)
{
StringBuilder stringBuilder = new StringBuilder();
string text = ((TeamScores[1] > TeamScores[0]) ? "<size=30>win</size>" : "");
string text2 = ((TeamScores[1] < TeamScores[0]) ? "<size=30>win</size>" : "");
string value = ((!isChinese) ? $"<size=60><color=blue>Team Blue</color>: {TeamScores[1]}</size>{text} <size=60><color=red>Team Red</color>: {TeamScores[0]}</size>{text2}" : $"<size=60><color=blue>蓝队</color>: {TeamScores[1]}分</size>{text} <size=60><color=red>红队</color>: {TeamScores[0]}分</size>{text2}");
stringBuilder.AppendLine(value);
stringBuilder.AppendLine();
stringBuilder.AppendLine("<size=40>Player Time Score</size>");
stringBuilder.AppendLine();
int value3;
var list = (from p in PlayerFinishTimes
orderby p.Value
select new
{
ViewID = p.Key,
Time = p.Value,
Score = (PlayerScores.TryGetValue(p.Key, out value3) ? value3 : 0)
}).ToList();
for (int i = 0; i < list.Count; i++)
{
var anon = list[i];
Character characterByViewId = GetCharacterByViewId(anon.ViewID);
string text3 = (((Object)(object)characterByViewId != (Object)null) ? characterByViewId.characterName : "Unknown");
int value2;
string text4 = ((!PlayerTeams.TryGetValue(anon.ViewID, out value2)) ? "white" : ((value2 == 0) ? "red" : "blue"));
string text5 = TeamRaceTimer.Instance.FormatTime(anon.Time);
stringBuilder.Append($"<size=32>{i + 1}.");
stringBuilder.Append("<color=" + text4 + ">" + text3 + "</color></size>");
int num = 15 - text3.Length;
if (num > 0)
{
stringBuilder.Append(new string(' ', num));
}
int num2 = 15 - text5.Length;
if (num2 > 0)
{
stringBuilder.Append(new string(' ', num2));
}
stringBuilder.Append(text5);
int num3 = 17 - anon.Score.ToString().Length;
if (num3 > 0)
{
stringBuilder.Append(new string(' ', num3));
}
stringBuilder.Append($"<size=32>{anon.Score}</size>");
stringBuilder.AppendLine();
}
stringBuilder.AppendLine(extraText);
return stringBuilder.ToString();
}
private void CreateTeamChains()
{
if ((Object)(object)TeamChainSystem.Instance == (Object)null)
{
return;
}
TeamChainSystem instance = TeamChainSystem.Instance;
Dictionary<int, List<Character>> dictionary = new Dictionary<int, List<Character>>();
foreach (Character allCharacter in Character.AllCharacters)
{
if ((Object)(object)((MonoBehaviourPun)allCharacter).photonView == (Object)null)
{
continue;
}
int viewID = ((MonoBehaviourPun)allCharacter).photonView.ViewID;
if (PlayerTeams.TryGetValue(viewID, out var value))
{
if (!dictionary.ContainsKey(value))
{
dictionary[value] = new List<Character>();
}
dictionary[value].Add(allCharacter);
}
}
foreach (KeyValuePair<int, List<Character>> item in dictionary)
{
instance.CreateChainsForTeam(item.Key, item.Value);
}
}
private void DebugLogTeamAssignments(List<Character> players)
{
string text = "红队(0): ";
string text2 = "蓝队(1): ";
foreach (Character player in players)
{
if ((Object)(object)((MonoBehaviourPun)player).photonView == (Object)null)
{
continue;
}
int viewID = ((MonoBehaviourPun)player).photonView.ViewID;
if (PlayerTeams.TryGetValue(viewID, out var value))
{
string text3 = player.characterName;
if (string.IsNullOrEmpty(text3))
{
text3 = "未命名玩家";
}
if (value == 0)
{
text += $"{text3}({viewID}), ";
}
else
{
text2 += $"{text3}({viewID}), ";
}
}
}
Plugin.Log.LogInfo((object)text.TrimEnd(',', ' '));
Plugin.Log.LogInfo((object)text2.TrimEnd(',', ' '));
Plugin.Log.LogInfo((object)$"队伍分配完成! 总计: {players.Count}名玩家");
}
}
public class TeamRaceTimer : MonoBehaviour
{
private float messageTimer;
private TMP_Text timerText;
private float startTime;
private float pausedTime;
public bool isRunning;
private bool isPaused;
public string message = "";
public float CurrentTime => isRunning ? (Time.time - startTime) : pausedTime;
public static TeamRaceTimer Instance { get; private set; }
private void Start()
{
timerText = ((Component)this).GetComponentInChildren<TMP_Text>();
if ((Object)(object)timerText == (Object)null)
{
Debug.LogError((object)"无法找到计时器文本组件!");
((Behaviour)this).enabled = false;
return;
}
timerText.text = "00:00.00";
timerText.alignment = (TextAlignmentOptions)514;
timerText.richText = true;
SetVisible(visible: false);
Instance = this;
}
public void StartTimer()
{
SetVisible(visible: true);
if (isPaused)
{
startTime = Time.time - pausedTime;
isPaused = false;
}
else
{
startTime = Time.time;
pausedTime = 0f;
}
isRunning = true;
}
public void PauseTimer()
{
if (isRunning)
{
pausedTime = CurrentTime;
isRunning = false;
isPaused = true;
}
}
public float StopTimer()
{
float currentTime = CurrentTime;
isRunning = false;
isPaused = false;
return currentTime;
}
public void ResetTimer()
{
startTime = Time.time;
pausedTime = 0f;
isRunning = false;
isPaused = false;
timerText.text = message + "\n\n " + FormatTime(0f);
}
public string FormatTime(float time)
{
int num = Mathf.FloorToInt(time / 60f);
int num2 = Mathf.FloorToInt(time % 60f);
int num3 = Mathf.FloorToInt(time * 100f % 100f);
string text = ((Singleton<TeamRaceManager>.Instance.LocalPlayerTeamId == 0) ? "red" : "blue");
return $"<size=32><color={text}>{num:00}:{num2:00}.{num3:00}</size></color>";
}
public void SetVisible(bool visible)
{
CanvasGroup component = ((Component)this).GetComponent<CanvasGroup>();
if ((Object)(object)component != (Object)null)
{
component.alpha = (visible ? 1f : 0f);
}
else
{
((Component)this).gameObject.SetActive(visible);
}
}
private void Update()
{
messageTimer -= Time.deltaTime;
if (messageTimer <= 0f)
{
message = "";
}
timerText.text = message + "\n\n" + FormatTime(CurrentTime);
}
public static void SetMessage(string msg, float time)
{
if ((Object)(object)Instance != (Object)null)
{
Instance.message = msg;
Instance.messageTimer = time;
}
}
}
public class ResultUI : MonoBehaviour
{
private static ResultUI _instance;
private TMP_Text _resultText;
private CanvasGroup _canvasGroup;
private float _showTime = 5f;
private float _timer;
private bool _isShowing;
public static ResultUI Instance => _instance;
private void Awake()
{
if ((Object)(object)_instance != (Object)null && (Object)(object)_instance != (Object)(object)this)
{
Object.Destroy((Object)(object)((Component)this).gameObject);
return;
}
_instance = this;
_resultText = ((Component)this).GetComponentInChildren<TMP_Text>();
_resultText.richText = true;
_resultText.text = "";
_canvasGroup = ((Component)this).gameObject.GetComponentInChildren<CanvasGroup>();
if ((Object)(object)_canvasGroup == (Object)null)
{
_canvasGroup = ((Component)this).gameObject.AddComponent<CanvasGroup>();
}
_canvasGroup.alpha = 0f;
_canvasGroup.blocksRaycasts = false;
_canvasGroup.interactable = false;
}
public static void ShowResultUI(string result, float time, bool useEffects = true)
{
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)Instance == (Object)null))
{
Instance._resultText.text = result;
Instance._showTime = time;
Instance._isShowing = true;
Instance._resultText.transform.localScale = Vector3.one;
Instance._canvasGroup.alpha = 0f;
if (useEffects)
{
Instance.PlayAnimatedSequence(time);
return;
}
Instance._canvasGroup.alpha = 1f;
Instance._timer = time;
((Behaviour)Instance).enabled = true;
}
}
private void PlayAnimatedSequence(float displayTime)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Expected O, but got Unknown
DOTween.Kill((object)_resultText.transform, false);
DOTween.Kill((object)_canvasGroup, false);
Sequence val = DOTween.Sequence();
_resultText.transform.localScale = Vector3.zero;
_canvasGroup.alpha = 0f;
TweenSettingsExtensions.Append(val, (Tween)(object)TweenSettingsExtensions.SetEase<TweenerCore<Vector3, Vector3, VectorOptions>>(ShortcutExtensions.DOScale(_resultText.transform, 1.2f, 0.5f), (Ease)27));
TweenSettingsExtensions.Append(val, (Tween)(object)TweenSettingsExtensions.SetEase<TweenerCore<Vector3, Vector3, VectorOptions>>(ShortcutExtensions.DOScale(_resultText.transform, 1f, 0.3f), (Ease)3));
TweenSettingsExtensions.Join(val, (Tween)(object)DOTween.To((DOGetter<float>)(() => _canvasGroup.alpha), (DOSetter<float>)delegate(float x)
{
_canvasGroup.alpha = x;
}, 1f, 0.5f));
TweenSettingsExtensions.AppendInterval(val, displayTime - 1f);
TweenSettingsExtensions.Append(val, (Tween)(object)TweenSettingsExtensions.OnComplete<TweenerCore<float, float, FloatOptions>>(DOTween.To((DOGetter<float>)(() => _canvasGroup.alpha), (DOSetter<float>)delegate(float x)
{
_canvasGroup.alpha = x;
}, 0f, 1f), (TweenCallback)delegate
{
_resultText.text = "";
_isShowing = false;
((Behaviour)this).enabled = false;
}));
TweenExtensions.Play<Sequence>(val);
}
private void Update()
{
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Expected O, but got Unknown
if (!_isShowing)
{
return;
}
_timer -= Time.deltaTime;
if (_timer <= 0f)
{
TweenSettingsExtensions.OnComplete<TweenerCore<float, float, FloatOptions>>(DOTween.To((DOGetter<float>)(() => _canvasGroup.alpha), (DOSetter<float>)delegate(float x)
{
_canvasGroup.alpha = x;
}, 0f, 0.5f), (TweenCallback)delegate
{
_resultText.text = "";
_isShowing = false;
});
}
}
}
[HarmonyPatch]
public static class Patch
{
[HarmonyPatch(typeof(GUIManager), "Start")]
private static class PatchGUIManager
{
public static void Postfix(GUIManager __instance)
{
InitTimerUI(__instance);
InitResultUI(__instance);
}
private static void InitTimerUI(GUIManager __instance)
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
AscentUI componentInChildren = ((Component)__instance).GetComponentInChildren<AscentUI>();
Transform val = ((componentInChildren != null) ? ((Component)componentInChildren).transform : null);
if (!((Object)(object)val == (Object)null))
{
RectTransform val2 = (RectTransform)Object.Instantiate<Transform>(val, val.parent);
((Object)val2).name = "TeamRaceTimer";
Object.Destroy((Object)(object)((Component)val2).GetComponent<AscentUI>());
((Component)val2).gameObject.AddComponent<TeamRaceTimer>();
val2.anchorMin = new Vector2(1f, 0.5f);
val2.anchorMax = new Vector2(1f, 0.5f);
val2.pivot = new Vector2(1f, 0.5f);
val2.anchoredPosition = new Vector2(-50f, 0f);
val2.sizeDelta = new Vector2(200f, 50f);
}
}
private static void InitResultUI(GUIManager __instance)
{
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
AscentUI componentInChildren = ((Component)__instance).GetComponentInChildren<AscentUI>();
Transform val = ((componentInChildren != null) ? ((Component)componentInChildren).transform : null);
if (!((Object)(object)val == (Object)null))
{
Transform val2 = Object.Instantiate<Transform>(val, val.parent);
((Object)val2).name = "ResultUI";
Object.Destroy((Object)(object)((Component)val2).GetComponent<AscentUI>());
((Component)val2).gameObject.AddComponent<ResultUI>();
RectTransform component = ((Component)val2).GetComponent<RectTransform>();
component.anchorMin = new Vector2(0.5f, 0.5f);
component.anchorMax = new Vector2(0.5f, 0.5f);
component.pivot = new Vector2(0.5f, 0.5f);
component.anchoredPosition = Vector2.zero;
component.sizeDelta = new Vector2(800f, 600f);
TMP_Text componentInChildren2 = ((Component)val2).GetComponentInChildren<TMP_Text>();
if ((Object)(object)componentInChildren2 != (Object)null)
{
componentInChildren2.alignment = (TextAlignmentOptions)257;
componentInChildren2.fontSize = 24f;
((Graphic)componentInChildren2).color = Color.white;
}
}
}
}
[HarmonyPatch(typeof(MapHandler))]
private static class PatchMapHandler
{
[HarmonyPatch("GoToSegment")]
public static void Postfix(MapHandler __instance, ref Segment s)
{
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: 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_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: 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)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)__instance.segments[(int)s]._segmentCampfire == (Object)null)
{
nextCampfire = null;
Plugin.Log.LogInfo((object)"无篝火位置,直奔顶点吧!");
GameObject val = GameObject.Find("Flag_planted_seagull");
if ((Object)(object)val != (Object)null)
{
nextPoint = val.transform.position;
Plugin.Log.LogInfo((object)$"已设置下一个点为: {nextPoint}");
}
else
{
nextPoint = (nextPoint = Singleton<MountainProgressHandler>.Instance.progressPoints.Last().transform.position);
}
}
else
{
nextCampfire = __instance.segments[(int)s]._segmentCampfire.gameObject.GetComponentInChildren<Campfire>(true);
if (!((Object)(object)nextCampfire != (Object)null))
{
return;
}
float num = Vector3.Distance(((Component)nextCampfire).transform.position, ((Component)Character.localCharacter).transform.position);
Plugin.Log.LogInfo((object)$"下一个篝火位置: {nextCampfire},距离玩家{num:F2}M");
}
Singleton<TeamRaceManager>.Instance.StartTeamAssignment();
}
}
[HarmonyPatch(typeof(RunManager))]
private static class PatchRunManager
{
[HarmonyPatch("Awake")]
public static void Postfix(RunManager __instance)
{
if ((Object)(object)((Component)__instance).gameObject.GetComponent<TeamRaceManager>() == (Object)null)
{
((Component)__instance).gameObject.AddComponent<TeamRaceManager>();
Plugin.Log.LogInfo((object)"已添加TeamRaceManager组件到RunManager对象上");
}
}
}
[HarmonyPatch(typeof(MountainProgressHandler))]
private static class PatchMountainProgressHandler
{
[HarmonyPatch("CheckAreaAchievement")]
public static void Prefix(MountainProgressHandler __instance, ref ProgressPoint pointReached)
{
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Invalid comparison between Unknown and I4
//IL_0093: 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)
if (pointReached.title.ToLower() != "shore")
{
return;
}
List<Campfire> list = Object.FindObjectsByType<Campfire>((FindObjectsSortMode)0).ToList();
Plugin.Log.LogInfo((object)$"已经到达海岸!,共找到{list.Count}个篝火!");
foreach (Campfire item in list)
{
if ((Object)(object)nextCampfire == (Object)null && (int)item.state != 1 && (Object)(object)Character.localCharacter != (Object)null)
{
float num = Vector3.Distance(((Component)item).transform.position, Character.localCharacter.Center);
if (num > 50f)
{
nextCampfire = item;
Plugin.Log.LogInfo((object)("已设置nextCampfire为当前Campfire: " + ((Object)item).name));
Singleton<TeamRaceManager>.Instance.StartTeamAssignment();
break;
}
}
}
}
}
[HarmonyPatch(typeof(Character))]
private static class PatchCharacter
{
[HarmonyPatch("RPCA_Revive")]
[HarmonyPostfix]
private static void RevivePatch(Character __instance)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Invalid comparison between Unknown and I4
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)__instance == (Object)(object)Character.localCharacter && Singleton<TeamRaceManager>.Instance.shouldStatusValue != -1f)
{
if ((int)Singleton<TeamRaceManager>.Instance.shouldStatus != 7)
{
__instance.refs.afflictions.AddStatus(Singleton<TeamRaceManager>.Instance.shouldStatus, Singleton<TeamRaceManager>.Instance.shouldStatusValue, false);
Singleton<TeamRaceManager>.Instance.shouldStatusValue = -1f;
}
else
{
__instance.AddExtraStamina(Singleton<TeamRaceManager>.Instance.shouldStatusValue);
Singleton<TeamRaceManager>.Instance.shouldStatusValue = -1f;
}
}
}
}
public static Campfire nextCampfire;
public static Vector3 nextPoint;
}
public class TeamChainSystem : MonoBehaviour
{
public class ChainLink
{
public Character playerA;
public Character playerB;
public LineRenderer lineRenderer;
public SpringJoint springJoint;
private int teamId;
public ChainLink(Character a, Character b, int team)
{
playerA = a;
playerB = b;
teamId = team;
CreateVisualChain();
CreatePhysicsConnection();
}
private void CreateVisualChain()
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Expected O, but got Unknown
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Expected O, but got Unknown
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject($"Team{teamId}_Chain_{((MonoBehaviourPun)playerA).photonView.ViewID}-{((MonoBehaviourPun)playerB).photonView.ViewID}");
lineRenderer = val.AddComponent<LineRenderer>();
lineRenderer.positionCount = 2;
((Renderer)lineRenderer).material = new Material(Shader.Find("Sprites/Default"));
lineRenderer.startColor = Instance.ChainColor;
lineRenderer.endColor = Instance.ChainColor;
lineRenderer.startWidth = Instance.ChainWidth;
lineRenderer.endWidth = Instance.ChainWidth;
}
private void CreatePhysicsConnection()
{
Rigidbody hipRigidbody = GetHipRigidbody(playerA);
Rigidbody hipRigidbody2 = GetHipRigidbody(playerB);
if ((Object)(object)hipRigidbody != (Object)null && (Object)(object)hipRigidbody2 != (Object)null)
{
springJoint = ((Component)hipRigidbody).gameObject.AddComponent<SpringJoint>();
((Joint)springJoint).connectedBody = hipRigidbody2;
springJoint.spring = 15f;
springJoint.damper = 0.5f;
springJoint.minDistance = 2f;
springJoint.maxDistance = Instance.ChainLength;
((Joint)springJoint).enableCollision = true;
}
}
private Rigidbody GetHipRigidbody(Character character)
{
Transform val = ((Component)character).transform.FindRecursive("Hip");
return (val != null) ? ((Component)val).GetComponent<Rigidbody>() : null;
}
public void Update()
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: 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)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)playerA == (Object)null || (Object)(object)playerB == (Object)null)
{
Destroy();
return;
}
Vector3 hipPosition = GetHipPosition(playerA);
Vector3 hipPosition2 = GetHipPosition(playerB);
lineRenderer.SetPosition(0, hipPosition);
lineRenderer.SetPosition(1, hipPosition2);
float num = Vector3.Distance(hipPosition, hipPosition2);
if (num > Instance.ChainLength && (Object)(object)springJoint != (Object)null)
{
Rigidbody hipRigidbody = GetHipRigidbody(playerA);
if ((Object)(object)hipRigidbody != (Object)null)
{
Vector3 val = hipPosition2 - hipPosition;
Vector3 normalized = ((Vector3)(ref val)).normalized;
float num2 = (num - Instance.ChainLength) * 10f;
hipRigidbody.AddForce(normalized * num2, (ForceMode)2);
}
}
}
private Vector3 GetHipPosition(Character character)
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
Transform val = ((Component)character).transform.FindRecursive("Hip");
return (val != null) ? val.position : (((Component)character).transform.position + Vector3.up * 0.5f);
}
public void Destroy()
{
if ((Object)(object)lineRenderer != (Object)null)
{
Object.Destroy((Object)(object)((Component)lineRenderer).gameObject);
}
if ((Object)(object)springJoint != (Object)null)
{
Object.Destroy((Object)(object)springJoint);
}
}
}
public float ChainLength = 5f;
public Color ChainColor = new Color(0.36f, 0.22f, 0.09f);
public float ChainWidth = 0.1f;
private Dictionary<int, List<ChainLink>> teamChains = new Dictionary<int, List<ChainLink>>();
public static TeamChainSystem Instance { get; private set; }
private void Awake()
{
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
}
else
{
Object.Destroy((Object)(object)((Component)this).gameObject);
}
}
public void CreateChainsForTeam(int teamId, List<Character> members)
{
RemoveTeamChains(teamId);
members.Sort((Character a, Character b) => ((MonoBehaviourPun)a).photonView.ViewID.CompareTo(((MonoBehaviourPun)b).photonView.ViewID));
List<ChainLink> list = new List<ChainLink>();
for (int i = 0; i < members.Count - 1; i++)
{
ChainLink item = new ChainLink(members[i], members[i + 1], teamId);
list.Add(item);
}
if (members.Count > 2)
{
list.Add(new ChainLink(members[0], members[members.Count - 1], teamId));
}
teamChains[teamId] = list;
}
public void RemoveTeamChains(int teamId)
{
if (!teamChains.TryGetValue(teamId, out var value))
{
return;
}
foreach (ChainLink item in value)
{
item.Destroy();
}
teamChains.Remove(teamId);
}
private void LateUpdate()
{
foreach (KeyValuePair<int, List<ChainLink>> teamChain in teamChains)
{
foreach (ChainLink item in teamChain.Value)
{
item.Update();
}
}
}
public void ClearAllChains()
{
List<int> list = teamChains.Keys.ToList();
foreach (int item in list)
{
RemoveTeamChains(item);
}
teamChains.Clear();
}
}
public static class TransformExtensions
{
public static Transform FindRecursive(this Transform parent, string name)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected O, but got Unknown
if (((Object)parent).name == name)
{
return parent;
}
foreach (Transform item in parent)
{
Transform parent2 = item;
Transform val = parent2.FindRecursive(name);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
return null;
}
}