Decompiled source of PricingExporter v1.0.0

PricingExporter.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using UnityEngine;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace PricingExporter;

[BepInPlugin("RB007.plugins.PricingExporter", "PricingExporter", "1.0.0")]
public class PricingExporterPlugin : BaseUnityPlugin
{
	private struct PricingEntry
	{
		public int productID;

		public string displayName;

		public string brand;

		public int productTier;

		public float unitCost;

		public float sellPrice;

		public float margin;

		public float recommendedPrice;
	}

	private const string GUID = "RB007.plugins.PricingExporter";

	private const string PluginName = "PricingExporter";

	private const string VersionString = "1.0.0";

	public static ConfigEntry<KeyCode> exportKey;

	public static ConfigEntry<float> targetMarginPercent;

	private void Awake()
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		exportKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Settings", "Export Key", (KeyCode)289, "按下这个键会把当前所有在售商品的定价导出为 CSV 文件。");
		targetMarginPercent = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Target Margin Percent", 20f, "计算推荐售价时,在进货成本基础上增加的百分比利润。");
		Debug.Log((object)string.Concat("[PricingExporter] Loaded successfully! Press ", exportKey.Value, " in-game to export pricing."));
	}

	private void Update()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		if (Input.GetKeyDown(exportKey.Value))
		{
			ExportPricingToCsv();
		}
	}

	private void ExportPricingToCsv()
	{
		ProductListing val = Object.FindFirstObjectByType<ProductListing>();
		if ((Object)(object)val == (Object)null)
		{
			Debug.LogWarning((object)"[PricingExporter] 尚未进入游戏存档,无法导出定价。");
			ShowNotification("StockPlus导出: 请先进入游戏存档");
			return;
		}
		try
		{
			List<PricingEntry> list = ComputePricingEntries(val);
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("商品ID,商品名称,品牌,产品等级,进货成本,当前售价,当前盈亏,状态,推荐不亏本售价(成本+" + targetMarginPercent.Value + "%)");
			foreach (PricingEntry item in list)
			{
				string text = ((!(item.margin < 0f)) ? "盈利" : "亏本");
				stringBuilder.AppendLine(item.productID + "," + CsvEscape(item.displayName) + "," + CsvEscape(item.brand) + "," + item.productTier + "," + item.unitCost.ToString("F2") + "," + item.sellPrice.ToString("F2") + "," + item.margin.ToString("F2") + "," + text + "," + item.recommendedPrice.ToString("F2"));
			}
			string text2 = Path.Combine(Paths.GameRootPath, "StockPlus_Exports");
			Directory.CreateDirectory(text2);
			string path = "定价表_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".csv";
			string text3 = Path.Combine(text2, path);
			File.WriteAllText(text3, stringBuilder.ToString(), new UTF8Encoding(encoderShouldEmitUTF8Identifier: true));
			Debug.Log((object)("[PricingExporter] 已导出 " + list.Count + " 件商品 -> " + text3));
			ShowNotification("已导出 " + list.Count + " 件商品定价表");
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[PricingExporter] 导出失败: " + ex));
			ShowNotification("StockPlus导出失败,详见日志");
		}
	}

	private List<PricingEntry> ComputePricingEntries(ProductListing plisting)
	{
		List<PricingEntry> list = new List<PricingEntry>();
		Type nestedType = typeof(ProductListing).GetNestedType("ProductData", BindingFlags.Public | BindingFlags.NonPublic);
		FieldInfo field = typeof(ProductListing).GetField("productsData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		FieldInfo field2 = nestedType.GetField("productTier");
		FieldInfo field3 = nestedType.GetField("basePricePerUnit");
		FieldInfo field4 = nestedType.GetField("productBrand");
		Array array = (Array)field.GetValue(plisting);
		foreach (int availableProduct in plisting.availableProducts)
		{
			if (availableProduct < 0 || availableProduct >= array.Length)
			{
				continue;
			}
			object value = array.GetValue(availableProduct);
			if (value == null)
			{
				continue;
			}
			int num = (int)field2.GetValue(value);
			if (!plisting.unlockedProductTiers[num])
			{
				continue;
			}
			float num2 = (float)field3.GetValue(value);
			string brand = ((!(field4 != null)) ? "" : ((string)field4.GetValue(value)));
			float num3 = num2 * plisting.tierInflation[num];
			float num4 = ((availableProduct >= plisting.productPlayerPricing.Length) ? 0f : plisting.productPlayerPricing[availableProduct]);
			float margin = num4 - num3;
			float num5 = num3 * (1f + targetMarginPercent.Value / 100f);
			num5 = Mathf.Round(num5 * 100f) / 100f;
			string displayName = "商品 #" + availableProduct;
			if ((Object)(object)LocalizationManager.instance != (Object)null)
			{
				string localizationString = LocalizationManager.instance.GetLocalizationString("product" + availableProduct);
				if (!string.IsNullOrEmpty(localizationString))
				{
					displayName = localizationString;
				}
			}
			list.Add(new PricingEntry
			{
				productID = availableProduct,
				displayName = displayName,
				brand = brand,
				productTier = num,
				unitCost = num3,
				sellPrice = num4,
				margin = margin,
				recommendedPrice = num5
			});
		}
		return list;
	}

	private static string CsvEscape(string value)
	{
		if (string.IsNullOrEmpty(value))
		{
			return "\"\"";
		}
		return "\"" + value.Replace("\"", "\"\"") + "\"";
	}

	private static void ShowNotification(string message)
	{
		try
		{
			if ((Object)(object)GameCanvas.Instance != (Object)null)
			{
				GameCanvas.Instance.CreateCanvasNotification(message);
			}
		}
		catch
		{
		}
	}
}