Skip to content

Commit

Permalink
Merge pull request #718 from starfi5h/pr-wip
Browse files Browse the repository at this point in the history
Sync extra texts in production statistics panel
  • Loading branch information
starfi5h authored Dec 6, 2024
2 parents 98a8fd4 + b953f67 commit d8fb4b5
Show file tree
Hide file tree
Showing 11 changed files with 370 additions and 33 deletions.
15 changes: 15 additions & 0 deletions NebulaModel/Packets/Statistics/StatisticsExtraDataPacket.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace NebulaModel.Packets.Statistics;

public class StatisticsExtraDataPacket
{
public StatisticsExtraDataPacket() { }

public StatisticsExtraDataPacket(int factoryCount, byte[] binaryData)
{
FactoryCount = factoryCount;
BinaryData = binaryData;
}

public int FactoryCount { get; set; }
public byte[] BinaryData { get; set; }
}
9 changes: 6 additions & 3 deletions NebulaModel/Packets/Statistics/StatisticsRequestEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,19 @@ public class StatisticsRequestEvent
{
public StatisticsRequestEvent() { }

public StatisticsRequestEvent(StatisticEvent Event)
public StatisticsRequestEvent(StatisticEvent statisticEvent, int astroFilter)
{
this.Event = Event;
Event = statisticEvent;
AstroFilter = astroFilter;
}

public StatisticEvent Event { get; set; }
public int AstroFilter { get; set; }
}

