Repository navigation
Expand file tree
/
Copy pathControllerHandler.cs
More file actions
144 lines (132 loc) · 5.11 KB
/
Copy pathControllerHandler.cs
File metadata and controls
144 lines (132 loc) · 5.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
using System;
using System.Collections;
using HarmonyLib;
using Hpmv;
using SuperchargedPatch.Extensions;
namespace SuperchargedPatch
{
public static class ControllerHandler
{
public static MultiplayerController MultiplayerController;
public static long CaptureCount, CaptureTicks, LastCaptureTicks;
public static void LateUpdate()
{
// Make sure to flush any network messages before capturing state. Normally this
// is done as part of MultiplayerController.LateUpdate(), but we're also executing in
// LateUpdate so the order is not deterministic.
MultiplayerController?.FlushAllPendingBatchedMessages();
// While paused, a missing RPC reply must not block Unity or create
// another accepted frame. Preserve native messages for the reply.
Hpmv.InputData pausedInput;
if (Helpers.IsPaused() && !Injector.Server.TryGetCurrentInput(out pausedInput))
{
Injector.Server.SkipPausedCallback();
return;
}
if (Helpers.IsPaused())
{
WarpHandler.HandleWarpRequestIfAny();
}
var data = Injector.Server.CurrentFrameData;
if (!Helpers.IsPaused())
{
if (Injector.Server.CurrentInput.__isset.nextFrame)
{
ActiveStateCollector.NotifyFrame(Injector.Server.CurrentInput.NextFrame);
}
}
long captureStart = System.Diagnostics.Stopwatch.GetTimestamp();
ActiveStateCollector.CollectDataForFrame(data);
LastCaptureTicks = System.Diagnostics.Stopwatch.GetTimestamp() - captureStart;
CaptureTicks += LastCaptureTicks;
CaptureCount++;
data.LastFramePaused = Helpers.IsPaused();
bool terminalPauseApplied = NativeRoundEndLatch.ApplyPendingPause();
if (!terminalPauseApplied)
{
if (Injector.Server.CurrentInput.RequestPause)
{
Helpers.Pause();
}
else if (Injector.Server.CurrentInput.RequestResume)
{
Helpers.Resume();
}
}
StateInvalidityManager.PreventInvalidState = Injector.Server.CurrentInput.PreventInvalidState;
data.NextFramePaused = TimeManager.IsPaused(TimeManager.PauseLayer.Main);
Injector.Server.CommitFrame();
NativeRoundEndLatch.CommitCapabilityPublication();
}
public static void FixedUpdate()
{
Injector.Server.CurrentFrameData.PhysicsFramesElapsed += 1;
}
public static void Update()
{
if (Injector.Server.CurrentFrameData.PhysicsFramesElapsed == 0)
{
FramesSinceLastNoPhysicsFrame = 0;
}
else
{
FramesSinceLastNoPhysicsFrame += 1;
}
Injector.Server.CurrentFrameData.FramesSinceLastNoPhysicsFrame = FramesSinceLastNoPhysicsFrame;
}
public static int FramesSinceLastNoPhysicsFrame = 0;
}
[HarmonyPatch(typeof(MultiplayerController), "Update")]
public static class MultiplayerControllerAwakePatch
{
public static void Postfix(MultiplayerController __instance)
{
// Do this, because FindObjectOfType is very very slow.
ControllerHandler.MultiplayerController = __instance;
}
}
[HarmonyPatch(typeof(ClientFlowControllerBase), "RunLevelIntro")]
public static class PatchClientFlowControllerBaseRunLevelIntro
{
[HarmonyPostfix]
public static void Postfix(ref IEnumerator __result)
{
__result = WaitForNoPhysicsFrame(__result);
}
private static IEnumerator WaitForNoPhysicsFrame(IEnumerator then)
{
for (int i = 0; ; i++)
{
yield return null;
if (Injector.Server.CurrentFrameData.PhysicsFramesElapsed == 0)
{
Console.WriteLine("Successfully started with non-physics frame after " + i + " tries");
break;
}
if (i == 6)
{
Console.WriteLine("Warning: FAILED TO WAIT FOR NO PHYSICS FRAME");
break;
}
}
while (then.MoveNext())
{
yield return then.Current;
}
yield break;
}
}
[HarmonyPatch(typeof(ServerFlowControllerBase), "ChangeGameState")]
public static class PatchServerFlowControllerBaseChangeGameState
{
[HarmonyPostfix]
public static void Postfix(ServerFlowControllerBase __instance, GameState state)
{
NativeRoundEndLatch.AfterServerStateChange(__instance, state);
if (state == GameState.InLevel)
{
Console.WriteLine("At game start, physics phase shift is " + ControllerHandler.FramesSinceLastNoPhysicsFrame);
}
}
}
}