refactor(project): renamed project and namespace

This commit is contained in:
Yui
2025-11-04 16:32:31 -03:00
parent a4b2bf4bcf
commit 9e701275ec
11 changed files with 13 additions and 14 deletions

45
Server/Mod.cs Normal file
View File

@@ -0,0 +1,45 @@
using System.Diagnostics;
using System.Reflection;
using SPTarkov.DI.Annotations;
using SPTarkov.Server.Core.DI;
using SPTarkov.Server.Core.Models.Enums;
using SPTarkov.Server.Core.Models.Utils;
using SPTarkov.Server.Core.Services;
using WeebSights.Services;
namespace WeebSights;
[Injectable(TypePriority = OnLoadOrder.PostSptModLoader + 1)]
public class Mod(ISptLogger<Mod> logger,
WeebItemService weebItemService,
WeebTraderService weebTraderService,
WeebLocaleService weebLocaleService): IOnLoad
{
public Task OnLoad()
{
var stopWatch = Stopwatch.StartNew();
var currentAssemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
logger.Info($"[Weeb Iron Sights] Loaded in {currentAssemblyPath}");
if (!weebLocaleService.TryLoadLocales(Path.Join(currentAssemblyPath, "/db/locales/en.json"), out var locales))
{
logger.Error("[Weeb Iron Sights] Failed to load locales. Names might be weird");
}
if(!weebItemService.TryLoadConfig(Path.Join(currentAssemblyPath, "/db/items.jsonc"), out var items))
{
logger.Critical("[Weeb Iron Sights] Failed to load items. MOD WILL NOT LOAD");
stopWatch.Stop();
return Task.CompletedTask;
}
var resultItemCreation = weebItemService.GenerateItems(items, locales);
if (!weebTraderService.AddToAssortFromItemClone(Traders.MECHANIC, resultItemCreation))
{
logger.Critical("[Weeb Iron Sights] Failed to add items into Mechanic. Sights wont be available for purchase");
}
stopWatch.Stop();
logger.Success($"[Weeb Iron Sights] Loaded in {stopWatch.ElapsedMilliseconds} ms");
return Task.CompletedTask;
}
}

20
Server/ModMetadata.cs Normal file
View File

@@ -0,0 +1,20 @@
using SPTarkov.Server.Core.Models.Spt.Mod;
namespace WeebSights;
public record ModMetadata : AbstractModMetadata
{
public override string Name { get; init; } = "Weeb Iron Sights";
public override string Author { get; init; } = "yuyui.moe";
public override List<string>? Contributors { get; init; } = ["SamSWAT"];
public override SemanticVersioning.Version Version { get; init; } = new("1.0.0");
public override SemanticVersioning.Range SptVersion { get; init; } = new("~4.0.0");
public override List<string>? Incompatibilities { get; init; }
public override Dictionary<string, SemanticVersioning.Range>? ModDependencies { get; init; }
public override string? Url { get; init; }
public override bool? IsBundleMod { get; init; } = true;
public override string? License { get; init; } = "MIT";
public override string ModGuid { get; init; } = "moe.yuyui.animesights-port";
}

View File

@@ -0,0 +1,22 @@
using System.Text.Json.Serialization;
using SPTarkov.Server.Core.Models.Common;
namespace WeebSights.Models;
public record WeebItemConfig()
{
[JsonPropertyName("id")]
public MongoId Id { get; set; }
[JsonPropertyName("clone_from_tpl")]
public MongoId CloneFromTpl { get; set; }
[JsonPropertyName("bundle_path")]
public string BundlePath { get; set; }
[JsonPropertyName("price")]
public int Price { get; set; }
[JsonPropertyName("ergonomics")]
public int Ergonomics { get; set; }
}

View File

@@ -0,0 +1,16 @@
using System.Text.Json.Serialization;
using SPTarkov.Server.Core.Models.Common;
namespace WeebSights.Models;
public record WeebLocaleConfig()
{
[JsonPropertyName("name")]
public string Name { get; set; }
[JsonPropertyName("short_name")]
public string ShortName { get; set; }
[JsonPropertyName("description")]
public string Description { get; set; }
}