public enum StatisticEvent
{
WindowOpened = 1,
WindowClosed = 2
WindowClosed = 2,
AstroFilterChanged = 3
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#region

using System.IO;
using NebulaAPI.Packets;
using NebulaModel.Networking;
using NebulaModel.Packets;
using NebulaModel.Packets.Statistics;
using NebulaWorld;

#endregion

namespace NebulaNetwork.PacketProcessors.Statistics;

[RegisterPacketProcessor]
internal class StatisticsExtraDataProcessor : PacketProcessor<StatisticsExtraDataPacket>
{
protected override void ProcessPacket(StatisticsExtraDataPacket packet, NebulaConnection conn)
{
using var reader = new BinaryUtils.Reader(packet.BinaryData);
ImportExtension(reader.BinaryReader, packet.FactoryCount);
}

static void ImportExtension(BinaryReader reader, int factoryCount)
{
var factoryStatPool = GameMain.data.statistics.production.factoryStatPool;
for (var i = 0; i < factoryCount; i++)
{
var factoryIndex = reader.ReadInt32();
if (factoryIndex >= factoryStatPool.Length) return; // Abort if factoryProductionStat hasn't imported yet
var factoryProductionStat = factoryStatPool[factoryIndex];
ImportProductStatExtension(reader, factoryProductionStat);
}
}

static void ImportProductStatExtension(BinaryReader reader, FactoryProductionStat factoryProductionStat)
{
var productCursor = reader.ReadInt32();
for (var i = 1; i < productCursor; i++)
{
var itemId = reader.ReadInt32();
var refProductSpeed = reader.ReadSingle();
var refConsumeSpeed = reader.ReadSingle();
var storageCount = reader.ReadInt64();
var trashCount = reader.ReadInt64();
var importStorageCount = reader.ReadInt64();
var exportStorageCount = reader.ReadInt64();

if (factoryProductionStat == null) continue;
var index = factoryProductionStat.productIndices[itemId];
if (index == 0) continue;

var product = factoryProductionStat.productPool[index];
product.refProductSpeed = refProductSpeed;
product.refConsumeSpeed = refConsumeSpeed;
product.storageCount = storageCount;
product.trashCount = trashCount;
product.importStorageCount = importStorageCount;
product.exportStorageCount = exportStorageCount;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#region

using System;
using System.IO;
using NebulaAPI.GameState;
using NebulaAPI.Packets;
using NebulaModel.Networking;
using NebulaModel.Packets;
Expand All @@ -28,22 +26,100 @@ protected override void ProcessPacket(StatisticsRequestEvent packet, NebulaConne
{
return;
}
NebulaModel.Logger.Log.Debug($"{packet.Event} {packet.AstroFilter} player={player.Id}");
switch (packet.Event)
{
case StatisticEvent.WindowOpened:
{
Multiplayer.Session.Statistics.RegisterPlayer(conn, player.Id);

using var writer = new BinaryUtils.Writer();
Multiplayer.Session.Statistics.ExportAllData(writer.BinaryWriter);
conn.SendPacket(new StatisticsDataPacket(writer.CloseAndGetBytes()));
using (var writer = new BinaryUtils.Writer())
{
Multiplayer.Session.Statistics.ExportAllData(writer.BinaryWriter);
conn.SendPacket(new StatisticsDataPacket(writer.CloseAndGetBytes()));
}
SendExtraData(conn, packet.AstroFilter);
break;
}
case StatisticEvent.WindowClosed:
Multiplayer.Session.Statistics.UnRegisterPlayer(player.Id);
break;
default:
throw new ArgumentOutOfRangeException(nameof(packet), "Unknown event type: " + packet.Event);

case StatisticEvent.AstroFilterChanged:
SendExtraData(conn, packet.AstroFilter);
break;
}
}

static void SendExtraData(NebulaConnection conn, int astroFilter)
{
if (astroFilter == 0) return;
var window = UIRoot.instance.uiGame.statWindow;
var originalAstroFilter = window.astroFilter;
window.astroFilter = astroFilter;
window.RefreshItemsCyclicRefSpeed();
window.RefreshItemsStorageGroupCount();
window.RefreshGalacticTransportStorageCount();
window.astroFilter = originalAstroFilter;

using var writer = new BinaryUtils.Writer();
var factoryCount = ExportExtension(writer.BinaryWriter, astroFilter);
conn.SendPacket(new StatisticsExtraDataPacket(factoryCount, writer.CloseAndGetBytes()));
}

static int ExportExtension(BinaryWriter writer, int astroFilter)
{
var factoryStatPool = GameMain.data.statistics.production.factoryStatPool;
var factoryCount = 0;
if (astroFilter == -1)
{
for (var i = 0; i < GameMain.data.factoryCount; i++)
{
writer.Write(i);
ExportProductStatExtension(writer, factoryStatPool[i]);
factoryCount++;
}
}
else if (astroFilter % 100 == 0)
{
var star = GameMain.galaxy.StarById(astroFilter / 100);
if (star == null) return 0;
for (var i = 0; i < star.planetCount; i++)
{
var planet = star.planets[i];
if (planet?.factory != null)
{
var factoryIndex = planet.factoryIndex;
writer.Write(factoryIndex);
ExportProductStatExtension(writer, factoryStatPool[factoryIndex]);
factoryCount++;
}
}
}
else
{
var planet = GameMain.galaxy.PlanetById(astroFilter);
if (planet?.factory == null) return 0;
writer.Write(planet.factoryIndex);
ExportProductStatExtension(writer, factoryStatPool[planet.factoryIndex]);
factoryCount = 1;
}
return factoryCount;
}

static void ExportProductStatExtension(BinaryWriter writer, FactoryProductionStat factoryProductionStat)
{
writer.Write(factoryProductionStat.productCursor);
for (var i = 1; i < factoryProductionStat.productCursor; i++)
{
var product = factoryProductionStat.productPool[i];
writer.Write(product.itemId);
writer.Write(product.refProductSpeed);
writer.Write(product.refConsumeSpeed);
writer.Write(product.storageCount);
writer.Write(product.trashCount);
writer.Write(product.importStorageCount);
writer.Write(product.exportStorageCount);
}
}
}
10 changes: 0 additions & 10 deletions NebulaNetwork/Server.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ public class Server : IServer
public INetPacketProcessor PacketProcessor { get; set; } = new NebulaNetPacketProcessor();

private const float GAME_RESEARCH_UPDATE_INTERVAL = 2;
private const float STATISTICS_UPDATE_INTERVAL = 1;
private const float LAUNCH_UPDATE_INTERVAL = 4;
private const float DYSONSPHERE_UPDATE_INTERVAL = 2;
private const float WARNING_UPDATE_INTERVAL = 1;
Expand All @@ -54,8 +53,6 @@ public class Server : IServer

private float gameResearchHashUpdateTimer;
private NgrokManager ngrokManager;
private float productionStatisticsUpdateTimer;


private WebSocketServer socket;
private float warningUpdateTimer;
Expand Down Expand Up @@ -414,7 +411,6 @@ public void Update()
}

gameResearchHashUpdateTimer += Time.deltaTime;
productionStatisticsUpdateTimer += Time.deltaTime;
dysonLaunchUpateTimer += Time.deltaTime;
dysonSphereUpdateTimer += Time.deltaTime;
warningUpdateTimer += Time.deltaTime;
Expand All @@ -430,12 +426,6 @@ public void Update()
}
}

if (productionStatisticsUpdateTimer > STATISTICS_UPDATE_INTERVAL)
{
productionStatisticsUpdateTimer = 0;
Multiplayer.Session.Statistics.SendBroadcastIfNeeded();
}

