Skip to content

Commit

Permalink
Fix sync soil sand count incorrect in client
Browse files Browse the repository at this point in the history
  • Loading branch information
starfi5h committed Apr 10, 2024
1 parent e7ed12a commit 3dc5fae
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,17 @@ public class PlayerSandCountProcessor : PacketProcessor<PlayerSandCount>
{
protected override void ProcessPacket(PlayerSandCount packet, NebulaConnection conn)
{
var player = GameMain.mainPlayer;
var originalSandCount = player.sandCount;

if (IsHost)
{
if (!packet.IsDelta)
{
// when receive update request, host UpdateSyncedSandCount and send to other players
GameMain.mainPlayer.SetSandCount(packet.SandCount);
}
// when receive update request, host UpdateSyncedSandCount and send to other players
player.SetSandCount(packet.IsDelta ? originalSandCount + packet.SandCount : packet.SandCount);
return;
}

// taken from Player.SetSandCount()
var player = GameMain.mainPlayer;
var originalSandCount = player.sandCount;
if (packet.IsDelta)
{
player.sandCount += packet.SandCount;
Expand Down
75 changes: 61 additions & 14 deletions NebulaPatcher/Patches/Dynamic/Player_Patch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,83 @@ namespace NebulaPatcher.Patches.Dynamic;
[HarmonyPatch(typeof(Player))]
internal class Player_Patch
{
[HarmonyPrefix]
[HarmonyPatch(nameof(Player.ExchangeSand))]
public static bool ExchangeSand_Prefix(Player __instance)
{
if (!Multiplayer.IsActive)
{
return true;
}

var gainedSand = 0;
for (var i = 0; i < __instance.package.size; i++)
{
if (__instance.package.grids[i].itemId == 1099) // 1099: enemy drop sand item
{
gainedSand += __instance.package.grids[i].count;
__instance.package.grids[i].itemId = 0;
__instance.package.grids[i].filter = 0;
__instance.package.grids[i].count = 0;
__instance.package.grids[i].inc = 0;
__instance.package.grids[i].stackSize = 0;
}
}

// Only call SetSandCount when there is sand change in client
if (gainedSand > 0)
{
if (Config.Options.SyncSoil && Multiplayer.Session.IsClient)
{
// Report to server to add sand in shared pool
Multiplayer.Session.Client.SendPacket(new PlayerSandCount(gainedSand, true));
}
else
{
__instance.SetSandCount(__instance.sandCount + gainedSand);
}
}
return false;
}


[HarmonyPrefix]
[HarmonyPatch(nameof(Player.SetSandCount))]
public static bool SetSandCount_Prefix(long newSandCount)
{
if (!Multiplayer.IsActive)
{
return true;
}

if (!Config.Options.SyncSoil)
{
return !Multiplayer.IsActive || Multiplayer.Session.Factories.PacketAuthor == Multiplayer.Session.LocalPlayer.Id ||
return Multiplayer.Session.Factories.PacketAuthor == Multiplayer.Session.LocalPlayer.Id ||
Multiplayer.Session.LocalPlayer.IsHost &&
Multiplayer.Session.Factories.PacketAuthor == NebulaModAPI.AUTHOR_NONE ||
!Multiplayer.Session.Factories.IsIncomingRequest.Value;
}

switch (Multiplayer.IsActive)
if (Multiplayer.Session.LocalPlayer.IsHost)
{
//Soil should be given in singleplayer or to the host who then syncs it back to all players.
case true when Multiplayer.Session.LocalPlayer.IsHost:
var deltaSandCount = (int)(newSandCount - GameMain.mainPlayer.sandCount);
if (deltaSandCount != 0)
{
UpdateSyncedSandCount(deltaSandCount);
Multiplayer.Session.Server.SendPacket(new PlayerSandCount(newSandCount));
}
break;
var deltaSandCount = (int)(newSandCount - GameMain.mainPlayer.sandCount);
if (deltaSandCount != 0)
{
UpdateSyncedSandCount(deltaSandCount);
Multiplayer.Session.Server.SendPacket(new PlayerSandCount(newSandCount));
}
}
else
{
//Or client that use reform tool
case true when GameMain.mainPlayer.controller.actionBuild.reformTool.drawing:
Multiplayer.Session.Network.SendPacket(new PlayerSandCount(newSandCount));
break;
if (GameMain.mainPlayer.controller.actionBuild.reformTool.drawing)
{
Multiplayer.Session.Client.SendPacket(new PlayerSandCount(newSandCount));
}
}

return !Multiplayer.IsActive || Multiplayer.Session.LocalPlayer.IsHost;
return Multiplayer.Session.LocalPlayer.IsHost;
//Soil should be given in singleplayer or to the player who is author of the "Build" request, or to the host if there is no author.
}

Expand Down

0 comments on commit 3dc5fae

Please sign in to comment.