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.Text.RegularExpressions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Mirror;
using MoveClasses;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("TeamBattle")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TeamBattle")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("30871c5a-f70c-4492-ba06-01b2a3b215d2")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace GladioMoriKassenTeamBattle;
public enum Language
{
English,
Japanese
}
[BepInPlugin("jp.jyoki_tsubame.gladiomori.kassen", "-KASSEN- Team Battle", "1.0.4")]
public class GladioMoriKassenTeamBattlePlugin : BaseUnityPlugin
{
public enum GameResultType
{
Win,
Draw
}
public struct GameDecision
{
public GameResultType Result;
public string WinningTeam;
}
public static class GameDecisionEvaluator
{
public static GameDecision EvaluateStandardGameResult(Dictionary<string, List<PlayerGameStateInfo>> teams, List<PlayerGameStateInfo> alivePlayers)
{
GameDecision result = default(GameDecision);
if (alivePlayers.Count > 0 && teams.Count == 1)
{
result.Result = GameResultType.Win;
string text = teams.First().Key;
if (string.IsNullOrEmpty(text))
{
text = TeamHelper.ExtractTeamColor(teams.First().Value.First().player.playerName);
}
result.WinningTeam = text;
LogInstance.LogInfo((object)("EvaluateStandardGameResult: Winning Team = " + text));
}
else
{
result.Result = GameResultType.Draw;
result.WinningTeam = "";
LogInstance.LogInfo((object)"EvaluateStandardGameResult: Draw");
}
return result;
}
public static GameDecision EvaluateCaptainGameResult(Dictionary<string, List<PlayerGameStateInfo>> teams, List<PlayerGameStateInfo> alivePlayers)
{
GameDecision result = default(GameDecision);
Dictionary<string, bool> dictionary = new Dictionary<string, bool>();
foreach (KeyValuePair<string, List<PlayerGameStateInfo>> team in teams)
{
string key = team.Key;
bool flag2 = (dictionary[key] = team.Value.Any(delegate(PlayerGameStateInfo p)
{
string playerName = p.player.playerName;
return (string.IsNullOrEmpty(playerName) ? "" : Regex.Replace(playerName, "<[^>]+>", "")).StartsWith("[CAP]");
}));
LogInstance.LogInfo((object)$"EvaluateCaptainGameResult: Team '{key}' hasCaptain = {flag2}");
}
List<string> list = (from kvp in dictionary
where kvp.Value
select kvp.Key).ToList();
if (list.Count == 1)
{
result.Result = GameResultType.Win;
result.WinningTeam = list[0];
LogInstance.LogInfo((object)("EvaluateCaptainGameResult: Winning Team = " + list[0]));
}
else
{
result.Result = GameResultType.Draw;
result.WinningTeam = "";
LogInstance.LogInfo((object)"EvaluateCaptainGameResult: Draw (multiple or no teams with captain alive)");
}
return result;
}
}
public static bool modEnabled = false;
public static bool gameOverModEnabled = false;
public static bool spawnPositioningEnabled = false;
public static bool logEnabled = false;
public static bool captainModeEnabled = false;
public static bool autoTeamAssignmentEnabled = true;
public static Dictionary<int, int> playerColorSelections = new Dictionary<int, int>();
public static Dictionary<int, bool> playerDropdownOpen = new Dictionary<int, bool>();
public static Dictionary<int, bool> captainFlags = new Dictionary<int, bool>();
private List<MultiplayerRoomPlayer> previousPlayers = new List<MultiplayerRoomPlayer>();
public static Dictionary<int, string> originalPlayerNames = new Dictionary<int, string>();
public static int CurrentTeamCount = 0;
public static string[] CurrentAutoTeamColors = null;
private bool uiOpen;
private Rect windowRect = new Rect(100f, 100f, 500f, 1200f);
private KeyCode toggleKey = (KeyCode)288;
private string teamCountInput = "2";
private string autoTeamColorsInput = "red, blue, orange, yellow, cyan, purple, brown";
public static Dictionary<int, HashSet<Vector3>> usedStaticSpawnPositions = new Dictionary<int, HashSet<Vector3>>();
public static Language currentLanguage = Language.English;
private static readonly Dictionary<string, string> englishText = new Dictionary<string, string>
{
{ "ModEnabled", "Team color function Enabled" },
{ "TeamGameOverEnabled", "Team GameOver Enabled" },
{ "SpawnPositioningEnabled", "Spawn Positioning Enabled" },
{ "ChatBroadcastTeamAssignment", "Team Assignment Announcement" },
{ "PromptTeamCheck", "Prompt Team Check Announcement" },
{ "RestartAnnoucement", "Restart Announcement" },
{ "TeamChangeAnnouncement", "Team Changing Announcement" },
{ "RuleAnnouncement", "Rule Announcement" },
{ "RuleAnnouncementForJP", "Rule Announcement for JP User" },
{ "NameSelection", "Select Color for each player's name:" },
{ "UpdateAllPlayers", "Update All Players" },
{ "AutoTeamAssignmentSettings", "Auto Team Assignment Settings" },
{ "TeamCount", "Team Count:" },
{ "AutoTeamColors", "Auto Team Colors (comma separated):" },
{ "AutoAssignTeams", "Auto Assign Teams" },
{ "Language", "Language:" },
{ "LogEanbled", "Log Enabled:" },
{ "CaptainModeEnabled", "Captain Mode Enabled" },
{ "NewPlayerAutoAssignment", "Auto team assignment on new player entry enabled" },
{ "Captain", "Captain" },
{ "SelectCaptain", "Selection of a captain" }
};
private static readonly Dictionary<string, string> japaneseText = new Dictionary<string, string>
{
{ "ModEnabled", "チームカラー機能有効" },
{ "TeamGameOverEnabled", "チーム勝敗機能有効" },
{ "SpawnPositioningEnabled", "スポーン位置調整機能有効" },
{ "ChatBroadcastTeamAssignment", "チーム割り振り発表アナウンス" },
{ "PromptTeamCheck", "チーム確認を促すアナウンス" },
{ "RestartAnnoucement", "ゲーム再開アナウンス" },
{ "TeamChangeAnnouncement", "チーム変更中アナウンス" },
{ "RuleAnnouncement", "ルール説明アナウンス" },
{ "RuleAnnouncementForJP", "ルール説明アナウンス(ローマ字)" },
{ "NameSelection", "各プレイヤーの名前に付与する色:" },
{ "UpdateAllPlayers", "全プレイヤー更新" },
{ "AutoTeamAssignmentSettings", "自動チーム分け設定" },
{ "TeamCount", "チーム数:" },
{ "AutoTeamColors", "自動割り当て色(カンマ区切り):" },
{ "AutoAssignTeams", "自動チーム分け" },
{ "Language", "言語:" },
{ "LogEanbled", "ログ有効:" },
{ "CaptainModeEnabled", "大将戦有効" },
{ "NewPlayerAutoAssignment", "新規入室時の自動チーム割り当て有効" },
{ "Captain", "大将" },
{ "SelectCaptain", "大将をランダムに選出" }
};
public static GladioMoriKassenTeamBattlePlugin Instance { get; private set; }
public static ManualLogSource LogInstance { get; private set; }
public static string[] colorOptions
{
get
{
if ((Object)(object)Instance == (Object)null)
{
return new string[23]
{
"nothing", "aqua", "black", "blue", "brown", "cyan", "darkblue", "fuchsia", "green", "grey",
"lightblue", "lime", "magenta", "maroon", "navy", "olive", "orange", "purple", "red", "silver",
"teal", "white", "yellow"
};
}
List<string> list = (from s in Instance.autoTeamColorsInput.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
select s.Trim().ToLower()).ToList();
list.Insert(0, "nothing");
return list.ToArray();
}
}
public static string Localize(string key)
{
if (currentLanguage == Language.Japanese)
{
if (!japaneseText.ContainsKey(key))
{
return key;
}
return japaneseText[key];
}
if (!englishText.ContainsKey(key))
{
return key;
}
return englishText[key];
}
private void Awake()
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
LogInstance = ((BaseUnityPlugin)this).Logger;
new Harmony("jp.jyoki_tsubame.gladiomori.kassen").PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"GladioMoriKassenTeamBattle: Loaded");
}
private IEnumerator OnPlayerListChangedCoroutine(List<MultiplayerRoomPlayer> currentPlayers)
{
yield return (object)new WaitForSeconds(1f);
if (!autoTeamAssignmentEnabled)
{
yield break;
}
Dictionary<int, int> dictionary = new Dictionary<int, int>();
foreach (MultiplayerRoomPlayer currentPlayer in currentPlayers)
{
int key = ((((NetworkBehaviour)currentPlayer).connectionToClient != null) ? ((NetworkConnection)((NetworkBehaviour)currentPlayer).connectionToClient).connectionId : ((Object)currentPlayer).GetInstanceID());
if (!playerColorSelections.TryGetValue(key, out var value) || value == 0)
{
continue;
}
int teamIndex = TeamHelper.GetTeamIndex(currentPlayer);
if (teamIndex >= 0)
{
if (!dictionary.ContainsKey(teamIndex))
{
dictionary[teamIndex] = 0;
}
dictionary[teamIndex]++;
}
}
foreach (MultiplayerRoomPlayer currentPlayer2 in currentPlayers)
{
int num = ((((NetworkBehaviour)currentPlayer2).connectionToClient != null) ? ((NetworkConnection)((NetworkBehaviour)currentPlayer2).connectionToClient).connectionId : ((Object)currentPlayer2).GetInstanceID());
if (playerColorSelections.TryGetValue(num, out var value2) && value2 != 0)
{
continue;
}
int num2 = 0;
if (dictionary.Count > 0)
{
num2 = dictionary.OrderBy((KeyValuePair<int, int> kvp) => kvp.Value).First().Key;
}
string text = CurrentAutoTeamColors[num2];
int num3 = Array.IndexOf(colorOptions, text);
if (num3 < 0)
{
LogInstance.LogWarning((object)("自動割り当て: 指定色 '" + text + "' が colorOptions に存在しません。"));
continue;
}
playerColorSelections[num] = num3;
LogInstance.LogInfo((object)$"自動割り当て: プレイヤー {currentPlayer2.playerName} (ID:{num}) をチーム '{text}' に割り当て");
ForceUpdatePlayerName(currentPlayer2);
if (dictionary.ContainsKey(num2))
{
dictionary[num2]++;
}
else
{
dictionary[num2] = 1;
}
}
}
private void Update()
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
if (Input.GetKeyDown(toggleKey))
{
uiOpen = !uiOpen;
LogInfo("管理ウィンドウ表示状態: " + uiOpen);
}
MonitorPlayerList();
}
private void MonitorPlayerList()
{
List<MultiplayerRoomPlayer> list = Object.FindObjectsOfType<MultiplayerRoomPlayer>().ToList();
if (list.Count != previousPlayers.Count || !list.Select((MultiplayerRoomPlayer p) => ((Object)p).GetInstanceID()).SequenceEqual(previousPlayers.Select((MultiplayerRoomPlayer p) => ((Object)p).GetInstanceID())))
{
((MonoBehaviour)this).StartCoroutine(OnPlayerListChangedCoroutine(list));
LogInfo($"[PlayerMonitor] Player list changed: {previousPlayers.Count} -> {list.Count}");
previousPlayers = list;
}
}
private void OnGUI()
{
//IL_000f: 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_002a: Expected O, but got Unknown
//IL_0025: 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)
if (uiOpen)
{
windowRect = GUI.Window(123456, windowRect, new WindowFunction(DrawWindow), "-KASSEN- Team Battle v1.0.4");
}
}
private void DrawWindow(int windowID)
{
//IL_013e: Unknown result type (might be due to invalid IL or missing references)
//IL_0b48: Unknown result type (might be due to invalid IL or missing references)
GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
if (GUILayout.Button(Localize("Language") + " : " + currentLanguage, Array.Empty<GUILayoutOption>()))
{
currentLanguage = ((currentLanguage == Language.English) ? Language.Japanese : Language.English);
LogInfo("Language switched to " + currentLanguage);
}
bool flag = GUILayout.Toggle(modEnabled, Localize("ModEnabled"), Array.Empty<GUILayoutOption>());
if (flag != modEnabled)
{
modEnabled = flag;
if (!modEnabled)
{
gameOverModEnabled = false;
spawnPositioningEnabled = false;
captainModeEnabled = false;
autoTeamAssignmentEnabled = false;
MultiplayerRoomPlayer[] array = Object.FindObjectsOfType<MultiplayerRoomPlayer>();
foreach (MultiplayerRoomPlayer val in array)
{
int key = ((((NetworkBehaviour)val).connectionToClient != null) ? ((NetworkConnection)((NetworkBehaviour)val).connectionToClient).connectionId : ((Object)val).GetInstanceID());
playerColorSelections[key] = 0;
captainFlags[key] = false;
ForceUpdatePlayerName(val);
}
}
}
GUI.enabled = modEnabled;
bool enabled = GUI.enabled;
GUI.enabled = true;
GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f));
GUI.enabled = enabled;
gameOverModEnabled = GUILayout.Toggle(gameOverModEnabled, Localize("TeamGameOverEnabled"), Array.Empty<GUILayoutOption>());
spawnPositioningEnabled = GUILayout.Toggle(spawnPositioningEnabled, Localize("SpawnPositioningEnabled"), Array.Empty<GUILayoutOption>());
bool flag2 = GUILayout.Toggle(captainModeEnabled, Localize("CaptainModeEnabled"), Array.Empty<GUILayoutOption>());
if (flag2 != captainModeEnabled)
{
captainModeEnabled = flag2;
LogInfo("Captain mode switched to " + captainModeEnabled);
if (!captainModeEnabled)
{
MultiplayerRoomPlayer[] array = Object.FindObjectsOfType<MultiplayerRoomPlayer>();
foreach (MultiplayerRoomPlayer val2 in array)
{
int num = ((((NetworkBehaviour)val2).connectionToClient != null) ? ((NetworkConnection)((NetworkBehaviour)val2).connectionToClient).connectionId : ((Object)val2).GetInstanceID());
captainFlags[num] = false;
ForceUpdatePlayerName(val2);
LogInfo($"Captain mode off: Reset captain flag for player {val2.playerName} (ID: {num})");
}
}
}
if (GUILayout.Button(Localize("SelectCaptain"), Array.Empty<GUILayoutOption>()))
{
List<MultiplayerRoomPlayer> list = Object.FindObjectsOfType<MultiplayerRoomPlayer>().ToList();
if (list.Count == 0)
{
LogInstance.LogWarning((object)"Set Random Captain: No players found.");
}
else
{
foreach (KeyValuePair<int, List<MultiplayerRoomPlayer>> item in (from p in list
group p by TeamHelper.GetTeamIndex(p) into g
where g.Key >= 0
select g).ToDictionary((IGrouping<int, MultiplayerRoomPlayer> g) => g.Key, (IGrouping<int, MultiplayerRoomPlayer> g) => g.ToList()))
{
int key2 = item.Key;
List<MultiplayerRoomPlayer> value = item.Value;
foreach (MultiplayerRoomPlayer item2 in value)
{
int key3 = ((((NetworkBehaviour)item2).connectionToClient != null) ? ((NetworkConnection)((NetworkBehaviour)item2).connectionToClient).connectionId : ((Object)item2).GetInstanceID());
captainFlags[key3] = false;
ForceUpdatePlayerName(item2);
}
MultiplayerRoomPlayer val3 = value.OrderBy((MultiplayerRoomPlayer x) => Random.value).First();
int key4 = ((((NetworkBehaviour)val3).connectionToClient != null) ? ((NetworkConnection)((NetworkBehaviour)val3).connectionToClient).connectionId : ((Object)val3).GetInstanceID());
captainFlags[key4] = true;
ForceUpdatePlayerName(val3);
LogInfo($"Set Random Captain: For Team {key2}, assigned Captain = {val3.playerName}");
}
}
}
autoTeamAssignmentEnabled = GUILayout.Toggle(autoTeamAssignmentEnabled, Localize("NewPlayerAutoAssignment"), Array.Empty<GUILayoutOption>());
GUILayout.Space(10f);
if (GUILayout.Button(Localize("ChatBroadcastTeamAssignment"), Array.Empty<GUILayoutOption>()))
{
foreach (MultiplayerRoomPlayer item3 in Object.FindObjectsOfType<MultiplayerRoomPlayer>().ToList())
{
string cleanName = TeamHelper.GetCleanName(item3.NetworkplayerName);
string text = TeamHelper.ExtractTeamColor(item3.NetworkplayerName);
ChatHelper.BroadcastChatMessage(cleanName + ": " + text, "TeamBattleMod");
}
}
if (GUILayout.Button(Localize("PromptTeamCheck"), Array.Empty<GUILayoutOption>()))
{
ChatHelper.BroadcastChatMessage("Press ESC to check your team", "TeamBattleMod");
}
if (GUILayout.Button(Localize("RestartAnnoucement"), Array.Empty<GUILayoutOption>()))
{
ChatHelper.BroadcastChatMessage("Get ready!", "TeamBattleMod");
}
if (GUILayout.Button(Localize("TeamChangeAnnouncement"), Array.Empty<GUILayoutOption>()))
{
ChatHelper.BroadcastChatMessage("Now, team assignments are changing...", "TeamBattleMod");
}
if (GUILayout.Button(Localize("RuleAnnouncement"), Array.Empty<GUILayoutOption>()))
{
ChatHelper.BroadcastChatMessage("Your team is your name color. Same color = friend.", "TeamBattleMod");
ChatHelper.BroadcastChatMessage("Same color = friend, different color = enemy.", "TeamBattleMod");
ChatHelper.BroadcastChatMessage("Kill other color Players!", "TeamBattleMod");
}
if (GUILayout.Button(Localize("RuleAnnouncementForJP"), Array.Empty<GUILayoutOption>()))
{
ChatHelper.BroadcastChatMessage("namae no iro ga team wo arawasi masu", "TeamBattleMod");
ChatHelper.BroadcastChatMessage("player no namae no iroga onazi nara mikata, kotonaru nara teki desu ", "TeamBattleMod");
ChatHelper.BroadcastChatMessage("namae no iro ga tigau player wo taosi masyou!", "TeamBattleMod");
}
GUILayout.Space(10f);
GUILayout.Label(Localize("NameSelection"), Array.Empty<GUILayoutOption>());
GUILayout.Space(10f);
List<MultiplayerRoomPlayer> list2 = Object.FindObjectsOfType<MultiplayerRoomPlayer>().ToList();
GUILayout.Label("Total: " + list2.Count, Array.Empty<GUILayoutOption>());
Dictionary<int, int> dictionary = new Dictionary<int, int>();
foreach (MultiplayerRoomPlayer item4 in list2)
{
int teamIndex = TeamHelper.GetTeamIndex(item4);
if (!dictionary.ContainsKey(teamIndex))
{
dictionary[teamIndex] = 0;
}
dictionary[teamIndex]++;
}
foreach (KeyValuePair<int, int> item5 in dictionary.OrderBy((KeyValuePair<int, int> x) => x.Key))
{
string text2 = ((item5.Key >= 0 && CurrentAutoTeamColors != null && CurrentAutoTeamColors.Length > item5.Key) ? CurrentAutoTeamColors[item5.Key] : ((item5.Key < 0) ? "nothing" : colorOptions[item5.Key]));
string arg = ((!(text2 != "nothing")) ? text2 : ("<color=\"" + text2 + "\">" + text2 + "</color>"));
GUILayout.Label($"{arg}: {item5.Value}", Array.Empty<GUILayoutOption>());
}
GUILayout.Space(10f);
foreach (MultiplayerRoomPlayer item6 in list2)
{
int num2 = ((((NetworkBehaviour)item6).connectionToClient != null) ? ((NetworkConnection)((NetworkBehaviour)item6).connectionToClient).connectionId : ((Object)item6).GetInstanceID());
int value2 = 0;
if (!playerColorSelections.TryGetValue(num2, out value2))
{
value2 = 0;
}
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUILayout.Label("Player: " + item6.playerName, Array.Empty<GUILayoutOption>());
if (GUILayout.Button("Color: " + colorOptions[value2], (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) }))
{
bool value3 = false;
playerDropdownOpen.TryGetValue(num2, out value3);
playerDropdownOpen[num2] = !value3;
LogInfo($"プレイヤーID:{num2} ドロップダウン展開: {playerDropdownOpen[num2]}");
}
bool value4 = false;
if (!captainFlags.TryGetValue(num2, out value4))
{
captainFlags[num2] = false;
value4 = false;
}
bool flag3 = GUILayout.Toggle(value4, Localize("Captain"), Array.Empty<GUILayoutOption>());
if (flag3 != value4)
{
captainFlags[num2] = flag3;
ForceUpdatePlayerName(item6);
}
GUILayout.EndHorizontal();
if (!(playerDropdownOpen.TryGetValue(num2, out var value5) && value5))
{
continue;
}
GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty<GUILayoutOption>());
for (int j = 0; j < colorOptions.Length; j++)
{
if (GUILayout.Button(colorOptions[j], Array.Empty<GUILayoutOption>()))
{
playerColorSelections[num2] = j;
playerDropdownOpen[num2] = false;
LogInfo($"プレイヤーID:{num2} 色選択: {colorOptions[j]} (Index:{j})");
ForceUpdatePlayerName(item6);
}
}
GUILayout.EndVertical();
}
GUILayout.Space(20f);
GUILayout.Label(Localize("AutoTeamAssignmentSettings"), Array.Empty<GUILayoutOption>());
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUILayout.Label(Localize("TeamCount"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) });
teamCountInput = GUILayout.TextField(teamCountInput, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUILayout.Label(Localize("AutoTeamColors"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(180f) });
autoTeamColorsInput = GUILayout.TextField(autoTeamColorsInput, Array.Empty<GUILayoutOption>());
GUILayout.EndHorizontal();
if (GUILayout.Button(Localize("AutoAssignTeams"), Array.Empty<GUILayoutOption>()))
{
if (int.TryParse(teamCountInput, out var result) && result > 0)
{
CurrentAutoTeamColors = (from s in autoTeamColorsInput.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
select s.Trim().ToLower()).ToArray();
CurrentTeamCount = result;
AutoAssignTeams(result, CurrentAutoTeamColors);
LogInfo($"自動チーム分け: チーム数 {result} に分割");
}
else
{
LogInstance.LogWarning((object)"自動チーム分け: 無効なチーム数入力");
}
}
logEnabled = GUILayout.Toggle(logEnabled, Localize("LogEnabled"), Array.Empty<GUILayoutOption>());
GUILayout.Space(10f);
GUILayout.EndVertical();
GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f));
}
public static string RemoveAllTags(string input)
{
if (string.IsNullOrEmpty(input))
{
return "Player";
}
string text = Regex.Replace(input, "<.*?>", "");
if (string.IsNullOrWhiteSpace(text))
{
return "Player";
}
return text;
}
public static void ForceUpdatePlayerName(MultiplayerRoomPlayer player)
{
int num = ((((NetworkBehaviour)player).connectionToClient != null) ? ((NetworkConnection)((NetworkBehaviour)player).connectionToClient).connectionId : ((Object)player).GetInstanceID());
if (!originalPlayerNames.ContainsKey(num))
{
originalPlayerNames[num] = player.playerName;
}
int value = 0;
if (!playerColorSelections.TryGetValue(num, out value))
{
value = 0;
}
string text = colorOptions[value];
string text2 = RemoveAllTags(originalPlayerNames[num]);
if (string.IsNullOrEmpty(text2))
{
text2 = "Player";
}
string text3 = text2;
bool value2 = false;
if (!captainFlags.TryGetValue(num, out value2))
{
value2 = false;
}
if (value2)
{
text3 = "<b><size=20>[CAP]" + text3 + "</size></b>";
}
if (value != 0)
{
text3 = "<color=\"" + text + "\">" + text3 + "</color>";
}
LogInfo($"ForceUpdatePlayerName: ConnId={num}, OriginalName={text2}, SelectedIndex={value}, SelectedColor={text}, NewName={text3}");
player.NetworkplayerName = text3;
}
public static void AutoAssignTeams(int teamCount, string[] autoTeamColors)
{
if (teamCount > autoTeamColors.Length)
{
LogInstance.LogWarning((object)$"チーム数 {teamCount} は自動割り当て可能な色数 {autoTeamColors.Length} を超えています。最大 {autoTeamColors.Length} に設定します。");
teamCount = autoTeamColors.Length;
}
List<MultiplayerRoomPlayer> list = Object.FindObjectsOfType<MultiplayerRoomPlayer>().ToList();
if (list.Count == 0)
{
LogInstance.LogWarning((object)"自動チーム分け: プレイヤーが見つかりません");
return;
}
list = list.OrderBy((MultiplayerRoomPlayer p) => Random.value).ToList();
for (int i = 0; i < list.Count; i++)
{
int num = i % teamCount;
int num2 = ((((NetworkBehaviour)list[i]).connectionToClient != null) ? ((NetworkConnection)((NetworkBehaviour)list[i]).connectionToClient).connectionId : ((Object)list[i]).GetInstanceID());
string text = autoTeamColors[num];
int num3 = Array.IndexOf(colorOptions, text);
if (num3 < 0)
{
LogInstance.LogWarning((object)("自動チーム分け: 指定色 '" + text + "' が利用できません。"));
num3 = 0;
}
playerColorSelections[num2] = num3;
LogInfo($"自動チーム分け: プレイヤー {list[i].playerName} (ID: {num2}) をチーム {text} に割り当て");
ForceUpdatePlayerName(list[i]);
}
}
public static GameObject GetPlayerCharacter(PlayerMultiplayerInputManager manager)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Expected O, but got Unknown
FieldInfo fieldInfo = AccessTools.Field(typeof(PlayerMultiplayerInputManager), "playerCharacter");
if (!(fieldInfo != null))
{
return null;
}
return (GameObject)fieldInfo.GetValue(manager);
}
public static void LogInfo(string log)
{
if (logEnabled)
{
LogInstance.LogInfo((object)log);
}
}
public static void LogWarning(string log)
{
LogInstance.LogWarning((object)log);
}
}
public struct ChatMessage : NetworkMessage
{
public string message;
public string sender;
}
public static class ChatHelper
{
public static void BroadcastChatMessage(string message, string sender)
{
if ((Object)(object)MultiplayerChat.singleton != (Object)null)
{
MethodInfo methodInfo = AccessTools.Method(typeof(MultiplayerChat), "RpcHandleMessage", (Type[])null, (Type[])null);
if (methodInfo != null)
{
methodInfo.Invoke(MultiplayerChat.singleton, new object[2] { message, sender });
GladioMoriKassenTeamBattlePlugin.LogInfo("ChatHelper: Broadcasted message '" + message + "' from '" + sender + "' via RpcHandleMessage");
}
else
{
GladioMoriKassenTeamBattlePlugin.LogWarning("ChatHelper: RpcHandleMessage メソッドが見つかりません");
}
}
else
{
GladioMoriKassenTeamBattlePlugin.LogWarning("ChatHelper: MultiplayerChat.singleton が null です");
}
}
}
public static class SpawnHelperStatic
{
private static readonly Vector3[] team0Spawns_T2 = (Vector3[])(object)new Vector3[8]
{
new Vector3(0f, 1.45f, -12f),
new Vector3(3f, 1.45f, 0f),
new Vector3(0f, 1.45f, -3f),
new Vector3(7f, 6f, 7f),
new Vector3(12f, 1.45f, 0f),
new Vector3(8f, 1.45f, 9f),
new Vector3(7f, 6f, -7f),
new Vector3(8f, 1.45f, -9f)
};
private static readonly Vector3[] team1Spawns_T2 = (Vector3[])(object)new Vector3[8]
{
new Vector3(-12f, 1.45f, 0f),
new Vector3(-8f, 1.45f, 9f),
new Vector3(-7f, 6f, 7f),
new Vector3(-3f, 1.45f, 0f),
new Vector3(-7f, 6f, -7f),
new Vector3(0f, 1.45f, 12f),
new Vector3(-8f, 1.45f, -9f),
new Vector3(0f, 1.45f, 3f)
};
private static readonly Vector3[] team0Spawns_T3 = (Vector3[])(object)new Vector3[6]
{
new Vector3(7f, 6f, -7f),
new Vector3(7f, 6f, 7f),
new Vector3(12f, 1.45f, 0f),
new Vector3(8f, 1.45f, 9f),
new Vector3(3f, 1.45f, 0f),
new Vector3(8f, 1.45f, -9f)
};
private static readonly Vector3[] team1Spawns_T3 = (Vector3[])(object)new Vector3[5]
{
new Vector3(0f, 1.45f, 12f),
new Vector3(-7f, 6f, 7f),
new Vector3(0f, 1.45f, 3f),
new Vector3(-8f, 1.45f, 9f),
new Vector3(-3f, 1.45f, 0f)
};
private static readonly Vector3[] team2Spawns_T3 = (Vector3[])(object)new Vector3[5]
{
new Vector3(-12f, 1.45f, 0f),
new Vector3(0f, 1.45f, -12f),
new Vector3(-7f, 6f, -7f),
new Vector3(0f, 1.45f, -3f),
new Vector3(-8f, 1.45f, -9f)
};
private static readonly Vector3[] team0Spawns_T4 = (Vector3[])(object)new Vector3[4]
{
new Vector3(-7f, 6f, 7f),
new Vector3(-8f, 1.45f, 9f),
new Vector3(-12f, 1.45f, 0f),
new Vector3(-3f, 1.45f, 0f)
};
private static readonly Vector3[] team1Spawns_T4 = (Vector3[])(object)new Vector3[4]
{
new Vector3(0f, 1.45f, 12f),
new Vector3(7f, 6f, 7f),
new Vector3(8f, 1.45f, 9f),
new Vector3(0f, 1.45f, 3f)
};
private static readonly Vector3[] team2Spawns_T4 = (Vector3[])(object)new Vector3[4]
{
new Vector3(-7f, 6f, -7f),
new Vector3(0f, 1.45f, -12f),
new Vector3(0f, 1.45f, -3f),
new Vector3(-8f, 1.45f, -9f)
};
private static readonly Vector3[] team3Spawns_T4 = (Vector3[])(object)new Vector3[4]
{
new Vector3(7f, 6f, -7f),
new Vector3(12f, 1.45f, 0f),
new Vector3(3f, 1.45f, 0f),
new Vector3(8f, 1.45f, -9f)
};
private static readonly Vector3[] team0Spawns_T5 = (Vector3[])(object)new Vector3[4]
{
new Vector3(7f, 6f, -7f),
new Vector3(8f, 1.45f, -9f),
new Vector3(0f, 1.45f, -3f),
new Vector3(0f, 1.45f, -12f)
};
private static readonly Vector3[] team1Spawns_T5 = (Vector3[])(object)new Vector3[3]
{
new Vector3(8f, 1.45f, 9f),
new Vector3(0f, 1.45f, 3f),
new Vector3(0f, 1.45f, 12f)
};
private static readonly Vector3[] team2Spawns_T5 = (Vector3[])(object)new Vector3[3]
{
new Vector3(-8f, 1.45f, -9f),
new Vector3(-3f, 1.45f, 0f),
new Vector3(-7f, 6f, -7f)
};
private static readonly Vector3[] team3Spawns_T5 = (Vector3[])(object)new Vector3[3]
{
new Vector3(12f, 1.45f, 0f),
new Vector3(3f, 1.45f, 0f),
new Vector3(7f, 6f, 7f)
};
private static readonly Vector3[] team4Spawns_T5 = (Vector3[])(object)new Vector3[3]
{
new Vector3(-12f, 1.45f, 0f),
new Vector3(-7f, 6f, 7f),
new Vector3(-8f, 1.45f, 9f)
};
private static readonly Vector3[] team0Spawns_T6 = (Vector3[])(object)new Vector3[3]
{
new Vector3(-3f, 1.45f, 0f),
new Vector3(-12f, 1.45f, 0f),
new Vector3(-7f, 6f, 7f)
};
private static readonly Vector3[] team1Spawns_T6 = (Vector3[])(object)new Vector3[3]
{
new Vector3(3f, 1.45f, 0f),
new Vector3(0f, 1.45f, -12f),
new Vector3(7f, 6f, -7f)
};
private static readonly Vector3[] team2Spawns_T6 = (Vector3[])(object)new Vector3[3]
{
new Vector3(0f, 1.45f, 3f),
new Vector3(-8f, 1.45f, 9f),
new Vector3(0f, 1.45f, 12f)
};
private static readonly Vector3[] team3Spawns_T6 = (Vector3[])(object)new Vector3[3]
{
new Vector3(-8f, 1.45f, -9f),
new Vector3(-7f, 6f, -7f),
new Vector3(0f, 1.45f, -3f)
};
private static readonly Vector3[] team4Spawns_T6 = (Vector3[])(object)new Vector3[2]
{
new Vector3(8f, 1.45f, 9f),
new Vector3(7f, 6f, 7f)
};
private static readonly Vector3[] team5Spawns_T6 = (Vector3[])(object)new Vector3[2]
{
new Vector3(12f, 1.45f, 0f),
new Vector3(8f, 1.45f, -9f)
};
private static Vector3[] GetSpawnArrayForTeam(int teamCount, int teamIndex)
{
switch (teamCount)
{
case 2:
if (teamIndex != 0)
{
return team1Spawns_T2;
}
return team0Spawns_T2;
case 3:
return teamIndex switch
{
0 => team0Spawns_T3,
1 => team1Spawns_T3,
2 => team2Spawns_T3,
_ => throw new ArgumentOutOfRangeException(),
};
case 4:
return teamIndex switch
{
0 => team0Spawns_T4,
1 => team1Spawns_T4,
2 => team2Spawns_T4,
3 => team3Spawns_T4,
_ => throw new ArgumentOutOfRangeException(),
};
case 5:
return teamIndex switch
{
0 => team0Spawns_T5,
1 => team1Spawns_T5,
2 => team2Spawns_T5,
3 => team3Spawns_T5,
4 => team4Spawns_T5,
_ => throw new ArgumentOutOfRangeException(),
};
case 6:
return teamIndex switch
{
0 => team0Spawns_T6,
1 => team1Spawns_T6,
2 => team2Spawns_T6,
3 => team3Spawns_T6,
4 => team4Spawns_T6,
5 => team5Spawns_T6,
_ => throw new ArgumentOutOfRangeException(),
};
default:
throw new NotImplementedException("この実装はチーム数が2,3,4,5,6の場合のみ対応しています。");
}
}
public static Vector3 GetUniqueStaticSpawnPointForTeam(int teamIndex, int teamCount)
{
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
Vector3[] spawnArrayForTeam = GetSpawnArrayForTeam(teamCount, teamIndex);
if (!GladioMoriKassenTeamBattlePlugin.usedStaticSpawnPositions.ContainsKey(teamIndex))
{
GladioMoriKassenTeamBattlePlugin.usedStaticSpawnPositions[teamIndex] = new HashSet<Vector3>();
}
Vector3[] array = spawnArrayForTeam.OrderByDescending(delegate(Vector3 sp)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
Vector2 val3 = new Vector2(sp.x, sp.z);
return ((Vector2)(ref val3)).magnitude;
}).ToArray();
Vector3[] array2 = array;
foreach (Vector3 val in array2)
{
if (!GladioMoriKassenTeamBattlePlugin.usedStaticSpawnPositions[teamIndex].Contains(val))
{
GladioMoriKassenTeamBattlePlugin.usedStaticSpawnPositions[teamIndex].Add(val);
return val;
}
}
GladioMoriKassenTeamBattlePlugin.LogInstance.LogWarning((object)$"All static spawn positions for team {teamIndex} are used. Returning a random spawn.");
Vector3 val2 = array[Random.Range(0, array.Length)];
GladioMoriKassenTeamBattlePlugin.usedStaticSpawnPositions[teamIndex].Add(val2);
return val2;
}
public static void ClearUsedStaticSpawnPositions()
{
foreach (int item in GladioMoriKassenTeamBattlePlugin.usedStaticSpawnPositions.Keys.ToList())
{
GladioMoriKassenTeamBattlePlugin.usedStaticSpawnPositions[item].Clear();
}
}
}
[HarmonyPatch(typeof(MultiplayerRoomPlayer), "UserCode_CmdChangePlayerName__String")]
public static class NameChangerPatch
{
private static bool Prefix(MultiplayerRoomPlayer __instance, ref string newPlayerName)
{
if (!GladioMoriKassenTeamBattlePlugin.modEnabled)
{
return true;
}
int num = ((((NetworkBehaviour)__instance).connectionToClient != null) ? ((NetworkConnection)((NetworkBehaviour)__instance).connectionToClient).connectionId : ((Object)__instance).GetInstanceID());
int value = 0;
GladioMoriKassenTeamBattlePlugin.playerColorSelections.TryGetValue(num, out value);
string text = GladioMoriKassenTeamBattlePlugin.colorOptions[value];
GladioMoriKassenTeamBattlePlugin.LogInfo($"[NameChangerPatch] ConnId={num} : Before Process newPlayerName={newPlayerName}, SelectedIndex={value}, SelectedColor={text}");
if (newPlayerName.StartsWith("<color=") && newPlayerName.EndsWith("</color>"))
{
int num2 = newPlayerName.IndexOf(">") + 1;
int num3 = newPlayerName.LastIndexOf("</color>");
if (num2 > 0 && num3 > num2)
{
newPlayerName = newPlayerName.Substring(num2, num3 - num2);
}
}
if (value != 0)
{
newPlayerName = "<color=\"" + text + "\">" + newPlayerName + "</color>";
}
GladioMoriKassenTeamBattlePlugin.LogInfo($"[NameChangerPatch] ConnId={num} : After Process newPlayerName={newPlayerName}");
return true;
}
}
[HarmonyPatch(typeof(PlayerMultiplayerInputManager), "CreatePlayer")]
public static class SpawnPatch
{
private static bool Prefix(PlayerMultiplayerInputManager __instance)
{
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: 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_01a7: Unknown result type (might be due to invalid IL or missing references)
if (!GladioMoriKassenTeamBattlePlugin.spawnPositioningEnabled)
{
return true;
}
if (!NetworkServer.active)
{
Debug.LogWarning((object)"[Server] CreatePlayer called when server was not active");
return false;
}
if ((Object)(object)__instance.multiplayerRoomPlayer == (Object)null)
{
GladioMoriKassenTeamBattlePlugin.LogInfo("SpawnPatch: multiplayerRoomPlayer not found");
return false;
}
int teamIndex = TeamHelper.GetTeamIndex(__instance.multiplayerRoomPlayer);
GladioMoriKassenTeamBattlePlugin.LogInfo($"SpawnPatch: teamIndex = {teamIndex}");
int currentTeamCount = GladioMoriKassenTeamBattlePlugin.CurrentTeamCount;
if (teamIndex < 0 || currentTeamCount <= 0)
{
GladioMoriKassenTeamBattlePlugin.LogInfo($"SpawnPatch: illegal state teamIndex:{teamIndex} or teamCount:{currentTeamCount}");
return true;
}
Vector3 uniqueStaticSpawnPointForTeam = SpawnHelperStatic.GetUniqueStaticSpawnPointForTeam(teamIndex, currentTeamCount);
Quaternion identity = Quaternion.identity;
GameObject val = Object.Instantiate<GameObject>(__instance.playerPrefab, uniqueStaticSpawnPointForTeam, identity);
AccessTools.Field(typeof(PlayerMultiplayerInputManager), "playerCharacter").SetValue(__instance, val);
NetworkServer.Spawn(val, (NetworkConnection)null);
FieldInfo fieldInfo = AccessTools.Field(typeof(PlayerMultiplayerInputManager), "ballMovements");
List<BallMovement> value = val.GetComponentsInChildren<BallMovement>().ToList();
fieldInfo.SetValue(__instance, value);
__instance.rotatePlayer = val.GetComponentsInChildren<RotatePlayer>(true).FirstOrDefault();
FieldInfo fieldInfo2 = AccessTools.Field(typeof(PlayerMultiplayerInputManager), "playerAnimator");
PlayerAnimator componentInChildren = val.GetComponentInChildren<PlayerAnimator>();
fieldInfo2.SetValue(__instance, componentInChildren);
FieldInfo fieldInfo3 = AccessTools.Field(typeof(PlayerMultiplayerInputManager), "playerHealth");
PlayerHealth component = val.GetComponent<PlayerHealth>();
fieldInfo3.SetValue(__instance, component);
if (__instance.moveSet != null && (Object)(object)componentInChildren != (Object)null)
{
componentInChildren.SetMoveSet(__instance.moveSet, false, false);
__instance.UpdateDefaultMovesetSettings();
}
component.SetEquipment(__instance.equippedEquipment, true);
NetworkIdentity component2 = val.GetComponent<NetworkIdentity>();
__instance.NetworkplayerHealthIdentity = component2.netId;
component.OnlyPhysical();
GladioMoriKassenTeamBattlePlugin.LogInfo($"SpawnPatch: Player {__instance.playerName} instantiated at {uniqueStaticSpawnPointForTeam}");
return false;
}
}
public static class TeamHelper
{
public static int GetTeamIndex(MultiplayerRoomPlayer mrp)
{
int key = ((((NetworkBehaviour)mrp).connectionToClient != null) ? ((NetworkConnection)((NetworkBehaviour)mrp).connectionToClient).connectionId : ((Object)mrp).GetInstanceID());
if (GladioMoriKassenTeamBattlePlugin.playerColorSelections.TryGetValue(key, out var value))
{
string value2 = GladioMoriKassenTeamBattlePlugin.colorOptions[value];
if (GladioMoriKassenTeamBattlePlugin.CurrentAutoTeamColors != null)
{
return Array.IndexOf(GladioMoriKassenTeamBattlePlugin.CurrentAutoTeamColors, value2);
}
return value;
}
return -1;
}
public static string GetCleanNameFromNetwork(MultiplayerRoomPlayer mrp)
{
string networkplayerName = mrp.NetworkplayerName;
if (!string.IsNullOrEmpty(networkplayerName) && networkplayerName.StartsWith("<color=\"") && networkplayerName.EndsWith("</color>"))
{
int num = networkplayerName.IndexOf(">") + 1;
int num2 = networkplayerName.LastIndexOf("</color>");
if (num > 0 && num2 > num)
{
return networkplayerName.Substring(num, num2 - num).ToLower();
}
}
return networkplayerName;
}
public static string ExtractTeamColor(string coloredName)
{
if (!string.IsNullOrEmpty(coloredName) && coloredName.StartsWith("<color=\"") && coloredName.Contains("\">"))
{
int length = "<color=\"".Length;
int num = coloredName.IndexOf("\">", length);
if (num > length)
{
string text = coloredName.Substring(length, num - length).ToLower();
GladioMoriKassenTeamBattlePlugin.LogInfo("ExtractTeamColor: Raw='" + coloredName + "', Extracted='" + text + "'");
return text;
}
}
GladioMoriKassenTeamBattlePlugin.LogInstance.LogWarning((object)("ExtractTeamColor: Invalid input. Value = '" + coloredName + "'"));
return "";
}
public static string GetCleanName(string coloredName)
{
if (!string.IsNullOrEmpty(coloredName) && coloredName.StartsWith("<color=\"") && coloredName.EndsWith("</color>"))
{
int num = coloredName.IndexOf(">") + 1;
int num2 = coloredName.LastIndexOf("</color>");
if (num > 0 && num2 > num)
{
return coloredName.Substring(num, num2 - num);
}
}
return coloredName;
}
}
[HarmonyPatch(typeof(GameMaster), "GameOver")]
public static class GameOverPatch
{
private static bool Prefix(GameMaster __instance, bool forceLoss)
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Expected O, but got Unknown
//IL_011a: Unknown result type (might be due to invalid IL or missing references)
//IL_014a: Unknown result type (might be due to invalid IL or missing references)
//IL_0184: Unknown result type (might be due to invalid IL or missing references)
//IL_0189: Unknown result type (might be due to invalid IL or missing references)
//IL_0196: Unknown result type (might be due to invalid IL or missing references)
//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
//IL_01ba: Expected O, but got Unknown
//IL_0221: Unknown result type (might be due to invalid IL or missing references)
if (!GladioMoriKassenTeamBattlePlugin.gameOverModEnabled)
{
return true;
}
if (__instance.gameIsOver || __instance.testScene)
{
return false;
}
__instance.gameIsOver = true;
if ((Object)(object)ReplayManager.singleton != (Object)null)
{
ReplayManager.singleton.PauseRecording();
}
WinScreenInfo val = new WinScreenInfo();
List<PlayerGameStateInfo> list = __instance.registeredPlayers.Where((PlayerGameStateInfo x) => x.player.alive).ToList();
GladioMoriKassenTeamBattlePlugin.LogInfo($"GameOverPatch: AlivePlayers Count = {list.Count}");
Dictionary<string, List<PlayerGameStateInfo>> dictionary = new Dictionary<string, List<PlayerGameStateInfo>>();
foreach (PlayerGameStateInfo item in list)
{
string text = TeamHelper.ExtractTeamColor(item.player.playerName);
GladioMoriKassenTeamBattlePlugin.LogInfo("GameOverPatch: Player " + item.player.playerName + " チーム = " + text);
if (!dictionary.ContainsKey(text))
{
dictionary[text] = new List<PlayerGameStateInfo>();
}
dictionary[text].Add(item);
}
if (forceLoss)
{
val.gameEndResultType = (GameEndResultType)2;
}
else
{
GladioMoriKassenTeamBattlePlugin.GameDecision gameDecision = ((!GladioMoriKassenTeamBattlePlugin.captainModeEnabled) ? GladioMoriKassenTeamBattlePlugin.GameDecisionEvaluator.EvaluateStandardGameResult(dictionary, list) : GladioMoriKassenTeamBattlePlugin.GameDecisionEvaluator.EvaluateCaptainGameResult(dictionary, list));
val.gameEndResultType = (GameEndResultType)((gameDecision.Result != 0) ? 1 : 0);
val.winningPlayerName = gameDecision.WinningTeam;
}
val.playerList = new List<WinScreenPlayerInfo>();
foreach (PlayerGameStateInfo registeredPlayer in __instance.registeredPlayers)
{
val.playerList.Add(new WinScreenPlayerInfo
{
deathTime = registeredPlayer.deathTime,
playerName = registeredPlayer.player.playerName,
deathReason = registeredPlayer.deathReason
});
}
if ((Object)(object)SingleplayerManager.singleton != (Object)null)
{
bool flag = false;
if (!forceLoss && list.Count > 0 && dictionary.Count == 1 && !dictionary.First().Value.First().player.ai)
{
flag = true;
}
SingleplayerManager.singleton.HandleFightResult(val.gameEndResultType, flag);
}
if ((Object)(object)__instance.multiplayerGameMaster != (Object)null)
{
GladioMoriKassenTeamBattlePlugin.LogInfo("GameOverPatch: Calling multiplayerGameMaster.GameOver");
__instance.multiplayerGameMaster.GameOver(val);
foreach (int item2 in GladioMoriKassenTeamBattlePlugin.usedStaticSpawnPositions.Keys.ToList())
{
GladioMoriKassenTeamBattlePlugin.usedStaticSpawnPositions[item2].Clear();
}
GladioMoriKassenTeamBattlePlugin.LogInfo("GameOverPatch: usedSpawnPositions cleared.");
return false;
}
if ((Object)(object)__instance.gameMenu != (Object)null)
{
__instance.gameMenu.ShowWinScreenInfo(val);
}
foreach (int item3 in GladioMoriKassenTeamBattlePlugin.usedStaticSpawnPositions.Keys.ToList())
{
GladioMoriKassenTeamBattlePlugin.usedStaticSpawnPositions[item3].Clear();
}
GladioMoriKassenTeamBattlePlugin.LogInfo("GameOverPatch: usedSpawnPositions cleared.");
return false;
}
}
[HarmonyPatch(typeof(GameMaster), "InformPlayerDeath")]
public static class InformPlayerDeathPatch
{
private static void Postfix(GameMaster __instance, PlayerHealth player, DeathReason newDeathReason, PlayerHealth newKiller)
{
if (!GladioMoriKassenTeamBattlePlugin.gameOverModEnabled)
{
return;
}
string playerName = player.playerName;
string text = (string.IsNullOrEmpty(playerName) ? playerName : Regex.Replace(playerName, "<color=\"[^\"]*\">|</color>", ""));
if (text.StartsWith("<b><size=20>[CAP]"))
{
string text2 = TeamHelper.ExtractTeamColor(playerName);
string text3 = Regex.Replace(text, "<.*?>", string.Empty);
string text4 = "Captain " + text3 + " of team " + text2 + " has died!";
ChatHelper.BroadcastChatMessage(text4, "TeamBattleMod");
GladioMoriKassenTeamBattlePlugin.LogInfo("InformPlayerDeathPatch: Announced captain death: " + text4);
}
List<PlayerGameStateInfo> list = __instance.registeredPlayers.Where((PlayerGameStateInfo x) => !x.player.ai && x.player.alive).ToList();
Dictionary<string, List<PlayerGameStateInfo>> dictionary = new Dictionary<string, List<PlayerGameStateInfo>>();
foreach (PlayerGameStateInfo item in list)
{
string key = TeamHelper.ExtractTeamColor(item.player.playerName);
if (!dictionary.ContainsKey(key))
{
dictionary[key] = new List<PlayerGameStateInfo>();
}
dictionary[key].Add(item);
}
List<string> values = dictionary.Keys.ToList();
GladioMoriKassenTeamBattlePlugin.LogInfo(string.Format("InformPlayerDeathPatch: AliveNonAIMembers={0}, UniqueTeams={1}", list.Count, string.Join(", ", values)));
GladioMoriKassenTeamBattlePlugin.GameDecision gameDecision = ((!GladioMoriKassenTeamBattlePlugin.captainModeEnabled) ? GladioMoriKassenTeamBattlePlugin.GameDecisionEvaluator.EvaluateStandardGameResult(dictionary, list) : GladioMoriKassenTeamBattlePlugin.GameDecisionEvaluator.EvaluateCaptainGameResult(dictionary, list));
GladioMoriKassenTeamBattlePlugin.LogInfo($"InformPlayerDeathPatch: Game decision result = {gameDecision.Result}, WinningTeam = {gameDecision.WinningTeam}");
if (gameDecision.Result == GladioMoriKassenTeamBattlePlugin.GameResultType.Win && !__instance.gameIsOver)
{
GladioMoriKassenTeamBattlePlugin.LogInfo("InformPlayerDeathPatch: Game decision reached, starting GameOverTimer");
MethodInfo methodInfo = AccessTools.Method(typeof(GameMaster), "GameOverTimer", (Type[])null, (Type[])null);
if (methodInfo != null)
{
IEnumerator enumerator2 = (IEnumerator)methodInfo.Invoke(__instance, null);
((MonoBehaviour)__instance).StartCoroutine(enumerator2);
}
else
{
GladioMoriKassenTeamBattlePlugin.LogInstance.LogError((object)"InformPlayerDeathPatch: GameOverTimer method not found");
}
}
}
}
[HarmonyPatch(typeof(GameMenu), "RestartGame")]
public static class RestartGamePatch
{
private static void Prefix()
{
SpawnHelperStatic.ClearUsedStaticSpawnPositions();
GladioMoriKassenTeamBattlePlugin.LogInfo("RestartGamePatch: usedStaticSpawnPositions cleared.");
}
}
[HarmonyPatch(typeof(MultiplayerMenuManager), "Start")]
public static class MultiplayerMenuManagerStartPatch
{
private static void Prefix()
{
GladioMoriKassenTeamBattlePlugin.originalPlayerNames.Clear();
}
}
[HarmonyPatch(typeof(MultiplayerChat), "RpcHandleMessage")]
public static class RpcHandleMessagePatch
{
private static void Prefix(ref string playerName)
{
playerName = Regex.Replace(playerName, "<.*?>", string.Empty);
}
}