if (dysonLaunchUpateTimer > LAUNCH_UPDATE_INTERVAL)
{
dysonLaunchUpateTimer = 0;
Expand Down
1 change: 1 addition & 0 deletions NebulaPatcher/Patches/Dynamic/GameData_Patch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ public static void GameTick_Postfix(long time)
if (Multiplayer.Session.LocalPlayer.IsHost)
{
Multiplayer.Session.Launch.CollectProjectile();
Multiplayer.Session.Statistics.SendBroadcastIfNeeded(time);
return;
}

Expand Down
37 changes: 37 additions & 0 deletions NebulaPatcher/Patches/Dynamic/UIProductEntry_Patch.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#region

using HarmonyLib;
using NebulaModel.Packets.Statistics;
using NebulaWorld;

#endregion

namespace NebulaPatcher.Patches.Dynamic;

[HarmonyPatch(typeof(UIProductEntry))]
internal class UIProductEntry_Patch
{
[HarmonyPrefix]
[HarmonyPatch(nameof(UIProductEntry.OnRefreshRefSpeedClick))]
[HarmonyPatch(nameof(UIProductEntry.OnRefreshStorageCountClick))]
public static void OnRefreshClick_Postfix()
{
if (!Multiplayer.IsActive || Multiplayer.Session.LocalPlayer.IsHost)
{
return;
}

// When client left-click the refresh button, request the extra data from server
var astroFilter = UIRoot.instance.uiGame.statWindow.astroFilter;
if (astroFilter == 0)
{
if (GameMain.localPlanet != null) return;
astroFilter = GameMain.localStar?.id ?? 0;
}
else if (GameMain.localPlanet != null && GameMain.localPlanet.astroId == astroFilter)
{
return; // For local planet, use the local calculation
}
Multiplayer.Session.Network.SendPacket(new StatisticsRequestEvent(StatisticEvent.AstroFilterChanged, astroFilter));
}
}
44 changes: 40 additions & 4 deletions NebulaPatcher/Patches/Dynamic/UIStatisticsWindow_Patch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,22 @@ namespace NebulaPatcher.Patches.Dynamic;
[HarmonyPatch(typeof(UIStatisticsWindow))]
internal class UIStatisticsWindow_Patch
{
[HarmonyPostfix]
[HarmonyPrefix]
[HarmonyPatch(nameof(UIStatisticsWindow._OnOpen))]
[SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Original Function Name")]
public static void _OnOpen_Postfix()
public static void _OnOpen_Postfix(UIStatisticsWindow __instance)
{
if (!Multiplayer.IsActive || Multiplayer.Session.LocalPlayer.IsHost)
{
return;
}
Multiplayer.Session.Statistics.IsStatisticsNeeded = true;
Multiplayer.Session.Network.SendPacket(new StatisticsRequestEvent(StatisticEvent.WindowOpened));
var astroFilter = __instance.astroFilter;
if (astroFilter == 0)
{
astroFilter = GameMain.localPlanet?.astroId ?? (GameMain.localStar?.id ?? 0);
}
Multiplayer.Session.Network.SendPacket(new StatisticsRequestEvent(StatisticEvent.WindowOpened, astroFilter));
}

[HarmonyPostfix]
Expand All @@ -36,7 +41,7 @@ public static void _OnClose_Postfix()
return;
}
Multiplayer.Session.Statistics.IsStatisticsNeeded = false;
Multiplayer.Session.Network.SendPacket(new StatisticsRequestEvent(StatisticEvent.WindowClosed));
Multiplayer.Session.Network.SendPacket(new StatisticsRequestEvent(StatisticEvent.WindowClosed, 0));
}

[HarmonyPrefix]
Expand All @@ -47,4 +52,35 @@ public static bool AddProductStatGroup_Prefix(int _factoryIndex, ProductionStati
//Skip when StatisticsDataPacket hasn't arrived yet
return _factoryIndex >= 0 && ___productionStat.factoryStatPool[_factoryIndex] != null;
}

[HarmonyPostfix]
[HarmonyPatch(nameof(UIStatisticsWindow.AstroBoxToValue))]
public static void AstroBoxToValue_Postfix(UIStatisticsWindow __instance)
{
if (!Multiplayer.IsActive || Multiplayer.Session.LocalPlayer.IsHost) return;

if (__instance.isStatisticsTab && __instance.lastAstroFilter != __instance.astroFilter)
{
if (__instance.astroFilter != 0)
{
Multiplayer.Session.Network.SendPacket(new StatisticsRequestEvent(StatisticEvent.AstroFilterChanged, __instance.astroFilter));
}
else if (GameMain.localPlanet == null && GameMain.localStar != null) // local star
{
Multiplayer.Session.Network.SendPacket(new StatisticsRequestEvent(StatisticEvent.AstroFilterChanged, GameMain.localStar.astroId));
}
}
}

[HarmonyPrefix]
[HarmonyPatch(nameof(UIStatisticsWindow.RefreshItemsCyclicRefSpeed))]
[HarmonyPatch(nameof(UIStatisticsWindow.RefreshItemsStorageGroupCount))]
[HarmonyPatch(nameof(UIStatisticsWindow.RefreshGalacticTransportStorageCount))]
public static bool Refresh_Prefix(UIStatisticsWindow __instance)
{
if (!Multiplayer.IsActive || Multiplayer.Session.LocalPlayer.IsHost) return true;

// Client: Only allow refresh on local planet. Otherwise use request to get data from server
return GameMain.localPlanet != null && (__instance.astroFilter == 0 || __instance.astroFilter == GameMain.data.localPlanet.id);
}
}
Loading

0 comments on commit d8fb4b5

Please sign in to comment.