Added AddTraderWithDynamicAssorts example
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<RootNamespace>_13._1AddTraderWithDynamicAssorts</RootNamespace>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputType>Library</OutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- TODO: Change to Nuget Package -->
|
||||
<ItemGroup>
|
||||
<Reference Include="Core">
|
||||
<HintPath>..\TempReferences\Core.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
<CopyLocal>false</CopyLocal>
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
</Reference>
|
||||
<Reference Include="SptCommon">
|
||||
<HintPath>..\TempReferences\SptCommon.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
<CopyLocal>false</CopyLocal>
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
</Reference>
|
||||
<Reference Include="SptDependencyInjection">
|
||||
<HintPath>..\TempReferences\SptDependencyInjection.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
<CopyLocal>false</CopyLocal>
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,184 @@
|
||||
using Core.Models.Common;
|
||||
using Core.Models.Eft.Common.Tables;
|
||||
using Core.Models.Spt.Config;
|
||||
using Core.Models.Spt.Server;
|
||||
using Core.Utils;
|
||||
|
||||
namespace _13._1AddTraderWithDynamicAssorts
|
||||
{
|
||||
public class AddTraderHelper
|
||||
{
|
||||
/**
|
||||
* Add record to trader config to set the refresh time of trader in seconds (default is 60 minutes)
|
||||
* @param traderConfig trader config to add our trader to
|
||||
* @param baseJson json file for trader (db/base.json)
|
||||
* @param refreshTimeSecondsMin How many seconds between trader stock refresh min time
|
||||
* @param refreshTimeSecondsMax How many seconds between trader stock refresh max time
|
||||
*/
|
||||
public void SetTraderUpdateTime(TraderConfig traderConfig, dynamic baseJson, int refreshTimeSecondsMin, int refreshTimeSecondsMax)
|
||||
{
|
||||
// Add refresh time in seconds to config
|
||||
var traderRefreshRecord = new UpdateTime
|
||||
{
|
||||
TraderId = baseJson.id,
|
||||
Seconds = new MinMax<int>(refreshTimeSecondsMin, refreshTimeSecondsMax)
|
||||
};
|
||||
|
||||
|
||||
traderConfig.UpdateTime.Add(traderRefreshRecord);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add our new trader to the database
|
||||
* @param traderDetailsToAdd trader details
|
||||
* @param tables database
|
||||
* @param jsonUtil json utility class
|
||||
*/
|
||||
public void AddTraderToDb(dynamic traderDetailsToAdd, DatabaseTables tables, JsonUtil jsonUtil, object assortJson)
|
||||
{
|
||||
// Create trader data ready to add to database
|
||||
var traderDataToAdd = new Trader
|
||||
{
|
||||
Assort =
|
||||
jsonUtil.Deserialize<TraderAssort>(
|
||||
jsonUtil.Serialize(assortJson)), // Deserialise/serialise creates a copy of the json
|
||||
Base =
|
||||
jsonUtil.Deserialize<TraderBase>(
|
||||
jsonUtil.Serialize(traderDetailsToAdd)), // Deserialise/serialise creates a copy of the json
|
||||
QuestAssort = new Dictionary<string, Dictionary<string, string>> // questassort is empty as trader has no assorts unlocked by quests
|
||||
{
|
||||
{ "Started", new Dictionary<string, string>() },
|
||||
{ "Success", new Dictionary<string, string>() },
|
||||
{ "Fail", new Dictionary<string, string>() }
|
||||
}
|
||||
};
|
||||
|
||||
// Add trader to trader table, key is the traders id
|
||||
tables.Traders.Add(traderDetailsToAdd._id, traderDataToAdd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add traders name/location/description to the locale table
|
||||
* @param baseJson json file for trader (db/base.json)
|
||||
* @param tables database tables
|
||||
* @param fullName Complete name of trader
|
||||
* @param firstName First name of trader
|
||||
* @param nickName Nickname of trader
|
||||
* @param location Location of trader (e.g. "Here in the cat shop")
|
||||
* @param description Description of trader
|
||||
*/
|
||||
public void AddTraderToLocales(dynamic baseJson, DatabaseTables tables, string fullName, string firstName, string nickName, string location, string description)
|
||||
{
|
||||
// For each language, add locale for the new trader
|
||||
var locales = tables.Locales.Global;
|
||||
|
||||
foreach (var (key, value) in locales) {
|
||||
value.Value[$"{baseJson._id} FullName"] = fullName;
|
||||
value.Value[$"{baseJson._id} FirstName"] = firstName;
|
||||
value.Value[$"{baseJson._id} Nickname"] = nickName;
|
||||
value.Value[$"{baseJson._id} Location"] = location;
|
||||
value.Value[$"{baseJson._id} Description"] = description;
|
||||
}
|
||||
}
|
||||
|
||||
public List<Item> CreateGlock()
|
||||
{
|
||||
// Create an array ready to hold weapon + all mods
|
||||
var glock = new List<Item>();
|
||||
|
||||
// Add the base first
|
||||
glock.Add(new Item { // Add the base weapon first
|
||||
Id =
|
||||
NewItemIds.GLOCK_BASE, // Ids matter, MUST BE UNIQUE See mod.ts for more details
|
||||
Template =
|
||||
"5a7ae0c351dfba0017554310", // This is the weapons tpl, found on: https://db.sp-tarkov.com/search
|
||||
});
|
||||
|
||||
// Add barrel
|
||||
glock.Add(new Item {
|
||||
Id =
|
||||
NewItemIds.GLOCK_BARREL,
|
||||
Template =
|
||||
"5a6b60158dc32e000a31138b",
|
||||
ParentId =
|
||||
NewItemIds.GLOCK_BASE, // This is a sub item, you need to define its parent its attached to / inserted into
|
||||
SlotId =
|
||||
"mod_barrel", // Required for mods, you need to define what 'slot' the mod will fill on the weapon
|
||||
});
|
||||
|
||||
// Add receiver
|
||||
glock.Add( new Item {
|
||||
Id =
|
||||
NewItemIds.GLOCK_RECIEVER,
|
||||
Template =
|
||||
"5a9685b1a2750c0032157104",
|
||||
ParentId =
|
||||
NewItemIds.GLOCK_BASE,
|
||||
SlotId =
|
||||
"mod_reciever",
|
||||
});
|
||||
|
||||
// Add compensator
|
||||
glock.Add(new Item {
|
||||
Id =
|
||||
NewItemIds.GLOCK_COMPENSATOR,
|
||||
Template =
|
||||
"5a7b32a2e899ef00135e345a",
|
||||
ParentId =
|
||||
NewItemIds.GLOCK_RECIEVER, // The parent of this mod is the receiver NOT weapon, be careful to get the correct parent
|
||||
SlotId =
|
||||
"mod_muzzle",
|
||||
});
|
||||
|
||||
// Add Pistol grip
|
||||
glock.Add(new Item {
|
||||
Id =
|
||||
NewItemIds.GLOCK_PISTOL_GRIP,
|
||||
Template =
|
||||
"5a7b4960e899ef197b331a2d",
|
||||
ParentId =
|
||||
NewItemIds.GLOCK_BASE,
|
||||
SlotId =
|
||||
"mod_pistol_grip",
|
||||
});
|
||||
|
||||
// Add front sight
|
||||
glock.Add(new Item {
|
||||
Id =
|
||||
NewItemIds.GLOCK_FRONT_SIGHT,
|
||||
Template =
|
||||
"5a6f5d528dc32e00094b97d9",
|
||||
ParentId =
|
||||
NewItemIds.GLOCK_RECIEVER,
|
||||
SlotId =
|
||||
"mod_sight_rear",
|
||||
});
|
||||
|
||||
// Add rear sight
|
||||
glock.Add(new Item {
|
||||
Id =
|
||||
NewItemIds.GLOCK_REAR_SIGHT,
|
||||
Template =
|
||||
"5a6f58f68dc32e000a311390",
|
||||
ParentId =
|
||||
NewItemIds.GLOCK_RECIEVER,
|
||||
SlotId =
|
||||
"mod_sight_front",
|
||||
});
|
||||
|
||||
// Add magazine
|
||||
glock.Add(new Item {
|
||||
Id =
|
||||
NewItemIds.GLOCK_MAGAZINE,
|
||||
Template =
|
||||
"630769c4962d0247b029dc60",
|
||||
ParentId =
|
||||
NewItemIds.GLOCK_BASE,
|
||||
SlotId =
|
||||
"mod_magazine",
|
||||
});
|
||||
|
||||
return glock;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
using Core.Models.Eft.Common.Tables;
|
||||
using Core.Models.Enums;
|
||||
using Core.Models.External;
|
||||
using Core.Models.Spt.Config;
|
||||
using Core.Models.Utils;
|
||||
using Core.Routers;
|
||||
using Core.Servers;
|
||||
using Core.Services;
|
||||
using Core.Utils;
|
||||
|
||||
namespace _13._1AddTraderWithDynamicAssorts
|
||||
{
|
||||
public class AddTraderWithDynamicAssorts : IPostDBLoadMod
|
||||
{
|
||||
private readonly ISptLogger<AddTraderWithDynamicAssorts> _logger;
|
||||
private readonly HashUtil _hashUtil;
|
||||
private readonly JsonUtil _jsonUtil;
|
||||
private readonly FileUtil _fileUtil;
|
||||
private readonly DatabaseService _databaseService;
|
||||
private readonly ImageRouter _imageRouter;
|
||||
private readonly ConfigServer _configServer;
|
||||
private readonly TraderConfig _traderConfig;
|
||||
private readonly RagfairConfig _ragfairConfig;
|
||||
|
||||
public AddTraderWithDynamicAssorts(
|
||||
ISptLogger<AddTraderWithDynamicAssorts> logger,
|
||||
HashUtil hashUtil,
|
||||
JsonUtil jsonUtil,
|
||||
FileUtil fileUtil,
|
||||
DatabaseService databaseService,
|
||||
ImageRouter imageRouter,
|
||||
ConfigServer configServer)
|
||||
{
|
||||
_logger = logger;
|
||||
_hashUtil = hashUtil;
|
||||
_jsonUtil = jsonUtil;
|
||||
_fileUtil = fileUtil;
|
||||
_databaseService = databaseService;
|
||||
_imageRouter = imageRouter;
|
||||
_configServer = configServer;
|
||||
|
||||
_traderConfig = _configServer.GetConfig<TraderConfig>();
|
||||
_ragfairConfig = _configServer.GetConfig<RagfairConfig>();
|
||||
}
|
||||
|
||||
public void PostDBLoad()
|
||||
{
|
||||
var traderImagePath = "./db/cat.jpg";
|
||||
|
||||
var baseJson = _fileUtil.ReadFile("./db/base.json");
|
||||
var traderBase = _jsonUtil.Deserialize<TraderBase>(baseJson);
|
||||
|
||||
// Create helper class and use it to register our traders image/icon + set its stock refresh time
|
||||
var addTraderHelper = new AddTraderHelper();
|
||||
_imageRouter.AddRoute(traderBase.Avatar.Replace(".jpg", ""), System.IO.Path.GetFullPath(traderImagePath));
|
||||
addTraderHelper.SetTraderUpdateTime(_traderConfig, traderBase, 3600, 4000);
|
||||
|
||||
// Add trader to flea market
|
||||
_ragfairConfig.Traders[traderBase.Id] = true;
|
||||
|
||||
// Get a reference to the database tables
|
||||
var tables = _databaseService.GetTables();
|
||||
|
||||
var fluentAssortCreator = new FluentTraderAssortCreator(_logger, _hashUtil);
|
||||
|
||||
// Add milk
|
||||
var milkAssort = fluentAssortCreator
|
||||
.CreateSingleAssortItem(ItemTpl.DRINK_PACK_OF_MILK)
|
||||
.AddStackCount(200)
|
||||
.AddBuyRestriction(10)
|
||||
.AddMoneyCost(Money.ROUBLES, 2000)
|
||||
.AddLoyaltyLevel(1)
|
||||
.Export(tables.Traders[traderBase.Id]);
|
||||
|
||||
// Add 3x bitcoin + salewa for milk barter
|
||||
fluentAssortCreator
|
||||
.CreateSingleAssortItem(ItemTpl.DRINK_PACK_OF_MILK)
|
||||
.AddStackCount(100)
|
||||
.AddBarterCost(ItemTpl.BARTER_PHYSICAL_BITCOIN, 3)
|
||||
.AddBarterCost(ItemTpl.MEDKIT_SALEWA_FIRST_AID_KIT, 1)
|
||||
.AddLoyaltyLevel(1)
|
||||
.Export(tables.Traders[traderBase.Id]);
|
||||
|
||||
|
||||
// Add glock as a money purchase
|
||||
fluentAssortCreator
|
||||
.CreateComplexAssortItem(addTraderHelper.CreateGlock())
|
||||
.AddUnlimitedStackCount()
|
||||
.AddMoneyCost(Money.ROUBLES, 20000)
|
||||
.AddBuyRestriction(3)
|
||||
.AddLoyaltyLevel(1)
|
||||
.Export(tables.Traders[traderBase.Id]);
|
||||
|
||||
// Add mp133 preset as a barter for mayonase
|
||||
fluentAssortCreator
|
||||
.CreateComplexAssortItem(tables.Globals.ItemPresets["584148f2245977598f1ad387"].Items) // Weapon preset id comes from globals.json
|
||||
.AddStackCount(200)
|
||||
.AddBarterCost(ItemTpl.FOOD_JAR_OF_DEVILDOG_MAYO, 1)
|
||||
.AddBuyRestriction(3)
|
||||
.AddLoyaltyLevel(1)
|
||||
.Export(tables.Traders[traderBase.Id]);
|
||||
|
||||
addTraderHelper.AddTraderToLocales(
|
||||
baseJson,
|
||||
_databaseService.GetTables(),
|
||||
traderBase.Name,
|
||||
"Cat",
|
||||
traderBase.Nickname,
|
||||
traderBase.Location,
|
||||
"This is the cat shop. Meow.");
|
||||
}
|
||||
}
|
||||
|
||||
public static class NewItemIds
|
||||
{
|
||||
public static string GLOCK_BASE = "66eeef3b2a166b73d2066a74";
|
||||
public static string GLOCK_BARREL = "66eeef3b2a166b73d2066a75";
|
||||
public static string GLOCK_RECIEVER = "66eeef3b2a166b73d2066a76";
|
||||
public static string GLOCK_COMPENSATOR = "66eeef3b2a166b73d2066a77";
|
||||
public static string GLOCK_PISTOL_GRIP = "66eeef3b2a166b73d2066a78";
|
||||
public static string GLOCK_REAR_SIGHT = "66eeef3b2a166b73d2066a79";
|
||||
public static string GLOCK_FRONT_SIGHT = "66eeef3b2a166b73d2066a7a";
|
||||
public static string GLOCK_MAGAZINE = "66eeef3b2a166b73d2066a7b";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
using Core.Models.Eft.Common.Tables;
|
||||
using Core.Models.Utils;
|
||||
using Core.Utils;
|
||||
|
||||
namespace _13._1AddTraderWithDynamicAssorts;
|
||||
|
||||
public class FluentTraderAssortCreator
|
||||
{
|
||||
private readonly ISptLogger<AddTraderWithDynamicAssorts> _logger;
|
||||
private readonly HashUtil _hashUtil;
|
||||
|
||||
private readonly List<Item> _itemsToSell = [];
|
||||
private readonly Dictionary<string, List<List<BarterScheme>>> _barterScheme = new();
|
||||
private readonly Dictionary<string, int> _loyaltyLevel = new();
|
||||
|
||||
public FluentTraderAssortCreator(
|
||||
ISptLogger<AddTraderWithDynamicAssorts> logger,
|
||||
HashUtil hashUtil)
|
||||
{
|
||||
_logger = logger;
|
||||
_hashUtil = hashUtil;
|
||||
}
|
||||
|
||||
public FluentTraderAssortCreator CreateSingleAssortItem(string itemTpl, string? itemId = null)
|
||||
{
|
||||
// Create item ready for insertion into assort table
|
||||
var newItemToAdd = new Item
|
||||
{
|
||||
Id = itemId ?? _hashUtil.Generate(),
|
||||
Template = itemTpl,
|
||||
ParentId = "hideout", // Should always be "hideout"
|
||||
SlotId = "hideout", // Should always be "hideout"
|
||||
Upd = new Upd
|
||||
{
|
||||
UnlimitedCount = false,
|
||||
StackObjectsCount = 100
|
||||
}
|
||||
};
|
||||
|
||||
_itemsToSell.Add(newItemToAdd);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public FluentTraderAssortCreator CreateComplexAssortItem(List<Item> items)
|
||||
{
|
||||
items[0].ParentId = "hideout";
|
||||
items[0].SlotId = "hideout";
|
||||
|
||||
items[0].Upd ??= new Upd();
|
||||
|
||||
items[0].Upd.UnlimitedCount = false;
|
||||
items[0].Upd.StackObjectsCount = 100;
|
||||
|
||||
_itemsToSell.AddRange(items);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public FluentTraderAssortCreator AddStackCount(int stackCount)
|
||||
{
|
||||
_itemsToSell[0].Upd.StackObjectsCount = stackCount;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public FluentTraderAssortCreator AddUnlimitedStackCount()
|
||||
{
|
||||
_itemsToSell[0].Upd.StackObjectsCount = 999999;
|
||||
_itemsToSell[0].Upd.UnlimitedCount = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public FluentTraderAssortCreator MakeStackCountUnlimited()
|
||||
{
|
||||
_itemsToSell[0].Upd.StackObjectsCount = 999999;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public FluentTraderAssortCreator AddBuyRestriction(int maxBuyLimit)
|
||||
{
|
||||
_itemsToSell[0].Upd.BuyRestrictionMax = maxBuyLimit;
|
||||
_itemsToSell[0].Upd.BuyRestrictionCurrent = 0;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public FluentTraderAssortCreator AddLoyaltyLevel(int level)
|
||||
{
|
||||
_loyaltyLevel[_itemsToSell[0].Id] = level;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public FluentTraderAssortCreator AddMoneyCost(string currencyType, int amount)
|
||||
{
|
||||
var dataToAdd = new BarterScheme
|
||||
{
|
||||
Count = amount,
|
||||
Template = currencyType
|
||||
};
|
||||
|
||||
_barterScheme.Add(_itemsToSell[0].Id, [[dataToAdd]]);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public FluentTraderAssortCreator AddBarterCost(string itemTpl, int count)
|
||||
{
|
||||
var sellableItemId = _itemsToSell[0].Id;
|
||||
|
||||
// No data at all, create
|
||||
if (_barterScheme.Count == 0)
|
||||
{
|
||||
var dataToAdd = new BarterScheme
|
||||
{
|
||||
Count = count,
|
||||
Template = itemTpl
|
||||
};
|
||||
|
||||
_barterScheme[sellableItemId] = [[dataToAdd]];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Item already exists, add to
|
||||
var existingData = _barterScheme[sellableItemId][0].FirstOrDefault(x => x.Template == itemTpl);
|
||||
if (existingData is not null)
|
||||
{
|
||||
// itemtpl already a barter for item, add to count
|
||||
existingData.Count += count;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No barter for item, add it fresh
|
||||
_barterScheme[sellableItemId][0].Add(new BarterScheme
|
||||
{
|
||||
Count = count,
|
||||
Template = itemTpl
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset objet ready for reuse
|
||||
* @returns
|
||||
*/
|
||||
public FluentTraderAssortCreator? Export(Trader data)
|
||||
{
|
||||
var itemBeingSoldId = _itemsToSell[0].Id;
|
||||
if (!data.Assort.Items.Exists(x => x.Id == itemBeingSoldId))
|
||||
{
|
||||
_logger.Error($"Unable to add complex item with item key: {_itemsToSell[0].Id}, key already used");
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
data.Assort.Items.AddRange(_itemsToSell);
|
||||
data.Assort.BarterScheme[itemBeingSoldId] = _barterScheme[itemBeingSoldId];
|
||||
data.Assort.LoyalLevelItems[itemBeingSoldId] = _loyaltyLevel[itemBeingSoldId];
|
||||
|
||||
_itemsToSell.Clear();
|
||||
_barterScheme.Clear();
|
||||
_loyaltyLevel.Clear();
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"Name": "13.1AddTraderWithDynamicAssorts",
|
||||
"Version": "1.0.0",
|
||||
"SptVersion": "~4.0",
|
||||
"LoadBefore": [],
|
||||
"LoadAfter": [],
|
||||
"IncompatibileMods": [],
|
||||
"Url": "https://github.com/sp-tarkov/server-csharp/tree/develop/ExampleMods/Mods",
|
||||
"IsBundleMod": false,
|
||||
"Author": "SPT",
|
||||
"Contributors": [],
|
||||
"Licence": "MIT"
|
||||
}
|
||||
@@ -38,6 +38,7 @@ EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "18.1CustomItemServiceLootBox", "18.1CustomItemServiceLootBox\18.1CustomItemServiceLootBox.csproj", "{B870C285-B435-4C40-89C4-0220D34CB9BE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "20CustomChatBot", "20CustomChatBot\20CustomChatBot.csproj", "{32271491-8CF1-4014-9A8E-E1EA22EA4292}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "13.1AddTraderWithDynamicAssorts", "13.1AddTraderWithDynamicAssorts\13.1AddTraderWithDynamicAssorts.csproj", "{9038FA64-E484-4549-9728-C50F12BBE643}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -117,6 +118,10 @@ Global
|
||||
{32271491-8CF1-4014-9A8E-E1EA22EA4292}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{32271491-8CF1-4014-9A8E-E1EA22EA4292}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{32271491-8CF1-4014-9A8E-E1EA22EA4292}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9038FA64-E484-4549-9728-C50F12BBE643}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9038FA64-E484-4549-9728-C50F12BBE643}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9038FA64-E484-4549-9728-C50F12BBE643}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9038FA64-E484-4549-9728-C50F12BBE643}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
Reference in New Issue
Block a user