28
Server/Server.csproj Normal file
View File

@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>WeebSights</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SPTarkov.Server.Core" Version="4.0.3" />
</ItemGroup>
<ItemGroup>
<Content Include="bundles\**">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Update="bundles.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Content Include="db\**">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,121 @@
using SPTarkov.DI.Annotations;
using SPTarkov.Server.Core.DI;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
using SPTarkov.Server.Core.Models.Spt.Mod;
using SPTarkov.Server.Core.Models.Utils;
using SPTarkov.Server.Core.Services;
using SPTarkov.Server.Core.Services.Mod;
using SPTarkov.Server.Core.Utils;
using WeebSights.Models;
namespace WeebSights.Services;
[Injectable(TypePriority = OnLoadOrder.PostDBModLoader + 3)]
public class WeebItemService(ISptLogger<WeebItemService> logger, JsonUtil jsonUtil, CustomItemService customItemService, DatabaseService databaseService)
{
public bool TryLoadConfig(string filePath, out List<WeebItemConfig> outputObject)
{
var json = LoadConfig(filePath);
if (json is null)
{
outputObject = [];
return false;
}
outputObject = json;
return true;
}
public List<WeebItemConfig>? LoadConfig(string filePath)
{
return jsonUtil.DeserializeFromFile<List<WeebItemConfig>>(filePath);
}
public void AddIronSightToFilters(WeebItemConfig sight)
{
var itemsWithSlots = databaseService.GetTemplates().Items.Where(i => i.Value.Properties?.Slots?.Count() > 0);
foreach (var item in itemsWithSlots)
{
var backIronSightSlot = item.Value.Properties?.Slots?.FirstOrDefault(s => s.Name == "mod_sight_rear");
if (backIronSightSlot == null)
{
continue;
}
var slotFilter = backIronSightSlot?.Properties?.Filters?.FirstOrDefault(f => f.Filter?.Contains(sight.CloneFromTpl) ?? false);
if (slotFilter == null)
{
continue;
}
if (slotFilter.Filter?.Add(sight.Id) is false)
{
logger.Error("[Weeb Iron Sights] Failed to add filter to item " + item.Key);
continue;
}
logger.Success($"[Weeb Iron Sights] Added {sight.Id} to filter on item {item.Key}");
}
}
public IEnumerable<CreateItemResult> GenerateItems(List<WeebItemConfig> items, Dictionary<MongoId, WeebLocaleConfig> locales)
{
if (items.Count == 0)
{
yield break;
}
foreach (var item in items)
{
if (!locales.TryGetValue(item.Id, out var localeConfig))
{
logger.Error($"[Weeb Iron Sights] Failed to load locale for {item.Id}, using IDs for name");
localeConfig = new WeebLocaleConfig()
{
Name = item.Id,
Description = "FAILED TO LOAD LOCALES",
ShortName = "WEEBSIGHT",
};
}
NewItemFromCloneDetails clonedItem = new()
{
NewId = item.Id,
ItemTplToClone = item.CloneFromTpl,
ParentId = "55818ac54bdc2d5b648b456e", // Ironsight
HandbookParentId = "5b5f746686f77447ec5d7708", // CATEGORY
HandbookPriceRoubles = item.Price,
OverrideProperties = new TemplateItemProperties()
{
Ergonomics = item.Ergonomics,
CreditsPrice = item.Price,
Prefab = new Prefab()
{
Path = item.BundlePath
},
},
Locales = new Dictionary<string, LocaleDetails>
{
{
"en", new LocaleDetails()
{
Name = localeConfig.Name,
ShortName = localeConfig.ShortName,
Description = localeConfig.Description,
}
}
}
};
var itemCreation = customItemService.CreateItemFromClone(clonedItem);
if (itemCreation.Success is false or null)
{
logger.Error($"[Weeb Iron Sights] Failed to clone item {item.CloneFromTpl} into {item.Id}");
itemCreation.Errors?.ForEach(e => logger.Critical("[Weeb Iron Sights] " + e));
continue;
}
AddIronSightToFilters(item);
yield return itemCreation;
}
}
}

View File

