-
Notifications
You must be signed in to change notification settings - Fork 1
/
ControllerHandler.cs
124 lines (113 loc) · 4.07 KB
/
ControllerHandler.cs
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
using System;
using System.Collections;
using HarmonyLib;
using Hpmv;
using SuperchargedPatch.Extensions;
namespace SuperchargedPatch
{
public static class ControllerHandler
{
public static MultiplayerController MultiplayerController;
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();
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);
}
}
ActiveStateCollector.CollectDataForFrame(data);
data.LastFramePaused = Helpers.IsPaused();
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();
}
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(GameState state)
{
if (state == GameState.InLevel)
{
Console.WriteLine("At game start, physics phase shift is " + ControllerHandler.FramesSinceLastNoPhysicsFrame);
}
}
}
}