Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 38 additions & 4 deletions SmithingPlus/Config/ConfigLoader.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using JetBrains.Annotations;
using Vintagestory.API.Client;
using Vintagestory.API.Common;
using Vintagestory.API.Server;

namespace SmithingPlus.Config;

Expand All @@ -15,7 +17,22 @@ public override double ExecuteOrder()
return 0.03;
}

public override void StartServerSide(ICoreServerAPI api)
{
SendConfigToClient(api);
}

public override void StartClientSide(ICoreClientAPI api)
{
ReadConfigFromServer(api);
}

public override void StartPre(ICoreAPI api)
{
LoadServerConfig(api);
}

private void LoadServerConfig(ICoreAPI api)
{
try
{
Expand All @@ -26,6 +43,9 @@ public override void StartPre(ICoreAPI api)
Mod.Logger.VerboseDebug("Config file not found, creating a new one...");
}

// Clamp and warn about issues in config.
VerifyConfig();

api.StoreModConfig(Config, ConfigName);
}
catch (Exception e)
Expand All @@ -35,19 +55,33 @@ public override void StartPre(ICoreAPI api)
}
}

public override void Start(ICoreAPI api)
public void SendConfigToClient(ICoreAPI api)
{
api.World.Config.SetBool("SmithingPlus_CanRepairForlornHopeEstoc", Config.CanRepairForlornHopeEstoc);
api.World.Config.SetBool("SmithingPlus_WorkableBits", Config.SmithWithBits || Config.EnableToolRecovery);

api.World.Config.SetBool("SmithingPlus_DynamicMoldUnits", Config.DynamicMoldUnits);
api.World.Config.SetFloat("SmithingPlus_CastToolDurabilityPenalty", Config.CastToolDurabilityPenalty);
api.World.Config.SetFloat("SmithingPlus_DurabilityPenaltyPerRepair", Config.DurabilityPenaltyPerRepair);
}

public void ReadConfigFromServer(ICoreAPI api)
{
Config.DynamicMoldUnits = api.World.Config.GetBool("SmithingPlus_DynamicMoldUnits");
Config.CastToolDurabilityPenalty = api.World.Config.GetFloat("SmithingPlus_CastToolDurabilityPenalty");
Config.DurabilityPenaltyPerRepair = api.World.Config.GetFloat("SmithingPlus_DurabilityPenaltyPerRepair");
}
Comment on lines +68 to +73
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's look at the ConfigLoader.cs file to see SendConfigToClient method and get full context
find . -name "ConfigLoader.cs" -type f

Repository: jayugg/SmithingPlus

Length of output: 100


🏁 Script executed:

# Look for the file and get its size
fd ConfigLoader.cs

Repository: jayugg/SmithingPlus

Length of output: 98


🏁 Script executed:

# Examine the ConfigLoader.cs file
cat -n SmithingPlus/Config/ConfigLoader.cs | head -100

Repository: jayugg/SmithingPlus

Length of output: 3865


🏁 Script executed:

# Search for SendConfigToClient method to see what values are sent
rg -n "SendConfigToClient" --type=cs -A 10 SmithingPlus/Config/ConfigLoader.cs

Repository: jayugg/SmithingPlus

Length of output: 1035


🏁 Script executed:

# Search for usage of ConfigLoader.Config properties on client side
rg -n "ConfigLoader\.Config\." --type=cs

Repository: jayugg/SmithingPlus

Length of output: 45


🏁 Script executed:

# Also search for direct Config property access patterns
rg -n "Config\.(CanRepairForlornHopeEstoc|SmithWithBits|EnableToolRecovery|DynamicMoldUnits|CastToolDurabilityPenalty|DurabilityPenaltyPerRepair|WorkableBits)" --type=cs

Repository: jayugg/SmithingPlus

Length of output: 2363


🏁 Script executed:

# Check if CanRepairForlornHopeEstoc is used anywhere on client side
rg -n "CanRepairForlornHopeEstoc" --type=cs

Repository: jayugg/SmithingPlus

Length of output: 314


🏁 Script executed:

# Search for how WorkableBits is used
rg -n "WorkableBits" --type=cs -B 2 -A 2