@@ -0,0 +1,29 @@
using SPTarkov.DI.Annotations;
using SPTarkov.Server.Core.DI;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Utils;
using WeebSights.Models;
namespace WeebSights.Services;
[Injectable(TypePriority = OnLoadOrder.PostDBModLoader + 4)]
public class WeebLocaleService(JsonUtil jsonUtil)
{
public bool TryLoadLocales(string filePath, out Dictionary<MongoId, WeebLocaleConfig> outputObject)
{
var json = LoadLocales(filePath);
if (json == null)
{
outputObject = new Dictionary<MongoId, WeebLocaleConfig>();
return false;
}
outputObject = json;
return true;
}
public Dictionary<MongoId, WeebLocaleConfig>? LoadLocales(string filePath)
{
return jsonUtil.DeserializeFromFile<Dictionary<MongoId, WeebLocaleConfig>>(filePath);
}
}

View File

@@ -0,0 +1,60 @@
using SPTarkov.DI.Annotations;
using SPTarkov.Server.Core.DI;
using SPTarkov.Server.Core.Extensions;
using SPTarkov.Server.Core.Models.Common;
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
using SPTarkov.Server.Core.Models.Enums;
using SPTarkov.Server.Core.Models.Spt.Mod;
using SPTarkov.Server.Core.Models.Utils;
using SPTarkov.Server.Core.Services;
namespace WeebSights.Services;
[Injectable(TypePriority = OnLoadOrder.PostDBModLoader + 2)]
public class WeebTraderService(ISptLogger<WeebTraderService> logger, DatabaseService databaseService)
{
public bool AddToAssortFromItemClone(MongoId traderId, IEnumerable<CreateItemResult> itemCloneResults)
{
if (!databaseService.GetTables().Traders.TryGetValue(traderId, out var trader))
{
logger.Error($"[Weeb Iron Sights] Failed to find trader with ID {traderId}");
return false;
}
foreach (var itemResult in itemCloneResults)
{
var item = databaseService.GetItems().FirstOrDefault(i => i.Key == itemResult.ItemId);
var traderItem = GenerateItemForTrader(item);
var traderBarter = new BarterScheme()
{
Count = item.Value.Properties?.CreditsPrice ?? 1,
Template = CurrencyType.RUB.GetCurrencyTpl()
};
trader.Assort.Items.Add(traderItem);
if (!trader.Assort.BarterScheme.TryAdd(item.Key, [[traderBarter]]))
{
logger.Error($"[Weeb Iron Sights] Failed to add barter for item {item.Value.Name} with ID {item.Value.Id} in MECHANIC");
}
logger.Success($"[Weeb Iron Sights] Added item {item.Value.Name} with ID {item.Value.Id} to MECHANIC");
}
return true;
}
private Item GenerateItemForTrader(KeyValuePair<MongoId, TemplateItem> databaseItem)
{
return new Item
{
Id = databaseItem.Key,
Template = databaseItem.Value.Id,
ParentId = "hideout",
SlotId = "hideout",
Upd = new Upd()
{
UnlimitedCount = true,
StackObjectsCount = 99999,
}
};
}
}

143
Server/db/items.jsonc Normal file
View File

