Skip to content

Commit 09ba1cf

Browse files
authored
Merge pull request #520 from starfi5h/pr-pause
Change send and receive behaviors
2 parents 53bf264 + d4b7f03 commit 09ba1cf

25 files changed

+220
-52
lines changed

.github/scripts/thunderstore_bundle.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ function generateManifest() {
124124
`nebula-${apiPluginInfo.name}-${apiPluginInfo.version}`,
125125
"PhantomGamers-IlLine-1.0.0",
126126
"CommonAPI-CommonAPI-1.2.2",
127+
"starfi5h-BulletTime-1.2.0",
127128
],
128129
website_url: "https://github.com/hubastard/nebula"
129130
};

NebulaModel/Logger/Log.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ namespace NebulaModel.Logger
55
{
66
public static class Log
77
{
8+
public static string MessageInfo { get; private set; }
9+
810
private static ILogger logger;
911

1012
public static void Init(ILogger logger)
@@ -27,6 +29,7 @@ public static void Debug(object message)
2729
public static void Info(string message)
2830
{
2931
logger.LogInfo(message);
32+
MessageInfo = message;
3033
}
3134

3235
public static void Info(object message)

NebulaModel/Networking/NebulaConnection.cs

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using NebulaModel.Logger;
33
using NebulaModel.Networking.Serialization;
44
using System;
5+
using System.Collections.Generic;
56
using System.Net;
67
using WebSocketSharp;
78

@@ -12,6 +13,8 @@ public class NebulaConnection : INebulaConnection
1213
private readonly EndPoint peerEndpoint;
1314
private readonly WebSocket peerSocket;
1415
private readonly NetPacketProcessor packetProcessor;
16+
private readonly Queue<byte[]> pendingPackets = new Queue<byte[]>();
17+
private bool enable = true;
1518

1619
public bool IsAlive => peerSocket?.IsAlive ?? false;
1720

@@ -24,25 +27,46 @@ public NebulaConnection(WebSocket peerSocket, EndPoint peerEndpoint, NetPacketPr
2427

2528
public void SendPacket<T>(T packet) where T : class, new()
2629
{
27-
if (peerSocket.ReadyState == WebSocketState.Open)
30+
lock (pendingPackets)
2831
{
29-
peerSocket.Send(packetProcessor.Write(packet));
30-
}
31-
else
32-
{
33-
Log.Warn($"Cannot send packet {packet?.GetType()} to a closed connection {peerEndpoint}");
34-
}
32+
byte[] rawData = packetProcessor.Write(packet);
33+
pendingPackets.Enqueue(rawData);
34+
ProcessPacketQueue();
35+
}
3536
}
3637

3738
public void SendRawPacket(byte[] rawData)
3839
{
39-
if (peerSocket.ReadyState == WebSocketState.Open)
40+
lock (pendingPackets)
4041
{
41-
peerSocket.Send(rawData);
42+
pendingPackets.Enqueue(rawData);
43+
ProcessPacketQueue();
44+
}
45+
}
46+
47+
private void ProcessPacketQueue()
48+
{
49+
if (enable && pendingPackets.Count > 0)
50+
{
51+
byte[] packet = pendingPackets.Dequeue();
52+
if (peerSocket.ReadyState == WebSocketState.Open)
53+
{
54+
peerSocket.SendAsync(packet, OnSendCompleted);
55+
enable = false;
56+
}
57+
else
58+
{
59+
Log.Warn($"Cannot send packet to a {peerSocket.ReadyState} connection {peerEndpoint.GetHashCode()}");
60+
}
4261
}
43-
else
62+
}
63+
64+
private void OnSendCompleted(bool result)
65+
{
66+
lock (pendingPackets)
4467
{
45-
Log.Warn($"Cannot send raw packet to a closed connection {peerSocket?.Url}");
68+
enable = true;
69+
ProcessPacketQueue();
4670
}
4771
}
4872

NebulaModel/Networking/Serialization/NetPacketProcessor.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ private static class HashCache<T>
2626
public bool SimulateLatency = false;
2727
public int SimulatedMinLatency = 20;
2828
public int SimulatedMaxLatency = 50;
29+
public bool Enable { get; set; } = true;
2930

3031
public NetPacketProcessor()
3132
{
@@ -70,7 +71,7 @@ public void ProcessPacketQueue()
7071
{
7172
ProcessDelayedPackets();
7273

73-
while (pendingPackets.Count > 0)
74+
while (pendingPackets.Count > 0 && Enable)
7475
{
7576
PendingPacket packet = pendingPackets.Dequeue();
7677
ReadPacket(new NetDataReader(packet.Data), packet.UserData);

NebulaModel/Packets/Session/HandshakeRequest.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,17 @@ public HandshakeRequest(byte[] clientCert, string username, Float4[] mechaColors
3333
writer.BinaryWriter.Write(mod.Version);
3434
count++;
3535
}
36+
else
37+
{
38+
foreach (BepInEx.BepInDependency dependency in pluginInfo.Value.Dependencies)
39+
{
40+
if (dependency.DependencyGUID == NebulaModAPI.API_GUID)
41+
{
42+
writer.BinaryWriter.Write(pluginInfo.Key);
43+
writer.BinaryWriter.Write(pluginInfo.Value.Metadata.Version.ToString());
44+
}
45+
}
46+
}
3647
}
3748

3849
ModsVersion = writer.CloseAndGetBytes();

NebulaModel/Packets/Session/LobbyRequest.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@ public LobbyRequest(byte[] clientCert, string username, Float4[] mechaColors)
2828
writer.BinaryWriter.Write(mod.Version);
2929
count++;
3030
}
31+
else
32+
{
33+
foreach (BepInEx.BepInDependency dependency in pluginInfo.Value.Dependencies)
34+
{
35+
if (dependency.DependencyGUID == NebulaModAPI.API_GUID)
36+
{
37+
writer.BinaryWriter.Write(pluginInfo.Key);
38+
writer.BinaryWriter.Write(pluginInfo.Value.Metadata.Version.ToString());
39+
count++;
40+
}
41+
}
42+
}
3143
}
3244

3345
ModsVersion = writer.CloseAndGetBytes();

NebulaNetwork/Client.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,10 @@ public override void Update()
140140
gameStateUpdateTimer += Time.deltaTime;
141141
if (gameStateUpdateTimer >= GAME_STATE_UPDATE_INTERVAL)
142142
{
143-
SendPacket(new PingPacket());
143+
if (!GameMain.isFullscreenPaused)
144+
{
145+
SendPacket(new PingPacket());
146+
}
144147
gameStateUpdateTimer = 0f;
145148
}
146149
}

NebulaNetwork/PacketProcessors/GameStates/GameStateUpdateProcessor.cs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
using NebulaAPI;
22
using NebulaModel;
3-
using NebulaModel.DataStructures;
43
using NebulaModel.Logger;
54
using NebulaModel.Networking;
65
using NebulaModel.Packets;
76
using NebulaModel.Packets.GameStates;
87
using NebulaWorld;
8+
using NebulaWorld.GameStates;
99
using System;
1010
using UnityEngine;
1111

@@ -14,9 +14,13 @@ namespace NebulaNetwork.PacketProcessors.GameStates
1414
[RegisterPacketProcessor]
1515
public class GameStateUpdateProcessor : PacketProcessor<GameStateUpdate>
1616
{
17+
public float MaxUPS = 120f;
18+
public float MinUPS = 30f;
19+
public float BUFFERING_TIME = 30f;
20+
public float BUFFERING_TICK = 60f;
21+
1722
private int averageRTT;
1823
private float avaerageUPS = 60f;
19-
private const float BUFFERING_TIME = 20f;
2024
private bool hasChanged;
2125

2226
public override void ProcessPacket(GameStateUpdate packet, NebulaConnection conn)
@@ -64,23 +68,23 @@ public override void ProcessPacket(GameStateUpdate packet, NebulaConnection conn
6468
// Adjust client's UPS to match game tick with server, range 30~120 UPS
6569
float UPS = diff / 1f + avaerageUPS;
6670
long skipTick = 0;
67-
if (UPS > 120f)
71+
if (UPS > MaxUPS)
6872
{
6973
// Try to disturbute game tick difference into BUFFERING_TIME (seconds)
70-
if (diff / BUFFERING_TIME + avaerageUPS > 120f)
74+
if (diff / BUFFERING_TIME + avaerageUPS > MaxUPS)
7175
{
7276
// The difference is too large, need to skip ticks to catch up
73-
skipTick = (long)(UPS - 120f);
77+
skipTick = (long)(UPS - MaxUPS);
7478
}
75-
UPS = 120f;
79+
UPS = MaxUPS;
7680
}
77-
else if (UPS < 30f)
81+
else if (UPS < MinUPS)
7882
{
79-
if (diff / BUFFERING_TIME + avaerageUPS < 30f)
83+
if (diff + avaerageUPS - MinUPS < -BUFFERING_TICK)
8084
{
81-
skipTick = (long)(UPS - 30f);
85+
skipTick = (long)(UPS - MinUPS);
8286
}
83-
UPS = 30f;
87+
UPS = MinUPS;
8488
}
8589
if (skipTick != 0)
8690
{
@@ -89,6 +93,8 @@ public override void ProcessPacket(GameStateUpdate packet, NebulaConnection conn
8993
}
9094
FPSController.SetFixUPS(UPS);
9195
hasChanged = true;
96+
// Tick difference in the next second. Expose for other mods
97+
GameStatesManager.NotifyTickDifference((diff / 1f + avaerageUPS) - UPS);
9298
}
9399
}
94100
}

NebulaNetwork/PacketProcessors/Planet/FactoryDataProcessor.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using NebulaAPI;
2+
using NebulaModel.Logger;
23
using NebulaModel.Networking;
34
using NebulaModel.Packets;
45
using NebulaModel.Packets.Planet;
@@ -15,8 +16,13 @@ public override void ProcessPacket(FactoryData packet, NebulaConnection conn)
1516
{
1617
return;
1718
}
19+
// Stop packet processing until factory is imported
20+
((NebulaModel.NetworkProvider)Multiplayer.Session.Network).PacketProcessor.Enable = false;
21+
Log.Info($"FactoryDataProcessor: Pause PacketProcessor");
1822

23+
PlanetData planet = GameMain.galaxy.PlanetById(packet.PlanetId);
1924
Multiplayer.Session.Planets.PendingFactories.Add(packet.PlanetId, packet.BinaryData);
25+
Log.Info($"Parsing {packet.BinaryData.Length} bytes of data for factory {planet.name} (ID: {planet.id})");
2026

2127
lock (PlanetModelingManager.fctPlanetReqList)
2228
{

NebulaNetwork/PacketProcessors/Planet/FactoryLoadRequestProcessor.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using NebulaAPI;
2+
using NebulaModel.Logger;
23
using NebulaModel.Networking;
34
using NebulaModel.Packets;
45
using NebulaModel.Packets.Planet;
6+
using NebulaWorld;
57

68
namespace NebulaNetwork.PacketProcessors.Planet
79
{
@@ -21,7 +23,22 @@ public override void ProcessPacket(FactoryLoadRequest packet, NebulaConnection c
2123
using (BinaryUtils.Writer writer = new BinaryUtils.Writer())
2224
{
2325
factory.Export(writer.BinaryWriter);
24-
conn.SendPacket(new FactoryData(packet.PlanetID, writer.CloseAndGetBytes()));
26+
byte[] data = writer.CloseAndGetBytes();
27+
Log.Info($"Sent {data.Length} bytes of data for PlanetFactory {planet.name} (ID: {planet.id})");
28+
conn.SendPacket(new FactoryData(packet.PlanetID, data));
29+
}
30+
31+
// Add requesting client to connected player, so he can receive following update
32+
IPlayerManager playerManager = Multiplayer.Session.Network.PlayerManager;
33+
INebulaPlayer player = playerManager.GetSyncingPlayer(conn);
34+
if (player != null)
35+
{
36+
player.Data.LocalPlanetId = packet.PlanetID;
37+
player.Data.LocalStarId = GameMain.galaxy.PlanetById(packet.PlanetID).star.id;
38+
using (playerManager.GetConnectedPlayers(out System.Collections.Generic.Dictionary<INebulaConnection, INebulaPlayer> connectedPlayers))
39+
{
40+
connectedPlayers.Add(player.Connection, player);
41+
}
2542
}
2643
}
2744
}

0 commit comments

Comments
 (0)