Repository: jayugg/SmithingPlus

Length of output: 588


Incomplete synchronization: read back all sent config values for consistency.

SendConfigToClient sends 5 values to world config (lines 60-65), but ReadConfigFromServer only reads back 3 of them:

  • ✅ Read back: DynamicMoldUnits, CastToolDurabilityPenalty, DurabilityPenaltyPerRepair
  • ❌ Not read back: CanRepairForlornHopeEstoc (line 60), WorkableBits (line 61)

While CanRepairForlornHopeEstoc and WorkableBits are not currently used on the client side, the missing synchronization creates inconsistency and violates the pattern established by the other config values. Since the server explicitly sends these values to the world config, they should be read back on the client to ensure the static Config object stays in sync with the server.

Add the missing properties to ReadConfigFromServer:

Suggested fix
 public void ReadConfigFromServer(ICoreAPI api)
 {
+    Config.CanRepairForlornHopeEstoc = api.World.Config.GetBool("SmithingPlus_CanRepairForlornHopeEstoc");
     Config.DynamicMoldUnits = api.World.Config.GetBool("SmithingPlus_DynamicMoldUnits");
     Config.CastToolDurabilityPenalty = api.World.Config.GetFloat("SmithingPlus_CastToolDurabilityPenalty");
     Config.DurabilityPenaltyPerRepair = api.World.Config.GetFloat("SmithingPlus_DurabilityPenaltyPerRepair");
 }

Note: WorkableBits is a computed value derived from SmithWithBits or EnableToolRecovery and does not need to be stored as a config property; it can be computed on demand when needed.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public void ReadConfigFromServer(ICoreAPI api)
{
Config.DynamicMoldUnits = api.World.Config.GetBool("SmithingPlus_DynamicMoldUnits");
Config.CastToolDurabilityPenalty = api.World.Config.GetFloat("SmithingPlus_CastToolDurabilityPenalty");
Config.DurabilityPenaltyPerRepair = api.World.Config.GetFloat("SmithingPlus_DurabilityPenaltyPerRepair");
}
public void ReadConfigFromServer(ICoreAPI api)
{
Config.CanRepairForlornHopeEstoc = api.World.Config.GetBool("SmithingPlus_CanRepairForlornHopeEstoc");
Config.DynamicMoldUnits = api.World.Config.GetBool("SmithingPlus_DynamicMoldUnits");
Config.CastToolDurabilityPenalty = api.World.Config.GetFloat("SmithingPlus_CastToolDurabilityPenalty");
Config.DurabilityPenaltyPerRepair = api.World.Config.GetFloat("SmithingPlus_DurabilityPenaltyPerRepair");
}
🤖 Prompt for AI Agents
In @SmithingPlus/Config/ConfigLoader.cs around lines 68 - 73,
ReadConfigFromServer currently reads only three of the five values that
SendConfigToClient writes; update ReadConfigFromServer to also read and assign
Config.CanRepairForlornHopeEstoc and Config.WorkableBits from api.World.Config
(use the same keys used in SendConfigToClient, e.g.,
"SmithingPlus_CanRepairForlornHopeEstoc" and "SmithingPlus_WorkableBits") so the
static Config stays in sync with the server; if WorkableBits is intended to be
computed on demand instead, then compute it where needed and still read
CanRepairForlornHopeEstoc here to preserve consistency.


private void VerifyConfig()
{
if (Config.BrokenToolVoxelPercent < 0.2)
Mod.Logger.Warning($"[{nameof(ConfigLoader)}] Config setting {nameof(Config.BrokenToolVoxelPercent)}" +
$"has a very low value, your broken tools well be almost or fully empty.");
;

if (Config.VoxelsPerBit is < 2 or > 3)
{
Mod.Logger.Warning($"[{nameof(ConfigLoader)}] Config setting {nameof(Config.VoxelsPerBit)}" +
$"requires a value between 2 and 3. Clamping value.");
;
Config.VoxelsPerBit = Math.Clamp(Config.VoxelsPerBit, 2, 3);
}
}
Expand All @@ -57,4 +91,4 @@ public override void Dispose()
Config = null;
base.Dispose();
}
}
}