@@ -0,0 +1,143 @@
[
{
"id": "6753d006cec7fc449f055445",
"clone_from_tpl": "5bc09a18d4351e003562b68e", //IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT
"bundle_path": "assets/content/items/mods/sights rear/sight_rear_all_magpul_mbus_anti.bundle",
"price": 4000,
"ergonomics": 3
},
{
"id": "6753d006cec7fc449f05544a",
"clone_from_tpl": "5bc09a18d4351e003562b68e", //IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT
"bundle_path": "assets/content/items/mods/sights rear/sight_rear_all_magpul_mbus_gen2_anti2.bundle",
"price": 4000,
"ergonomics": 3
},
{
"id": "6753d006cec7fc449f055450",
"clone_from_tpl": "5bc09a18d4351e003562b68e", //IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT
"bundle_path": "assets/content/items/mods/sights rear/sight_rear_all_magpul_mbus_gen2_fde_anti.bundle",
"price": 4000,
"ergonomics": 3
},
{
"id": "6753d006cec7fc449f055451",
"clone_from_tpl": "5bc09a18d4351e003562b68e", //IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT
"bundle_path": "assets/content/items/mods/sights rear/sight_rear_all_magpul_mbus_gen2_fde_anti2.bundle",
"price": 4000,
"ergonomics": 3
},
{
"id": "6753d006cec7fc449f055446",
"clone_from_tpl": "5bc09a18d4351e003562b68e", //IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT
"bundle_path": "assets/content/items/mods/sights rear/sight_rear_all_magpul_mbus_gen2_anime.bundle",
"price": 4000,
"ergonomics": 3
},
{
"id": "6753d006cec7fc449f055447",
"clone_from_tpl": "5bc09a18d4351e003562b68e", //IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT
"bundle_path": "assets/content/items/mods/sights rear/sight_rear_all_magpul_mbus_gen2_anime2.bundle",
"price": 4000,
"ergonomics": 3
},
{
"id": "6753d006cec7fc449f05544d",
"clone_from_tpl": "5bc09a18d4351e003562b68e", //IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT
"bundle_path": "assets/content/items/mods/sights rear/sight_rear_all_magpul_mbus_gen2_fde_anime2.bundle",
"price": 4000,
"ergonomics": 3
},
{
"id": "6753d006cec7fc449f055448",
"clone_from_tpl": "5bc09a18d4351e003562b68e", //IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT
"bundle_path": "assets/content/items/mods/sights rear/sight_rear_all_magpul_mbus_gen2_anime3.bundle",
"price": 4000,
"ergonomics": 3
},
{
"id": "6753d006cec7fc449f05544e",
"clone_from_tpl": "5bc09a18d4351e003562b68e", //IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT
"bundle_path": "assets/content/items/mods/sights rear/sight_rear_all_magpul_mbus_gen2_fde_anime3.bundle",
"price": 4000,
"ergonomics": 3
},
{
"id": "6753d006cec7fc449f055449",
"clone_from_tpl": "5bc09a18d4351e003562b68e", //IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT
"bundle_path": "assets/content/items/mods/sights rear/sight_rear_all_magpul_mbus_gen2_anime3v2.bundle",
"price": 4000,
"ergonomics": 3
},
{
"id": "6753d006cec7fc449f05544f",
"clone_from_tpl": "5bc09a18d4351e003562b68e", //IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT
"bundle_path": "assets/content/items/mods/sights rear/sight_rear_all_magpul_mbus_gen2_fde_anime3v2.bundle",
"price": 4000,
"ergonomics": 3
},
{
"id": "6753d006cec7fc449f05544b",
"clone_from_tpl": "5bc09a18d4351e003562b68e", //IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT
"bundle_path": "assets/content/items/mods/sights rear/sight_rear_all_magpul_mbus_gen2_ramrem.bundle",
"price": 4000,
"ergonomics": 3
},
{
"id": "6753d006cec7fc449f055452",
"clone_from_tpl": "5bc09a18d4351e003562b68e", //IRONSIGHT_MAGPUL_MBUS_GEN2_FLIPUP_REAR_SIGHT
"bundle_path": "assets/content/items/mods/sights rear/sight_rear_all_magpul_mbus_gen2_fde_ramrem.bundle",
"price": 4000,
"ergonomics": 3
},
{
"id": "6753d006cec7fc449f055453",
"clone_from_tpl": "5fc0fa957283c4046c58147e", //IRONSIGHT_MCX_FLIPUP_REAR_SIGHT
"bundle_path": "assets/content/items/mods/sights rear/sight_rear_all_sig_flip_up_anime.bundle",
"price": 4000,
"ergonomics": 3
},
{
"id": "6753d006cec7fc449f055454",
"clone_from_tpl": "5fc0fa957283c4046c58147e", //IRONSIGHT_MCX_FLIPUP_REAR_SIGHT
"bundle_path": "assets/content/items/mods/sights rear/sight_rear_all_sig_flip_up_anime2.bundle",
"price": 4000,
"ergonomics": 3
},
{
"id": "6753d006cec7fc449f055455",
"clone_from_tpl": "5fc0fa957283c4046c58147e", //IRONSIGHT_MCX_FLIPUP_REAR_SIGHT
"bundle_path": "assets/content/items/mods/sights rear/sight_rear_all_sig_flip_up_anime3.bundle",
"price": 4000,
"ergonomics": 3
},
{
"id": "6753d006cec7fc449f055456",
"clone_from_tpl": "5fc0fa957283c4046c58147e", //IRONSIGHT_MCX_FLIPUP_REAR_SIGHT
"bundle_path": "assets/content/items/mods/sights rear/sight_rear_all_sig_flip_up_anime3v2.bundle",
"price": 4000,
"ergonomics": 3
},
{
"id": "6753d006cec7fc449f055457",
"clone_from_tpl": "5fc0fa957283c4046c58147e", //IRONSIGHT_MCX_FLIPUP_REAR_SIGHT
"bundle_path": "assets/content/items/mods/sights rear/sight_rear_all_sig_flip_up_anti.bundle",
"price": 4000,
"ergonomics": 3
},
{
"id": "6753d006cec7fc449f055458",
"clone_from_tpl": "5fc0fa957283c4046c58147e", //IRONSIGHT_MCX_FLIPUP_REAR_SIGHT
"bundle_path": "assets/content/items/mods/sights rear/sight_rear_all_sig_flip_up_anti2.bundle",
"price": 4000,
"ergonomics": 3
},
{
"id": "6753d006cec7fc449f055459",
"clone_from_tpl": "5fc0fa957283c4046c58147e", //IRONSIGHT_MCX_FLIPUP_REAR_SIGHT
"bundle_path": "assets/content/items/mods/sights rear/sight_rear_all_sig_flip_up_ramrem.bundle",
"price": 4000,
"ergonomics": 3
}
]

