766 lines
21 KiB
C#
766 lines
21 KiB
C#
|
using System;
|
||
|
using System.Collections.ObjectModel;
|
||
|
using System.Runtime.InteropServices;
|
||
|
using JetBrains.Annotations;
|
||
|
using RoR2.ConVar;
|
||
|
using RoR2.EntitlementManagement;
|
||
|
using RoR2.ExpansionManagement;
|
||
|
using UnityEngine;
|
||
|
using UnityEngine.Networking;
|
||
|
|
||
|
namespace RoR2;
|
||
|
|
||
|
[RequireComponent(typeof(NetworkRuleChoiceMask))]
|
||
|
[RequireComponent(typeof(NetworkRuleBook))]
|
||
|
public class PreGameController : NetworkBehaviour
|
||
|
{
|
||
|
private enum PregameState
|
||
|
{
|
||
|
Idle,
|
||
|
Launching,
|
||
|
Launched
|
||
|
}
|
||
|
|
||
|
public class GameModeConVar : BaseConVar
|
||
|
{
|
||
|
public static readonly GameModeConVar instance;
|
||
|
|
||
|
public Run runPrefabComponent;
|
||
|
|
||
|
public GameModeConVar(string name, ConVarFlags flags, string defaultValue, string helpText)
|
||
|
: base(name, flags, defaultValue, helpText)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
static GameModeConVar()
|
||
|
{
|
||
|
instance = new GameModeConVar("gamemode", ConVarFlags.None, "ClassicRun", "Sets the specified game mode as the one to use in the next run.");
|
||
|
GameModeCatalog.availability.CallWhenAvailable(delegate
|
||
|
{
|
||
|
instance.runPrefabComponent = GameModeCatalog.FindGameModePrefabComponent(instance.GetString());
|
||
|
});
|
||
|
}
|
||
|
|
||
|
public override void SetString(string newValue)
|
||
|
{
|
||
|
GameModeCatalog.availability.CallWhenAvailable(delegate
|
||
|
{
|
||
|
Run run = GameModeCatalog.FindGameModePrefabComponent(newValue);
|
||
|
if (!run)
|
||
|
{
|
||
|
Debug.LogFormat("GameMode \"{0}\" does not exist.", newValue);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
runPrefabComponent = run;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
public override string GetString()
|
||
|
{
|
||
|
if (!runPrefabComponent)
|
||
|
{
|
||
|
return "ClassicRun";
|
||
|
}
|
||
|
return runPrefabComponent.gameObject.name;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private NetworkRuleChoiceMask networkRuleChoiceMaskComponent;
|
||
|
|
||
|
private NetworkRuleBook networkRuleBookComponent;
|
||
|
|
||
|
private RuleChoiceMask serverAvailableChoiceMask;
|
||
|
|
||
|
public ulong runSeed;
|
||
|
|
||
|
public static readonly IntConVar overrideRunSeed;
|
||
|
|
||
|
[SyncVar(hook = "UpdateGameModeIndex")]
|
||
|
private int _gameModeIndex;
|
||
|
|
||
|
private GameObject lobbyBackground;
|
||
|
|
||
|
private int currentLobbyBackgroundGameModeIndex;
|
||
|
|
||
|
private float lobbyBackgroundTimeToRefresh;
|
||
|
|
||
|
private const float lobbyBackgroundTimeToRefreshInterval = 4f;
|
||
|
|
||
|
private RuleBook ruleBookBuffer;
|
||
|
|
||
|
[SyncVar]
|
||
|
private int pregameStateInternal;
|
||
|
|
||
|
private const float launchTransitionDuration = 0f;
|
||
|
|
||
|
private GameObject gameModePrefab;
|
||
|
|
||
|
[SyncVar]
|
||
|
private float launchStartTime = float.PositiveInfinity;
|
||
|
|
||
|
private RuleChoiceMask unlockedChoiceMask;
|
||
|
|
||
|
private RuleChoiceMask dependencyChoiceMask;
|
||
|
|
||
|
private RuleChoiceMask entitlementChoiceMask;
|
||
|
|
||
|
private RuleChoiceMask requiredExpansionEnabledChoiceMask;
|
||
|
|
||
|
private RuleChoiceMask choiceMaskBuffer;
|
||
|
|
||
|
public static readonly BoolConVar cvSvAllowRuleVoting;
|
||
|
|
||
|
public static readonly BoolConVar cvSvAllowMultiplayerPause;
|
||
|
|
||
|
private static int kRpcRpcUpdateGameModeIndex;
|
||
|
|
||
|
private static int kRpcRpcUpdateMultiplayerPause;
|
||
|
|
||
|
public static PreGameController instance { get; private set; }
|
||
|
|
||
|
public RuleChoiceMask resolvedRuleChoiceMask => networkRuleChoiceMaskComponent.ruleChoiceMask;
|
||
|
|
||
|
public RuleBook readOnlyRuleBook => networkRuleBookComponent.ruleBook;
|
||
|
|
||
|
public GameModeIndex gameModeIndex
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return (GameModeIndex)_gameModeIndex;
|
||
|
}
|
||
|
set
|
||
|
{
|
||
|
Network_gameModeIndex = (int)value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private PregameState pregameState
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return (PregameState)pregameStateInternal;
|
||
|
}
|
||
|
set
|
||
|
{
|
||
|
NetworkpregameStateInternal = (int)value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public int Network_gameModeIndex
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return _gameModeIndex;
|
||
|
}
|
||
|
[param: In]
|
||
|
set
|
||
|
{
|
||
|
if (NetworkServer.localClientActive && !base.syncVarHookGuard)
|
||
|
{
|
||
|
base.syncVarHookGuard = true;
|
||
|
UpdateGameModeIndex(value);
|
||
|
base.syncVarHookGuard = false;
|
||
|
}
|
||
|
SetSyncVar(value, ref _gameModeIndex, 1u);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public int NetworkpregameStateInternal
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return pregameStateInternal;
|
||
|
}
|
||
|
[param: In]
|
||
|
set
|
||
|
{
|
||
|
SetSyncVar(value, ref pregameStateInternal, 2u);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public float NetworklaunchStartTime
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return launchStartTime;
|
||
|
}
|
||
|
[param: In]
|
||
|
set
|
||
|
{
|
||
|
SetSyncVar(value, ref launchStartTime, 4u);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static event Action<PreGameController, RuleBook> onPreGameControllerSetRuleBookServerGlobal;
|
||
|
|
||
|
public static event Action<PreGameController, RuleBook> onPreGameControllerSetRuleBookGlobal;
|
||
|
|
||
|
public static event Action<PreGameController> onServerRecalculatedModifierAvailability;
|
||
|
|
||
|
private void Awake()
|
||
|
{
|
||
|
lobbyBackgroundTimeToRefresh = 0f;
|
||
|
networkRuleChoiceMaskComponent = GetComponent<NetworkRuleChoiceMask>();
|
||
|
networkRuleBookComponent = GetComponent<NetworkRuleBook>();
|
||
|
networkRuleBookComponent.onRuleBookUpdated += OnRuleBookUpdated;
|
||
|
ruleBookBuffer = new RuleBook();
|
||
|
serverAvailableChoiceMask = new RuleChoiceMask();
|
||
|
unlockedChoiceMask = new RuleChoiceMask();
|
||
|
dependencyChoiceMask = new RuleChoiceMask();
|
||
|
entitlementChoiceMask = new RuleChoiceMask();
|
||
|
choiceMaskBuffer = new RuleChoiceMask();
|
||
|
requiredExpansionEnabledChoiceMask = new RuleChoiceMask();
|
||
|
if (NetworkServer.active)
|
||
|
{
|
||
|
gameModeIndex = GameModeCatalog.FindGameModeIndex(GameModeConVar.instance.GetString());
|
||
|
runSeed = GameModeCatalog.GetGameModePrefabComponent(gameModeIndex).GenerateSeedForNewRun();
|
||
|
}
|
||
|
bool isInSinglePlayer = RoR2Application.isInSinglePlayer;
|
||
|
for (int i = 0; i < serverAvailableChoiceMask.length; i++)
|
||
|
{
|
||
|
RuleChoiceDef choiceDef = RuleCatalog.GetChoiceDef(i);
|
||
|
serverAvailableChoiceMask[i] = (isInSinglePlayer ? choiceDef.availableInSinglePlayer : choiceDef.availableInMultiPlayer);
|
||
|
}
|
||
|
NetworkUser.OnPostNetworkUserStart += GenerateRuleVoteController;
|
||
|
RefreshLobbyBackground();
|
||
|
}
|
||
|
|
||
|
private void OnDestroy()
|
||
|
{
|
||
|
NetworkUser.OnPostNetworkUserStart -= GenerateRuleVoteController;
|
||
|
}
|
||
|
|
||
|
private void GenerateRuleVoteController(NetworkUser networkUser)
|
||
|
{
|
||
|
if (NetworkServer.active && !PreGameRuleVoteController.FindForUser(networkUser) && (networkUser.isLocalPlayer || cvSvAllowRuleVoting.value))
|
||
|
{
|
||
|
PreGameRuleVoteController.CreateForNetworkUserServer(networkUser);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void Start()
|
||
|
{
|
||
|
if (!NetworkServer.active)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
ResolveChoiceMask();
|
||
|
Console.instance.SubmitCmd(null, "exec server_pregame");
|
||
|
foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList)
|
||
|
{
|
||
|
Debug.LogFormat("Attempting to generate PreGameVoteController for {0}", readOnlyInstances.userName);
|
||
|
GenerateRuleVoteController(readOnlyInstances);
|
||
|
readOnlyInstances.BumpDLCChecker();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Server]
|
||
|
public bool ApplyChoice(int ruleChoiceIndex)
|
||
|
{
|
||
|
if (!NetworkServer.active)
|
||
|
{
|
||
|
Debug.LogWarning("[Server] function 'System.Boolean RoR2.PreGameController::ApplyChoice(System.Int32)' called on client");
|
||
|
return false;
|
||
|
}
|
||
|
if (!resolvedRuleChoiceMask[ruleChoiceIndex])
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
RuleChoiceDef choiceDef = RuleCatalog.GetChoiceDef(ruleChoiceIndex);
|
||
|
if (readOnlyRuleBook.GetRuleChoice(choiceDef.ruleDef.globalIndex) == choiceDef)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
ruleBookBuffer.Copy(readOnlyRuleBook);
|
||
|
ruleBookBuffer.ApplyChoice(choiceDef);
|
||
|
SetRuleBook(ruleBookBuffer);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
private void SetRuleBook(RuleBook newRuleBook)
|
||
|
{
|
||
|
networkRuleBookComponent.SetRuleBook(newRuleBook);
|
||
|
PreGameController.onPreGameControllerSetRuleBookServerGlobal?.Invoke(this, readOnlyRuleBook);
|
||
|
}
|
||
|
|
||
|
private void OnRuleBookUpdated(NetworkRuleBook networkRuleBookComponent)
|
||
|
{
|
||
|
PreGameController.onPreGameControllerSetRuleBookGlobal?.Invoke(this, networkRuleBookComponent.ruleBook);
|
||
|
}
|
||
|
|
||
|
[Server]
|
||
|
public void EnforceValidRuleChoices()
|
||
|
{
|
||
|
if (!NetworkServer.active)
|
||
|
{
|
||
|
Debug.LogWarning("[Server] function 'System.Void RoR2.PreGameController::EnforceValidRuleChoices()' called on client");
|
||
|
return;
|
||
|
}
|
||
|
ruleBookBuffer.Copy(readOnlyRuleBook);
|
||
|
for (int i = 0; i < RuleCatalog.ruleCount; i++)
|
||
|
{
|
||
|
RuleChoiceDef ruleChoice = ruleBookBuffer.GetRuleChoice(i);
|
||
|
if (resolvedRuleChoiceMask[ruleChoice])
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
RuleDef ruleDef = RuleCatalog.GetRuleDef(i);
|
||
|
RuleChoiceDef choiceDef = ruleDef.choices[ruleDef.defaultChoiceIndex];
|
||
|
int num = 0;
|
||
|
int j = 0;
|
||
|
for (int count = ruleDef.choices.Count; j < count; j++)
|
||
|
{
|
||
|
if (resolvedRuleChoiceMask[ruleDef.choices[j]])
|
||
|
{
|
||
|
num++;
|
||
|
}
|
||
|
}
|
||
|
if (resolvedRuleChoiceMask[choiceDef] || num == 0)
|
||
|
{
|
||
|
ruleBookBuffer.ApplyChoice(choiceDef);
|
||
|
continue;
|
||
|
}
|
||
|
int k = 0;
|
||
|
for (int count2 = ruleDef.choices.Count; k < count2; k++)
|
||
|
{
|
||
|
if (resolvedRuleChoiceMask[ruleDef.choices[k]])
|
||
|
{
|
||
|
ruleBookBuffer.ApplyChoice(ruleDef.choices[k]);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
SetRuleBook(ruleBookBuffer);
|
||
|
}
|
||
|
|
||
|
private void TestRuleValues()
|
||
|
{
|
||
|
RuleBook ruleBook = new RuleBook();
|
||
|
ruleBook.Copy(networkRuleBookComponent.ruleBook);
|
||
|
RuleDef ruleDef = RuleCatalog.GetRuleDef(UnityEngine.Random.Range(0, RuleCatalog.ruleCount));
|
||
|
RuleChoiceDef choiceDef = ruleDef.choices[UnityEngine.Random.Range(0, ruleDef.choices.Count)];
|
||
|
ruleBook.ApplyChoice(choiceDef);
|
||
|
SetRuleBook(ruleBook);
|
||
|
Invoke("TestRuleValues", 0.5f);
|
||
|
}
|
||
|
|
||
|
public override void OnStartClient()
|
||
|
{
|
||
|
base.OnStartClient();
|
||
|
PauseManager.isPaused = false;
|
||
|
PauseStopController.instance?.ForceClientUnpause();
|
||
|
}
|
||
|
|
||
|
private void OnEnable()
|
||
|
{
|
||
|
instance = SingletonHelper.Assign(instance, this);
|
||
|
if (NetworkServer.active)
|
||
|
{
|
||
|
RecalculateModifierAvailability();
|
||
|
}
|
||
|
NetworkUser.OnNetworkUserUnlockablesUpdated += OnNetworkUserUnlockablesUpdatedCallback;
|
||
|
NetworkUser.OnPostNetworkUserStart += OnPostNetworkUserStartCallback;
|
||
|
NetworkUser.onNetworkUserBodyPreferenceChanged += OnNetworkUserBodyPreferenceChanged;
|
||
|
NetworkUser.onNetworkUserLost += OnNetworkUserLost;
|
||
|
if (NetworkClient.active)
|
||
|
{
|
||
|
foreach (NetworkUser readOnlyLocalPlayers in NetworkUser.readOnlyLocalPlayersList)
|
||
|
{
|
||
|
readOnlyLocalPlayers.SendServerUnlockables();
|
||
|
}
|
||
|
}
|
||
|
if (!NetworkServer.active)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList)
|
||
|
{
|
||
|
readOnlyInstances.ServerRequestUnlockables();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void OnDisable()
|
||
|
{
|
||
|
instance = SingletonHelper.Unassign(instance, this);
|
||
|
NetworkUser.OnPostNetworkUserStart -= OnPostNetworkUserStartCallback;
|
||
|
NetworkUser.OnNetworkUserUnlockablesUpdated -= OnNetworkUserUnlockablesUpdatedCallback;
|
||
|
NetworkUser.onNetworkUserBodyPreferenceChanged -= OnNetworkUserBodyPreferenceChanged;
|
||
|
NetworkUser.onNetworkUserLost -= OnNetworkUserLost;
|
||
|
}
|
||
|
|
||
|
public bool IsCharacterSwitchingCurrentlyAllowed()
|
||
|
{
|
||
|
return pregameState == PregameState.Idle;
|
||
|
}
|
||
|
|
||
|
private void Update()
|
||
|
{
|
||
|
if (pregameState == PregameState.Launching)
|
||
|
{
|
||
|
if (PlatformSystems.networkManager.unpredictedServerFixedTime - launchStartTime >= 0.5f && NetworkServer.active)
|
||
|
{
|
||
|
StartRun();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_ = pregameState;
|
||
|
_ = 2;
|
||
|
}
|
||
|
if (NetworkServer.active)
|
||
|
{
|
||
|
lobbyBackgroundTimeToRefresh -= Time.deltaTime;
|
||
|
if (lobbyBackgroundTimeToRefresh <= 0f)
|
||
|
{
|
||
|
lobbyBackgroundTimeToRefresh = 4f;
|
||
|
CallRpcUpdateGameModeIndex(_gameModeIndex);
|
||
|
CallRpcUpdateMultiplayerPause(cvSvAllowMultiplayerPause.value);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Server]
|
||
|
public void StartLaunch()
|
||
|
{
|
||
|
if (!NetworkServer.active)
|
||
|
{
|
||
|
Debug.LogWarning("[Server] function 'System.Void RoR2.PreGameController::StartLaunch()' called on client");
|
||
|
}
|
||
|
else if (pregameState == PregameState.Idle)
|
||
|
{
|
||
|
pregameState = PregameState.Launching;
|
||
|
NetworklaunchStartTime = PlatformSystems.networkManager.unpredictedServerFixedTime;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[Server]
|
||
|
private void StartRun()
|
||
|
{
|
||
|
if (!NetworkServer.active)
|
||
|
{
|
||
|
Debug.LogWarning("[Server] function 'System.Void RoR2.PreGameController::StartRun()' called on client");
|
||
|
return;
|
||
|
}
|
||
|
ExpansionRequirementComponent component = GameModeConVar.instance.runPrefabComponent.GetComponent<ExpansionRequirementComponent>();
|
||
|
if (!component || !component.requiredExpansion || EntitlementManager.networkUserEntitlementTracker.AnyUserHasEntitlement(component.requiredExpansion.requiredEntitlement))
|
||
|
{
|
||
|
pregameState = PregameState.Launched;
|
||
|
NetworkSession.instance.BeginRun(GameModeConVar.instance.runPrefabComponent, readOnlyRuleBook, runSeed);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[ConCommand(commandName = "pregame_start_run", flags = ConVarFlags.SenderMustBeServer, helpText = "Begins a run out of pregame.")]
|
||
|
private static void CCPregameStartRun(ConCommandArgs args)
|
||
|
{
|
||
|
if ((bool)instance)
|
||
|
{
|
||
|
instance.StartRun();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static bool AnyUserHasUnlockable([NotNull] UnlockableDef unlockableDef)
|
||
|
{
|
||
|
ReadOnlyCollection<NetworkUser> readOnlyInstancesList = NetworkUser.readOnlyInstancesList;
|
||
|
for (int i = 0; i < readOnlyInstancesList.Count; i++)
|
||
|
{
|
||
|
if (readOnlyInstancesList[i].unlockables.Contains(unlockableDef))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
[ContextMenu("RecalculateModifierAvailability")]
|
||
|
[Server]
|
||
|
public void RecalculateModifierAvailability()
|
||
|
{
|
||
|
if (!NetworkServer.active)
|
||
|
{
|
||
|
Debug.LogWarning("[Server] function 'System.Void RoR2.PreGameController::RecalculateModifierAvailability()' called on client");
|
||
|
return;
|
||
|
}
|
||
|
for (int i = 0; i < RuleCatalog.choiceCount; i++)
|
||
|
{
|
||
|
RuleChoiceDef choiceDef = RuleCatalog.GetChoiceDef(i);
|
||
|
unlockedChoiceMask[i] = !choiceDef.requiredUnlockable || AnyUserHasUnlockable(choiceDef.requiredUnlockable);
|
||
|
dependencyChoiceMask[i] = choiceDef.requiredChoiceDef == null || readOnlyRuleBook.IsChoiceActive(choiceDef.requiredChoiceDef);
|
||
|
entitlementChoiceMask[i] = !choiceDef.requiredEntitlementDef || EntitlementManager.networkUserEntitlementTracker.AnyUserHasEntitlement(choiceDef.requiredEntitlementDef) || EntitlementManager.localUserEntitlementTracker.AnyUserHasEntitlement(choiceDef.requiredEntitlementDef);
|
||
|
requiredExpansionEnabledChoiceMask[i] = !choiceDef.requiredExpansionDef || readOnlyRuleBook.IsChoiceActive(choiceDef.requiredExpansionDef.enabledChoice);
|
||
|
}
|
||
|
ResolveChoiceMask();
|
||
|
PreGameController.onServerRecalculatedModifierAvailability?.Invoke(this);
|
||
|
}
|
||
|
|
||
|
[Server]
|
||
|
private void ResolveChoiceMask()
|
||
|
{
|
||
|
if (!NetworkServer.active)
|
||
|
{
|
||
|
Debug.LogWarning("[Server] function 'System.Void RoR2.PreGameController::ResolveChoiceMask()' called on client");
|
||
|
return;
|
||
|
}
|
||
|
RuleChoiceMask ruleChoiceMask = new RuleChoiceMask();
|
||
|
RuleChoiceMask ruleChoiceMask2 = new RuleChoiceMask();
|
||
|
Run gameModePrefabComponent = GameModeCatalog.GetGameModePrefabComponent(gameModeIndex);
|
||
|
if ((bool)gameModePrefabComponent)
|
||
|
{
|
||
|
if (overrideRunSeed.value != -1)
|
||
|
{
|
||
|
runSeed = (ulong)overrideRunSeed.value;
|
||
|
}
|
||
|
gameModePrefabComponent.OverrideRuleChoices(ruleChoiceMask, ruleChoiceMask2, runSeed);
|
||
|
}
|
||
|
for (int i = 0; i < choiceMaskBuffer.length; i++)
|
||
|
{
|
||
|
RuleChoiceDef choiceDef = RuleCatalog.GetChoiceDef(i);
|
||
|
bool flag = ruleChoiceMask[i];
|
||
|
bool flag2 = ruleChoiceMask2[i];
|
||
|
bool flag3 = serverAvailableChoiceMask[i];
|
||
|
bool flag4 = unlockedChoiceMask[i];
|
||
|
bool flag5 = dependencyChoiceMask[i];
|
||
|
bool flag6 = entitlementChoiceMask[i];
|
||
|
bool flag7 = requiredExpansionEnabledChoiceMask[i];
|
||
|
choiceMaskBuffer[i] = flag || (!flag2 && flag3 && flag4 && flag5 && flag6 && flag7 && !choiceDef.excludeByDefault);
|
||
|
}
|
||
|
networkRuleChoiceMaskComponent.SetRuleChoiceMask(choiceMaskBuffer);
|
||
|
EnforceValidRuleChoices();
|
||
|
}
|
||
|
|
||
|
private void OnNetworkUserUnlockablesUpdatedCallback(NetworkUser networkUser)
|
||
|
{
|
||
|
if (NetworkServer.active)
|
||
|
{
|
||
|
RecalculateModifierAvailability();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void OnPostNetworkUserStartCallback(NetworkUser networkUser)
|
||
|
{
|
||
|
if (NetworkServer.active)
|
||
|
{
|
||
|
networkUser.ServerRequestUnlockables();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void OnNetworkUserBodyPreferenceChanged(NetworkUser networkUser)
|
||
|
{
|
||
|
if (NetworkServer.active)
|
||
|
{
|
||
|
RecalculateModifierAvailability();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void OnNetworkUserLost(NetworkUser networkUser)
|
||
|
{
|
||
|
if (NetworkServer.active)
|
||
|
{
|
||
|
RecalculateModifierAvailability();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void UpdateGameModeIndex(int newIndex)
|
||
|
{
|
||
|
if (newIndex != currentLobbyBackgroundGameModeIndex)
|
||
|
{
|
||
|
Network_gameModeIndex = newIndex;
|
||
|
RefreshLobbyBackground();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void UpdateMultiplayerPause(bool newBool)
|
||
|
{
|
||
|
if ((bool)PauseStopController.instance)
|
||
|
{
|
||
|
PauseStopController.instance.allowMultiplayerPause = newBool;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
[ClientRpc]
|
||
|
private void RpcUpdateGameModeIndex(int newIndex)
|
||
|
{
|
||
|
UpdateGameModeIndex(newIndex);
|
||
|
}
|
||
|
|
||
|
[ClientRpc]
|
||
|
private void RpcUpdateMultiplayerPause(bool newBool)
|
||
|
{
|
||
|
UpdateMultiplayerPause(newBool);
|
||
|
}
|
||
|
|
||
|
private void RefreshLobbyBackground()
|
||
|
{
|
||
|
if ((bool)lobbyBackground)
|
||
|
{
|
||
|
UnityEngine.Object.Destroy(lobbyBackground);
|
||
|
}
|
||
|
currentLobbyBackgroundGameModeIndex = _gameModeIndex;
|
||
|
lobbyBackground = UnityEngine.Object.Instantiate(GameModeCatalog.GetGameModePrefabComponent(gameModeIndex).lobbyBackgroundPrefab);
|
||
|
}
|
||
|
|
||
|
[ConCommand(commandName = "pregame_set_rule_choice", flags = ConVarFlags.SenderMustBeServer, helpText = "Sets the specified choice during pregame. See the command \"rule_list_choices\" for possible options.")]
|
||
|
public static void CCPregameSetRuleChoice(ConCommandArgs args)
|
||
|
{
|
||
|
string argString = args.GetArgString(0);
|
||
|
RuleChoiceDef ruleChoiceDef = RuleCatalog.FindChoiceDef(argString);
|
||
|
if (ruleChoiceDef == null)
|
||
|
{
|
||
|
throw new ConCommandException($"'{argString}' is not a recognized rule choice name.");
|
||
|
}
|
||
|
if (!instance)
|
||
|
{
|
||
|
throw new ConCommandException("This command cannot be issued outside the character select screen.");
|
||
|
}
|
||
|
if (instance.ApplyChoice(ruleChoiceDef.globalIndex))
|
||
|
{
|
||
|
instance.RecalculateModifierAvailability();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static PreGameController()
|
||
|
{
|
||
|
overrideRunSeed = new IntConVar("override_run_seed", ConVarFlags.None, "-1", "Forces a default seed for benchmarking.");
|
||
|
cvSvAllowRuleVoting = new BoolConVar("sv_allow_rule_voting", ConVarFlags.None, "1", "Whether or not players are allowed to vote on rules.");
|
||
|
cvSvAllowMultiplayerPause = new BoolConVar("sv_allow_multiplayer_pause", ConVarFlags.None, "0", "Whether or not players are allowed to pause the multiplayer game.");
|
||
|
kRpcRpcUpdateGameModeIndex = -600953683;
|
||
|
NetworkBehaviour.RegisterRpcDelegate(typeof(PreGameController), kRpcRpcUpdateGameModeIndex, InvokeRpcRpcUpdateGameModeIndex);
|
||
|
kRpcRpcUpdateMultiplayerPause = 2048931628;
|
||
|
NetworkBehaviour.RegisterRpcDelegate(typeof(PreGameController), kRpcRpcUpdateMultiplayerPause, InvokeRpcRpcUpdateMultiplayerPause);
|
||
|
NetworkCRC.RegisterBehaviour("PreGameController", 0);
|
||
|
}
|
||
|
|
||
|
private void UNetVersion()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
protected static void InvokeRpcRpcUpdateGameModeIndex(NetworkBehaviour obj, NetworkReader reader)
|
||
|
{
|
||
|
if (!NetworkClient.active)
|
||
|
{
|
||
|
Debug.LogError("RPC RpcUpdateGameModeIndex called on server.");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
((PreGameController)obj).RpcUpdateGameModeIndex((int)reader.ReadPackedUInt32());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected static void InvokeRpcRpcUpdateMultiplayerPause(NetworkBehaviour obj, NetworkReader reader)
|
||
|
{
|
||
|
if (!NetworkClient.active)
|
||
|
{
|
||
|
Debug.LogError("RPC RpcUpdateMultiplayerPause called on server.");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
((PreGameController)obj).RpcUpdateMultiplayerPause(reader.ReadBoolean());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void CallRpcUpdateGameModeIndex(int newIndex)
|
||
|
{
|
||
|
if (!NetworkServer.active)
|
||
|
{
|
||
|
Debug.LogError("RPC Function RpcUpdateGameModeIndex called on client.");
|
||
|
return;
|
||
|
}
|
||
|
NetworkWriter networkWriter = new NetworkWriter();
|
||
|
networkWriter.Write((short)0);
|
||
|
networkWriter.Write((short)2);
|
||
|
networkWriter.WritePackedUInt32((uint)kRpcRpcUpdateGameModeIndex);
|
||
|
networkWriter.Write(GetComponent<NetworkIdentity>().netId);
|
||
|
networkWriter.WritePackedUInt32((uint)newIndex);
|
||
|
SendRPCInternal(networkWriter, 0, "RpcUpdateGameModeIndex");
|
||
|
}
|
||
|
|
||
|
public void CallRpcUpdateMultiplayerPause(bool newBool)
|
||
|
{
|
||
|
if (!NetworkServer.active)
|
||
|
{
|
||
|
Debug.LogError("RPC Function RpcUpdateMultiplayerPause called on client.");
|
||
|
return;
|
||
|
}
|
||
|
NetworkWriter networkWriter = new NetworkWriter();
|
||
|
networkWriter.Write((short)0);
|
||
|
networkWriter.Write((short)2);
|
||
|
networkWriter.WritePackedUInt32((uint)kRpcRpcUpdateMultiplayerPause);
|
||
|
networkWriter.Write(GetComponent<NetworkIdentity>().netId);
|
||
|
networkWriter.Write(newBool);
|
||
|
SendRPCInternal(networkWriter, 0, "RpcUpdateMultiplayerPause");
|
||
|
}
|
||
|
|
||
|
public override bool OnSerialize(NetworkWriter writer, bool forceAll)
|
||
|
{
|
||
|
if (forceAll)
|
||
|
{
|
||
|
writer.WritePackedUInt32((uint)_gameModeIndex);
|
||
|
writer.WritePackedUInt32((uint)pregameStateInternal);
|
||
|
writer.Write(launchStartTime);
|
||
|
return true;
|
||
|
}
|
||
|
bool flag = false;
|
||
|
if ((base.syncVarDirtyBits & (true ? 1u : 0u)) != 0)
|
||
|
{
|
||
|
if (!flag)
|
||
|
{
|
||
|
writer.WritePackedUInt32(base.syncVarDirtyBits);
|
||
|
flag = true;
|
||
|
}
|
||
|
writer.WritePackedUInt32((uint)_gameModeIndex);
|
||
|
}
|
||
|
if ((base.syncVarDirtyBits & 2u) != 0)
|
||
|
{
|
||
|
if (!flag)
|
||
|
{
|
||
|
writer.WritePackedUInt32(base.syncVarDirtyBits);
|
||
|
flag = true;
|
||
|
}
|
||
|
writer.WritePackedUInt32((uint)pregameStateInternal);
|
||
|
}
|
||
|
if ((base.syncVarDirtyBits & 4u) != 0)
|
||
|
{
|
||
|
if (!flag)
|
||
|
{
|
||
|
writer.WritePackedUInt32(base.syncVarDirtyBits);
|
||
|
flag = true;
|
||
|
}
|
||
|
writer.Write(launchStartTime);
|
||
|
}
|
||
|
if (!flag)
|
||
|
{
|
||
|
writer.WritePackedUInt32(base.syncVarDirtyBits);
|
||
|
}
|
||
|
return flag;
|
||
|
}
|
||
|
|
||
|
public override void OnDeserialize(NetworkReader reader, bool initialState)
|
||
|
{
|
||
|
if (initialState)
|
||
|
{
|
||
|
_gameModeIndex = (int)reader.ReadPackedUInt32();
|
||
|
pregameStateInternal = (int)reader.ReadPackedUInt32();
|
||
|
launchStartTime = reader.ReadSingle();
|
||
|
return;
|
||
|
}
|
||
|
int num = (int)reader.ReadPackedUInt32();
|
||
|
if (((uint)num & (true ? 1u : 0u)) != 0)
|
||
|
{
|
||
|
UpdateGameModeIndex((int)reader.ReadPackedUInt32());
|
||
|
}
|
||
|
if (((uint)num & 2u) != 0)
|
||
|
{
|
||
|
pregameStateInternal = (int)reader.ReadPackedUInt32();
|
||
|
}
|
||
|
if (((uint)num & 4u) != 0)
|
||
|
{
|
||
|
launchStartTime = reader.ReadSingle();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public override void PreStartClient()
|
||
|
{
|
||
|
}
|
||
|
}
|