107
Server/db/locales/en.json Normal file
View File

@@ -0,0 +1,107 @@
{
"6753d006cec7fc449f055445": {
"name": "Magpul MBUS Gen2 rear flip-up sight [Anti]",
"short_name": "MBUS RS",
"description": "Removable flip-up rear sight MBUS Gen2, installed on the mount. Manufactured by Magpul. Your personal waifu giving her neko love to support you in combat."
},
"6753d006cec7fc449f055446": {
"name": "Magpul MBUS Gen2 rear flip-up sight [Ai Fuyuumi]",
"short_name": "MBUS RS",
"description": "Removable flip-up rear sight MBUS Gen2, installed on the mount. Manufactured by Magpul."
},
"6753d006cec7fc449f055447": {
"name": "Magpul MBUS Gen2 rear flip-up sight [GF M4 SOPMOD II]",
"short_name": "MBUS RS",
"description": "Removable flip-up rear sight MBUS Gen2, installed on the mount. Manufactured by Magpul."
},
"6753d006cec7fc449f055448": {
"name": "Magpul MBUS Gen2 rear flip-up sight [Animu 3]",
"short_name": "MBUS RS",
"description": "Removable flip-up rear sight MBUS Gen2, installed on the mount. Manufactured by Magpul."
},
"6753d006cec7fc449f055449": {
"name": "Magpul MBUS Gen2 rear flip-up sight [Animu 3 v2]",
"short_name": "MBUS RS",
"description": "Removable flip-up rear sight MBUS Gen2, installed on the mount. Manufactured by Magpul."
},
"6753d006cec7fc449f05544a": {
"name": "Magpul MBUS Gen2 rear flip-up sight [Anti 2]",
"short_name": "MBUS RS",
"description": "Removable flip-up rear sight MBUS Gen2, installed on the mount. Manufactured by Magpul. The personal sight used by Anti, the war Neko! Nya!!"
},
"6753d006cec7fc449f05544b": {
"name": "Magpul MBUS Gen2 rear flip-up sight [Ram & Rem]",
"short_name": "MBUS RS",
"description": "Removable flip-up rear sight MBUS Gen2, installed on the mount. Manufactured by Magpul."
},
"6753d006cec7fc449f05544c": {
"name": "Magpul MBUS Gen2 rear flip-up sight (FDE) [Ai Fuyuumi]",
"short_name": "MBUS RS",
"description": "Removable flip-up rear sight MBUS Gen2, installed on the mount. Manufactured by Magpul. Flat Dark Earth color."
},
"6753d006cec7fc449f05544d": {
"name": "Magpul MBUS Gen2 rear flip-up sight (FDE) [GF M4 SOPMOD II]",
"short_name": "MBUS RS",
"description": "Removable flip-up rear sight MBUS Gen2, installed on the mount. Manufactured by Magpul. Flat Dark Earth color."
},
"6753d006cec7fc449f05544e": {
"name": "Magpul MBUS Gen2 rear flip-up sight (FDE) [Animu 3]",
"short_name": "MBUS RS",
"description": "Removable flip-up rear sight MBUS Gen2, installed on the mount. Manufactured by Magpul. Flat Dark Earth color."
},
"6753d006cec7fc449f05544f": {
"name": "Magpul MBUS Gen2 rear flip-up sight (FDE) [Animu 3 v2]",
"short_name": "MBUS RS",
"description": "Removable flip-up rear sight MBUS Gen2, installed on the mount. Manufactured by Magpul. Flat Dark Earth color."
},
"6753d006cec7fc449f055450": {
"name": "Magpul MBUS Gen2 rear flip-up sight (FDE) [Anti]",
"short_name": "MBUS RS",
"description": "Removable flip-up rear sight MBUS Gen2, installed on the mount. Manufactured by Magpul. Flat Dark Earth color. Your personal waifu giving her neko love to support you in combat."
},
"6753d006cec7fc449f055451": {
"name": "Magpul MBUS Gen2 rear flip-up sight (FDE) [Anti 2]",
"short_name": "MBUS RS",
"description": "Removable flip-up rear sight MBUS Gen2, installed on the mount. Manufactured by Magpul. Flat Dark Earth color. The personal sight used by Anti, the war Neko! Nya!!"
},
"6753d006cec7fc449f055452": {
"name": "Magpul MBUS Gen2 rear flip-up sight (FDE) [Ram & Rem]",
"short_name": "MBUS RS",
"description": "Removable flip-up rear sight MBUS Gen2, installed on the mount. Manufactured by Magpul. Flat Dark Earth color."
},
"6753d006cec7fc449f055453": {
"name": "MCX flip-up rear sight [Ai Fuyuumi]",
"short_name": "MCX RS",
"description": "Removable flip-up rear sight for MCX assault rifles, manufactured by SIG Sauer."
},
"6753d006cec7fc449f055454": {
"name": "MCX flip-up rear sight [GF M4 SOPMOD II]",
"short_name": "MCX RS",
"description": "Removable flip-up rear sight for MCX assault rifles, manufactured by SIG Sauer."
},
"6753d006cec7fc449f055455": {
"name": "MCX flip-up rear sight [Animu 3]",
"short_name": "MCX RS",
"description": "Removable flip-up rear sight for MCX assault rifles, manufactured by SIG Sauer."
},
"6753d006cec7fc449f055456": {
"name": "MCX flip-up rear sight [Animu 3 v2]",
"short_name": "MCX RS",
"description": "Removable flip-up rear sight for MCX assault rifles, manufactured by SIG Sauer."
},
"6753d006cec7fc449f055457": {
"name": "MCX flip-up rear sight [Anti]",
"short_name": "MCX RS",
"description": "Removable flip-up rear sight for MCX assault rifles, manufactured by SIG Sauer. Your personal waifu giving her neko love to support you in combat."
},
"6753d006cec7fc449f055458": {
"name": "MCX flip-up rear sight [Anti 2]",
"short_name": "MCX RS",
"description": "Removable flip-up rear sight for MCX assault rifles, manufactured by SIG Sauer. The personal sight used by Anti, the war Neko! Nya!!"
},
"6753d006cec7fc449f055459": {
"name": "MCX flip-up rear sight [Ram & Rem]",
"short_name": "MCX RS",
"description": "Removable flip-up rear sight for MCX assault rifles, manufactured by SIG Sauer."
}
}