Here I have added all the new items as of 12/04/2024.
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using UnityEngine;
using System.Collections;
using Facepunch.Extend;
using Oxide.Core.Libraries.Covalence;
/*
* Has WearContainer Anti Stacking Duplication features/bug fixes
* Fixes Custom skin splitting issues + Custom Item Names. Making oranges skinsfix plugin not required/needed.
* Has vending machine no ammo patch toggle (so it won't affect default map vending machine not giving out stock ammo.
* Doesn't have ammo duplication with repair bench by skin manipulation issue.
* Doesn't have condition reset issues when re-stacking used weapons.
* Has not being able to stack a used gun onto a new gun, only.
* Doesn't have the weapon attachments issues
*
* Fixed Visual bug on item splits ( where the players inventory UI wasn't updating properly )
* Slight performance tweak
* Added Updater methods.
*
* Fixed new NRE issues 6/8/2021
*
* Update 1.0.5 6/12/2021
* Changed check config value to >= because fuck it
*
* updated 1.0.6 7/15/2021
* Added feature to stop player abusing higher stack sizes when moving items from other storage containers to player inventory set from other plugins
* Fixed Clone stack issues
* Updated OnItemAddedToContainer code logic to fix StackItemStorage Bug Credits to Clearshot.
*
* Update 1.0.8
* Fixed High hook time warnings significantly reduced
* Fixed Condition loss comparison between float values
* Added Ignore Admin check for F1 Spawns
* Adjusted/fixed item moving issues from other plugins
*
* Update 1.0.9
* Patched Skins auto merging into 1 stack bug
*
* Update 1.1.0
* Added Liquid stacking support
* Fixed On ItemAdded issue with stacks when using StackItemStorage
*
* Update 1.1.1
* Added support for stacking Miner Hats with fuel + Candle Hats
*
* Update 1.1.2
* Fixed Stacking issues with float values not matching due to unity float comparison bug
*
* Update 1.1.3
* Fixed Vendor bug..
*
* Update 1.1.4
* Added OnCardSwipe to fix stack loss when it hits broken stage.
*
* Update 1.1.5
* Fixed High hook time hangs sometimes resulted in server crashes..
*
* Update 1.1.7
* Fixes all vendor problems when booting/rebooting servers
* Added Chat command to manually reset the vendors that you talk to only /resetvendors
*
* Update 1.1.8
* Pulled due to false reports.
* Reverted back to original patch of 1.1.7
*
* Update 1.1.9
* Fixes custom items that have different custom names applied with the same skinids from stacking.
* Fixes resetting stacks to default if ( true ) in config.
*
* Update 1.2.0
* Added Global Category Group Stack Setting options
*
* Update 1.3.0
* Added Editor UI
* Swapped back to Rust Plugin
* Added Image Library Support
* Added New Config Options
* Added Search Bar + fade out.
* Added additional checks/options made some performance improvements
*
* Update 1.3.2
* Blocks player movements while using editor
* Updated console output responses
* Updated UI Systems and fixed a bug relating to first time opening
* ( it was double opening )
*
* Update 1.3.21
* Updated Input checks
* Fixed spectating players while using the UI Editor..
*
* Update 1.3.22
* Expanded the UI Editor Search parameters a bit
*
* Update 1.3.3
* Fixed Missing Defaults
* Fixed UI Not showing correctly between Multipliers and Modified items
* Added
* aiming.module.mlrs, MLRS Aiming Module
* mlrs, MLRS
* ammo.rocket.mlrs, MLRS Rocket
* lumberjack hoodie, Lumberjack Hoodie
* frankensteintable, Frankenstein Table
* carvable.pumpkin, Carvable Pumpkin
* frankensteins.monster.01.head, Light Frankenstein Head
* frankensteins.monster.01.legs, Light Frankenstein Legs
* frankensteins.monster.01.torso, Light Frankenstein Torso
* frankensteins.monster.02.head, Medium Frankenstein Head
* frankensteins.monster.02.legs, Medium Frankenstein Legs
* frankensteins.monster.02.torso, Medium Frankenstein Torso
* frankensteins.monster.03.head, Heavy Frankenstein Head
* frankensteins.monster.03.legs, Heavy Frankenstein Legs
* frankensteins.monster.03.torso, Heavy Frankenstein Torso
* sunglasses02black, Sunglasses
* sunglasses02camo, Sunglasses
* sunglasses02red, Sunglasses
* sunglasses03black, Sunglasses
* sunglasses03chrome, Sunglasses
* sunglasses03gold, Sunglasses
* captainslog, Captain's Log
* fishing.tackle, Fishing Tackle
* bottle.vodka, Vodka Bottle
* vehicle.2mod.camper, Camper Vehicle Module
* skull, Skull
* rifle.lr300, LR-300 Assault Rifle
*
* Update 1.3.4
* Added new reset Command for the search bar
* Added new set Command for the search bar
* Updated Category Descriptions
* ( Type reset in any category search bar and it will reset that whole category for you! )
* ( Type set 8 in any category search bar and it will set that whole category for you to 8! )
*
* Update 1.3.5
* Re-fixed vendor problem..
*
* Notice
* I will not be providing any more updates for this, this month.
*
* Update 1.3.7
* Fixes ( Stack problems with different stack sizes for different storages )
* WARNING!
* Potentially heavy update.. idk if this will crash 1000000mil x Servers or not!
*
* Update 1.3.71
* Code Cleanup + improvements / back to permanent
* Fixed Reloading problems
* Added some missed checks for ImageLibrary to resolve
* Removed Admin Toggle Config Option. ( it's hardcoded to ignore admins )
*
* Update 1.4.0
* Partial UI Re-write/Optimizations!
* More config options!
* New command sluts! /stackmodifiercolor
* Fixed Search bar commands! ( reset & set ) now work excellently!
* Search parameters work 200% better than before!
* Added Patch for Nivex's RaidableBases Plugins
* This update was brought to you in conjunction with baz!
*
* Update 1.4.1
* Fixed UI Constantly Re-Updating the Multiplier Descriptions ( when not needed ).
* Another UI Performance update/Tweak
* Fixed Sunglasses Display Names
* Added Lang API Support from codefling https://codefling.com/plugins/lang-api?tab=details
*
* update 1.4.2
* Re-fixed ignore admin check
*
* update 1.4.4
* Optional Update
* Re-designed UI System
* Added All Category
*
* update 1.4.7
* Updated for rust update
* Added the following new items
* rhib
* rowboat
* snowmobile
* snowmobiletomaha
* hazmatsuit.arcticsuit
* hazmatsuit_scientist_arctic
* spraycan
* rifle.ak.ice
*
* update 1.4.8
* Updated for rust update
* Added the following new items
* bluedogtags
* dogtagneutral
* reddogtags
* attire.egg.suit
* sign.egg.suit
*
* update 1.4.9
* Added 1 new feature
* Disable Images toggle: Disables ImageLibrary Requirement / Images for UI Editor
*
* update 1.5.0
* Fixed loot panel UI not updating value counts on items when splitting a skinned item stack inside of a loot panel container into a players inventory
*
* update 1.5.1
* Removed All ImageLibrary support / code All plugins moving forward will strictly use built in FacePunch Native logic.
* Re-designed CanStack Hook re-coded fixing all rock skinned stacking bugs etc
* Big performance gains
* Improved search functions by 10 fold.
*
* update 1.5.2
* patched oncardswipe error
*
* update 1.5.3
* patched scientist suit having same name as peacekeeper scientist suit
* Fixed Stacking Problems with scientist suit & peacekeeper scientist suit
* Native FacePunch Bug / If you look in F1 menu for scientist suit you'll see what I mean.
*
* update 1.5.4
* added 3 new items
*
* update 1.6.0
* WARNING!! OPTIONAL UPDATE! HAS MANY CHANGES THAT MAY CHANGE THE DEFAULT BEHAVIOR YOUR USED TO.
* Replaced blocked list with a new bool toggle system
* Fixed a couple ui issues displaying the wrong value to you that it's actually using.
* Fixed the stack multiplier fields so they actually multiple the default values now.
* StackModifier will now check the item contents capacity & if it does not equal the same it will deny the stack.
* Search Input Field has 5 command options now, disableon | disableoff | set 100 | multiply 5 | reset
* Thanks to Jakes commit I can now remove the vending machine repair code!
* https://commits.facepunch.com/412359
* Fixed the following item display names being messed up by facepunch.
* skullspikes.candles
* skullspikes.pumpkin
* skull.trophy.jar
* skull.trophy.jar2
* skull.trophy.table
* innertube.horse
* innertube.unicorn
* sled.xmas
* discofloor.largetiles
*
* Update 1.6.1
* Added multiple safe guards to prevent setting item stack sizes to Zero..
* Added locomotive
* Added trophy
* Added grenade.flashbang
* Added grenade.molotov
* Added Hook > OnIgnoreStackSize
*
* Update 1.6.2
* Adjusted OnItemAddedToContainer
*
* Update 1.6.3
* Added new game items & updated chocolate to the new name
*
* Update 1.6.4
* Added another 3 new game items
*
* Update 1.6.5
* Moved config correction code to beginning of logic.
* Delayed server update by 3 & 5 on load.
*
* Update 1.6.6
* Fixes new config generation bug caused by old debug code.
* Created Correction logic for owners attempting to set negative values in the config.
* Created Corrections log file for owners to see what all got corrected.
* TODO: Re-write the check config script into a coroutine and clean that shit up..
*
* Update 1.6.7
* added 2 new rust game items from today's update.
*
* Update 1.6.8
* Added 4 new game items, Removed Car Key since FacePunch removed the item from the game..
* Fixed Server Setting Stack Size bugs
*
* Version 2x umod edition
* No longer has built-in UI Editor
* Added Console & Chat Commands
* Created Fancy Text Out-Put, enjoy /
*/
namespace Oxide.Plugins
{
[Info("Stack Modifier", "Khan", "2.0.0")]
[Description("Modify item stack sizes using chat commands or config edits, UI Editor is now a paid feature")]
public class StackModifier : RustPlugin
{
#region License Agreement (EULA) of Stack Modifier
/*
End-User License Agreement (EULA) of Stack Modifier
This End-User License Agreement ("EULA") is a legal agreement between you and Kyle. This EULA agreement
governs your acquisition and use of our Stack Modifier plugin ("Software") directly from Kyle.
Please read this EULA agreement carefully before downloading and using the Stack Modifier plugin.
It provides a license to use the Stack Modifier and contains warranty information and liability disclaimers.
If you are entering into this EULA agreement on behalf of a company or other legal entity, you represent that you have the authority
to bind such entity and its affiliates to these terms and conditions. If you do not have such authority or if you do not agree with the
terms and conditions of this EULA agreement, DO NOT purchase or download the Software.
This EULA agreement shall apply only to the Software supplied by Kyle Farris regardless of whether other software is referred
to or described herein. The terms also apply to any Kyle updates, supplements, Internet-based services, and support services for the Software,
unless other terms accompany those items on delivery. If so, those terms apply.
License Grant
Kyle hereby grants you a personal, non-transferable, non-exclusive license to use the Stack Modifier software on your devices in
accordance with the terms of this EULA agreement. You are permitted to load the Stack Modifier on your personal server owned by you.
You are not permitted to:
Edit, alter, modify, adapt, translate or otherwise change the whole or any part of the Software nor permit the whole or any part
of the Software to be combined with or become incorporated in any other software, nor decompile, disassemble or reverse
engineer the Software or attempt to do any such things.
Reproduce, copy, distribute, resell or otherwise use the Software for any commercial purpose
Allow any third party to use the Software on behalf of or for the benefit of any third party
Use the Software in any way which breaches any applicable local, national or international law
use the Software for any purpose that Kyle considers is a breach of this EULA agreement
Intellectual Property and Ownership
Kyle shall at all times retain ownership of the Software as originally downloaded by you and all subsequent downloads of the Software by you.
The Software (and the copyright, and other intellectual property rights of whatever nature in the Software, including any modifications made thereto) are and shall remain the property of Kyle.
Termination
This EULA agreement is effective from the date you first use the Software and shall continue until terminated.
You may terminate it at any time upon written notice to Kyle.
It will also terminate immediately if you fail to comply with any term of this EULA agreement.
Upon such termination, the licenses granted by this EULA agreement will immediately terminate and you agree to stop all access and use of the Software.
The provisions that by their nature continue and survive will survive any termination of this EULA agreement.
*/
#endregion
#region Fields
//TODO: Code in feature request for stack overrides
private const string Admin = "stackmodifier.admin";
private static Dictionary<string, int> _defaults = null;
private static Dictionary<string, int> _FB = new Dictionary<string, int>
{
{"legacy.shelter.wood", 1},
{"draculacape", 1},
{"draculamask", 1},
{"minigunammopack", 1},
{"hazmatsuittwitch", 1},
{"legacyfurnace", 1},
{"cupboard.tool.retro", 1},
{"gunrack.single.1.horizontal", 10},
{"gunrack.single.2.horizontal", 10},
{"gunrack.single.3.horizontal", 10},
{"hazmatyoutooz", 1},
{"heavyscientistyoutooz", 1},
{"chineselanternwhite", 1},
{"confetticannon", 1},
{"door.double.hinged.bardoors", 1},
{"bathtub.planter", 10},
{"head.bag", 1},
{"fishtrophy", 1},
{"huntingtrophylarge", 1},
{"huntingtrophysmall", 1},
{"minecart.planter", 10},
{"rail.road.planter", 10},
{"rockingchair", 5},
{"rockingchair.rockingchair2", 5},
{"rockingchair.rockingchair3", 5},
{"knife.skinning", 1},
{"storage_barrel_a", 1},
{"storage_barrel_b", 1},
{"storage_barrel_c", 1},
{"torchholder", 1},
{"wantedposter.wantedposter2", 1},
{"wantedposter.wantedposter3", 1},
{"wantedposter.wantedposter4", 1},
{"wantedposter", 1},
{"chicken.costume", 1},
{"lavenderidtag", 5000},
{"mintidtag", 5000},
{"largebackpack", 1},
{"frontiermirror.large", 1},
{"frontiermirror.medium", 1},
{"frontiermirror.small", 1},
{"frontiermirror.standing", 1},
{"goldframe.large", 1},
{"goldframe.medium", 1},
{"goldframe.small", 1},
{"goldframe.standing", 1},
{"goldmirror.large", 1},
{"goldmirror.medium", 1},
{"goldmirror.small", 1},
{"goldmirror.standing", 1},
{"lightup.large", 1},
{"lightupframe.medium", 1},
{"lightupframe.small", 1},
{"lightupframe.standing", 1},
{"lightupmirror.large", 1},
{"lightupmirror.medium", 1},
{"lightupmirror.small", 1},
{"lightupmirror.standing", 1},
{"scrapframe.large", 1},
{"scrapframe.medium", 1},
{"scrapframe.small", 1},
{"scrapframe.standing", 1},
{"scrapmirror.large", 1},
{"scrapmirror.medium", 1},
{"scrapmirror.small", 1},
{"scrapmirror.standing", 1},
{"twowaymirror.window", 1},
{"woodframe.large", 1},
{"woodframe.medium", 1},
{"woodframe.small", 1},
{"woodframe.standing", 1},
{"woodmirror.large", 1},
{"woodmirror.medium", 1},
{"woodmirror.small", 1},
{"woodmirror.standing", 1},
{"pinata", 5},
{"smallbackpack", 1},
{"trophy2023", 1},
{"twitchrivals2023desk", 1},
{"metal.detector", 1},
{"shovel", 1},
{"walkietalkie", 1},
{"spear.cny", 1},
{"vampire.stake", 1},
{"legacy bow", 1},
{"shotgun.m4", 1},
{"military flamethrower", 1},
{"minigun", 1},
{"rocket.launcher.dragon", 1},
{"attackhelicopter", 1},
{"tugboat", 1},
{"hazmatsuit.diver", 1},
{"clantable", 1},
{"weaponrack.light", 1},
{"weaponrack.doublelight", 1},
{"hab.armor", 1},
{"ammo.rocket.seeker", 2},
{"gunrack.horizontal", 10},
{"gunrack_stand", 10},
{"gunrack_tall.horizontal", 10},
{"gunrack_wide.horizontal", 10},
{"parachute.deployed", 1},
{"parachute", 1},
{"rifle.ak.diver", 1},
{"diverhatchet", 1},
{"diverpickaxe", 1},
{"divertorch", 1},
{"homingmissile.launcher", 1},
{"hat.wolf", 1},
{"fogmachine", 1},
{"strobelight", 1},
{"kayak", 1},
{"minihelicopter.repair", 1},
{"aiming.module.mlrs", 1},
{"mlrs", 1},
{"ammo.rocket.mlrs", 6},
{"scraptransportheli.repair", 1},
{"submarineduo", 1},
{"submarinesolo", 1},
{"workcart", 1},
{"ammo.grenadelauncher.buckshot", 24},
{"ammo.grenadelauncher.he", 12},
{"ammo.grenadelauncher.smoke", 12},
{"arrow.hv", 64},
{"arrow.wooden", 64},
{"arrow.bone", 64},
{"arrow.fire", 64},
{"ammo.handmade.shell", 64},
{"ammo.nailgun.nails", 64},
{"ammo.pistol", 128},
{"ammo.pistol.fire", 128},
{"ammo.pistol.hv", 128},
{"ammo.rifle", 128},
{"ammo.rifle.explosive", 128},
{"ammo.rifle.incendiary", 128},
{"ammo.rifle.hv", 128},
{"ammo.rocket.basic", 3},
{"ammo.rocket.fire", 3},
{"ammo.rocket.hv", 3},
{"ammo.rocket.smoke", 3},
{"ammo.shotgun", 64},
{"ammo.shotgun.fire", 64},
{"ammo.shotgun.slug", 32},
{"speargun.spear", 64},
{"submarine.torpedo.straight", 100},
{"door.double.hinged.metal", 1},
{"door.double.hinged.toptier", 1},
{"door.double.hinged.wood", 1},
{"door.hinged.metal", 1},
{"door.hinged.toptier", 1},
{"door.hinged.wood", 1},
{"floor.grill", 10},
{"floor.ladder.hatch", 1},
{"floor.triangle.grill", 10},
{"floor.triangle.ladder.hatch", 1},
{"gates.external.high.stone", 1},
{"gates.external.high.wood", 1},
{"ladder.wooden.wall", 5},
{"wall.external.high.stone", 10},
{"wall.external.high", 10},
{"wall.frame.cell.gate", 1},
{"wall.frame.cell", 10},
{"wall.frame.fence.gate", 1},
{"wall.frame.fence", 10},
{"wall.frame.garagedoor", 1},
{"wall.frame.netting", 5},
{"wall.frame.shopfront", 1},
{"wall.frame.shopfront.metal", 1},
{"wall.window.bars.metal", 10},
{"wall.window.bars.toptier", 10},
{"wall.window.bars.wood", 10},
{"shutter.metal.embrasure.a", 20},
{"shutter.metal.embrasure.b", 20},
{"wall.window.glass.reinforced", 10},
{"shutter.wood.a", 20},
{"watchtower.wood", 5},
{"diving.fins", 1},
{"diving.mask", 1},
{"diving.tank", 1},
{"diving.wetsuit", 1},
{"boots.frog", 1},
{"barrelcostume", 1},
{"cratecostume", 1},
{"hat.gas.mask", 1},
{"burlap.gloves.new", 1},
{"burlap.gloves", 1},
{"roadsign.gloves", 1},
{"tactical.gloves", 1},
{"ghostsheet", 1},
{"halloween.mummysuit", 1},
{"scarecrow.suit", 1},
{"scarecrowhead", 1},
{"attire.hide.helterneck", 1},
{"hat.beenie", 1},
{"hat.boonie", 1},
{"bucket.helmet", 1},
{"burlap.headwrap", 1},
{"hat.candle", 1},
{"hat.cap", 1},
{"clatter.helmet", 1},
{"coffeecan.helmet", 1},
{"deer.skull.mask", 1},
{"heavy.plate.helmet", 1},
{"hat.miner", 1},
{"partyhat", 1},
{"riot.helmet", 1},
{"wood.armor.helmet", 1},
{"hoodie", 1},
{"bone.armor.suit", 1},
{"heavy.plate.jacket", 1},
{"jacket.snow", 1},
{"jacket", 1},
{"wood.armor.jacket", 1},
{"lumberjack hoodie", 1},
{"mask.balaclava", 1},
{"mask.bandana", 1},
{"metal.facemask", 1},
{"nightvisiongoggles", 1},
{"attire.ninja.suit", 1},
{"burlap.trousers", 1},
{"heavy.plate.pants", 1},
{"attire.hide.pants", 1},
{"roadsign.kilt", 1},
{"pants.shorts", 1},
{"wood.armor.pants", 1},
{"pants", 1},
{"attire.hide.poncho", 1},
{"burlap.shirt", 1},
{"shirt.collared", 1},
{"attire.hide.vest", 1},
{"shirt.tanktop", 1},
{"shoes.boots", 1},
{"burlap.shoes", 1},
{"attire.hide.boots", 1},
{"attire.hide.skirt", 1},
{"attire.banditguard", 1},
{"hazmatsuit", 1},
{"hazmatsuit_scientist", 1},
{"hazmatsuit_scientist_peacekeeper", 1},
{"hazmatsuit.spacesuit", 1},
{"hazmatsuit_scientist_nvgm", 1},
{"scientistsuit_heavy", 1},
{"jumpsuit.suit.blue", 1},
{"jumpsuit.suit", 1},
{"tshirt.long", 1},
{"tshirt", 1},
{"metal.plate.torso", 1},
{"roadsign.jacket", 1},
{"bleach", 20},
{"ducttape", 20},
{"carburetor1", 5},
{"carburetor2", 5},
{"carburetor3", 5},
{"crankshaft1", 5},
{"crankshaft2", 5},
{"crankshaft3", 5},
{"piston1", 10},
{"piston2", 10},
{"piston3", 10},
{"sparkplug1", 20},
{"sparkplug2", 20},
{"sparkplug3", 20},
{"valve1", 15},
{"valve2", 15},
{"valve3", 15},
{"fuse", 10},
{"gears", 20},
{"glue", 10},
{"metalblade", 20},
{"metalpipe", 20},
{"propanetank", 5},
{"roadsigns", 20},
{"rope", 50},
{"sewingkit", 20},
{"sheetmetal", 20},
{"metalspring", 20},
{"sticks", 100},
{"tarp", 20},
{"techparts", 50},
{"riflebody", 10},
{"semibody", 10},
{"smgbody", 10},
{"barricade.concrete", 10},
{"barricade.wood.cover", 10},
{"barricade.metal", 10},
{"barricade.sandbags", 10},
{"barricade.stone", 10},
{"barricade.wood", 10},
{"barricade.woodwire", 10},
{"bbq", 1},
{"trap.bear", 3},
{"bed", 1},
{"campfire", 1},
{"ceilinglight", 10},
{"chair", 5},
{"composter", 1},
{"computerstation", 1},
{"drone", 1},
{"dropbox", 5},
{"elevator", 5},
{"fireplace.stone", 1},
{"firework.boomer.blue", 20},
{"firework.boomer.champagne", 20},
{"firework.boomer.green", 20},
{"firework.boomer.orange", 20},
{"firework.boomer.red", 20},
{"firework.boomer.violet", 20},
{"firework.romancandle.blue", 20},
{"firework.romancandle.green", 20},
{"firework.romancandle.red", 20},
{"firework.romancandle.violet", 20},
{"firework.volcano", 20},
{"firework.volcano.red", 20},
{"firework.volcano.violet", 20},
{"spikes.floor", 10},
{"frankensteintable", 1},
{"fridge", 1},
{"furnace.large", 1},
{"furnace", 1},
{"hitchtroughcombo", 1},
{"habrepair", 1},
{"jackolantern.angry", 1},
{"jackolantern.happy", 1},
{"trap.landmine", 5},
{"lantern", 1},
{"box.wooden.large", 1},
{"water.barrel", 1},
{"locker", 1},
{"mailbox", 1},
{"mixingtable", 1},
{"modularcarlift", 1},
{"mining.pumpjack", 1},
{"small.oil.refinery", 1},
{"planter.large", 10},
{"planter.small", 10},
{"electric.audioalarm", 5},
{"smart.alarm", 5},
{"smart.switch", 5},
{"storage.monitor", 1},
{"electric.battery.rechargable.large", 1},
{"electric.battery.rechargable.medium", 1},
{"electric.battery.rechargable.small", 1},
{"electric.button", 5},
{"electric.counter", 5},
{"electric.hbhfsensor", 1},
{"electric.laserdetector", 5},
{"electric.pressurepad", 1},
{"electric.doorcontroller", 5},
{"electric.heater", 5},
{"fluid.combiner", 5},
{"fluid.splitter", 5},
{"fluid.switch", 1},
{"electric.andswitch", 5},
{"electric.blocker", 5},
{"electrical.branch", 5},
{"electrical.combiner", 5},
{"electrical.memorycell", 5},
{"electric.orswitch", 5},
{"electric.random.switch", 5},
{"electric.rf.broadcaster", 1},
{"electric.rf.receiver", 1},
{"electric.xorswitch", 5},
{"electric.fuelgenerator.small", 1},
{"electric.generator.small", 1},
{"electric.solarpanel.large", 3},
{"electric.igniter", 3},
{"electric.flasherlight", 5},
{"electric.simplelight", 1},
{"electric.sirenlight", 5},
{"powered.water.purifier", 1},
{"electric.switch", 5},
{"electric.splitter", 5},
{"electric.sprinkler", 10},
{"electric.teslacoil", 3},
{"electric.timer", 5},
{"electric.cabletunnel", 1},
{"waterpump", 1},
{"mining.quarry", 1},
{"target.reactive", 1},
{"box.repair.bench", 1},
{"research.table", 1},
{"rug.bear", 1},
{"rug", 1},
{"searchlight", 1},
{"secretlabchair", 5},
{"shelves", 10},
{"sign.hanging.banner.large", 5},
{"sign.hanging", 5},
{"sign.hanging.ornate", 5},
{"sign.pictureframe.landscape", 5},
{"sign.pictureframe.portrait", 5},
{"sign.pictureframe.tall", 5},
{"sign.pictureframe.xl", 5},
{"sign.pictureframe.xxl", 5},
{"sign.pole.banner.large", 5},
{"sign.post.double", 5},
{"sign.post.single", 5},
{"sign.post.town", 5},
{"sign.post.town.roof", 5},
{"sign.wooden.huge", 5},
{"sign.wooden.large", 5},
{"sign.wooden.medium", 5},
{"sign.wooden.small", 5},
{"guntrap", 1},
{"sleepingbag", 1},
{"stash.small", 5},
{"sofa", 2},
{"spinner.wheel", 1},
{"fishtrap.small", 5},
{"table", 1},
{"workbench1", 1},
{"workbench2", 1},
{"workbench3", 1},
{"cupboard.tool", 1},
{"tunalight", 1},
{"vending.machine", 1},
{"water.catcher.large", 1},
{"water.catcher.small", 1},
{"water.purifier", 1},
{"generator.wind.scrap", 1},
{"box.wooden", 1},
{"apple", 10},
{"apple.spoiled", 1},
{"black.raspberries", 1},
{"blueberries", 20},
{"botabag", 1},
{"grub", 20},
{"worm", 20},
{"cactusflesh", 10},
{"can.beans", 10},
{"can.tuna", 10},
{"fish.anchovy", 10},
{"fish.catfish", 5},
{"fish.cooked", 20},
{"fish.raw", 20},
{"fish.herring", 10},
{"fish.minnows", 10},
{"fish.orangeroughy", 5},
{"fish.salmon", 10},
{"fish.sardine", 10},
{"fish.smallshark", 5},
{"fish.troutsmall", 10},
{"fish.yellowperch", 10},
{"granolabar", 10},
{"chicken.burned", 20},
{"chicken.cooked", 20},
{"chicken.raw", 20},
{"chicken.spoiled", 20},
{"deermeat.burned", 20},
{"deermeat.cooked", 20},
{"deermeat.raw", 20},
{"horsemeat.burned", 20},
{"horsemeat.cooked", 20},
{"horsemeat.raw", 20},
{"humanmeat.burned", 20},
{"humanmeat.cooked", 20},
{"humanmeat.raw", 20},
{"humanmeat.spoiled", 20},
{"bearmeat.burned", 20},
{"bearmeat.cooked", 20},
{"bearmeat", 20},
{"wolfmeat.burned", 20},
{"wolfmeat.cooked", 20},
{"wolfmeat.raw", 20},
{"wolfmeat.spoiled", 20},
{"meat.pork.burned", 20},
{"meat.pork.cooked", 20},
{"meat.boar", 20},
{"mushroom", 10},
{"jar.pickle", 10},
{"smallwaterbottle", 1},
{"waterjug", 1},
{"fun.bass", 1},
{"fun.cowbell", 1},
{"drumkit", 1},
{"fun.flute", 1},
{"fun.guitar", 1},
{"fun.jerrycanguitar", 1},
{"piano", 1},
{"fun.tambourine", 1},
{"fun.trumpet", 1},
{"fun.tuba", 1},
{"xylophone", 1},
{"door.key", 1},
{"lock.key", 10},
{"lock.code", 10},
{"blueprintbase", 1000},
{"chineselantern", 1},
{"dragondoorknocker", 1},
{"hat.dragonmask", 1},
{"newyeargong", 1},
{"hat.oxmask", 1},
{"hat.ratmask", 1},
{"lunar.firecrackers", 5},
{"arcade.machine.chippy", 1},
{"door.closer", 1},
{"attire.bunnyears", 1},
{"attire.bunny.onesie", 1},
{"hat.bunnyhat", 1},
{"easterdoorwreath", 1},
{"easterbasket", 1},
{"rustige_egg_a", 1},
{"rustige_egg_b", 1},
{"rustige_egg_c", 1},
{"rustige_egg_d", 1},
{"rustige_egg_e", 1},
{"rustige_egg_f", 1},
{"attire.nesthat", 1},
{"easter.bronzeegg", 10},
{"easter.goldegg", 10},
{"easter.paintedeggs", 1000},
{"easter.silveregg", 10},
{"halloween.candy", 1000},
{"largecandles", 1},
{"smallcandles", 1},
{"carvable.pumpkin", 1},
{"coffin.storage", 1},
{"cursedcauldron", 1},
{"gravestone", 1},
{"woodcross", 1},
{"frankensteins.monster.01.head", 1},
{"frankensteins.monster.01.legs", 1},
{"frankensteins.monster.01.torso", 1},
{"frankensteins.monster.02.head", 1},
{"frankensteins.monster.02.legs", 1},
{"frankensteins.monster.02.torso", 1},
{"frankensteins.monster.03.head", 1},
{"frankensteins.monster.03.legs", 1},
{"frankensteins.monster.03.torso", 1},
{"wall.graveyard.fence", 10},
{"halloween.lootbag.large", 10},
{"halloween.lootbag.medium", 10},
{"halloween.lootbag.small", 10},
{"pumpkinbasket", 1},
{"scarecrow", 5},
{"skullspikes.candles", 1},
{"skullspikes.pumpkin", 1},
{"skullspikes", 1},
{"skulldoorknocker", 1},
{"skull_fire_pit", 1},
{"spiderweb", 10},
{"spookyspeaker", 1},
{"halloween.surgeonsuit", 1},
{"skull.trophy.jar", 1},
{"skull.trophy.jar2", 1},
{"skull.trophy.table", 1},
{"skull.trophy", 1},
{"movembermoustachecard", 1},
{"movembermoustache", 1},
{"note", 1},
{"skull.human", 1},
{"abovegroundpool", 1},
{"beachchair", 1},
{"beachparasol", 1},
{"beachtable", 1},
{"beachtowel", 1},
{"boogieboard", 1},
{"innertube", 1},
{"innertube.horse", 1},
{"innertube.unicorn", 1},
{"tool.instant_camera", 1},
{"paddlingpool", 1},
{"photo", 1},
{"photoframe.landscape", 1},
{"photoframe.large", 1},
{"photoframe.portrait", 1},
{"sunglasses02black", 1},
{"sunglasses02camo", 1},
{"sunglasses02red", 1},
{"sunglasses03black", 1},
{"sunglasses03chrome", 1},
{"sunglasses03gold", 1},
{"sunglasses", 1},
{"gun.water", 1},
{"pistol.water", 1},
{"twitchsunglasses", 1},
{"twitch.headset", 1},
{"hobobarrel", 1},
{"door.hinged.industrial.a", 1},
{"candycaneclub", 1},
{"xmas.lightstring", 20},
{"xmas.door.garland", 10},
{"candycane", 1},
{"giantcandycanedecor", 1},
{"wall.ice.wall", 10},
{"wall.external.high.ice", 10},
{"giantlollipops", 1},
{"sign.neon.125x125", 5},
{"sign.neon.125x215.animated", 1},
{"sign.neon.125x215", 5},
{"sign.neon.xl.animated", 5},
{"sign.neon.xl", 1},
{"pookie.bear", 1},
{"xmas.lightstring.advanced", 150},
{"coal", 1},
{"xmas.present.large", 1},
{"xmas.present.medium", 5},
{"xmas.present.small", 10},
{"sled.xmas", 1},
{"sled", 1},
{"snowmachine", 1},
{"snowball", 1},
{"ammo.snowballgun", 128},
{"snowballgun", 1},
{"snowman", 5},
{"stocking.large", 1},
{"stocking.small", 5},
{"attire.reindeer.headband", 1},
{"santabeard", 1},
{"santahat", 1},
{"xmas.window.garland", 10},
{"wrappedgift", 1},
{"wrappingpaper", 1},
{"xmasdoorwreath", 1},
{"xmas.decoration.baubels", 1},
{"xmas.decoration.candycanes", 1},
{"xmas.decoration.gingerbreadmen", 1},
{"xmas.decoration.lights", 1},
{"xmas.decoration.pinecone", 1},
{"xmas.decoration.star", 1},
{"xmas.decoration.tinsel", 1},
{"xmas.tree", 1},
{"captainslog", 1},
{"fishing.tackle", 1},
{"bottle.vodka", 1},
{"autoturret", 1},
{"flameturret", 1},
{"gloweyes", 1},
{"ammo.rocket.sam", 1000},
{"samsite", 1},
{"black.berry", 20},
{"clone.black.berry", 50},
{"seed.black.berry", 50},
{"blue.berry", 20},
{"clone.blue.berry", 50},
{"seed.blue.berry", 50},
{"green.berry", 20},
{"clone.green.berry", 50},
{"seed.green.berry", 50},
{"red.berry", 20},
{"clone.red.berry", 50},
{"seed.red.berry", 50},
{"white.berry", 20},
{"clone.white.berry", 50},
{"seed.white.berry", 50},
{"yellow.berry", 20},
{"clone.yellow.berry", 50},
{"seed.yellow.berry", 50},
{"corn", 20},
{"clone.corn", 50},
{"seed.corn", 50},
{"clone.hemp", 50},
{"seed.hemp", 50},
{"potato", 20},
{"clone.potato", 50},
{"seed.potato", 50},
{"pumpkin", 20},
{"clone.pumpkin", 50},
{"seed.pumpkin", 50},
{"fat.animal", 1000},
{"battery.small", 1},
{"blood", 1000},
{"bone.fragments", 1000},
{"cctv.camera", 64},
{"charcoal", 1000},
{"cloth", 1000},
{"crude.oil", 500},
{"diesel_barrel", 20},
{"can.beans.empty", 10},
{"can.tuna.empty", 10},
{"explosives", 100},
{"fertilizer", 1000},
{"gunpowder", 1000},
{"horsedung", 100},
{"hq.metal.ore", 1000},
{"metal.refined", 100},
{"leather", 1000},
{"lowgradefuel", 500},
{"metal.fragments", 1000},
{"metal.ore", 1000},
{"paper", 1000},
{"plantfiber", 1000},
{"researchpaper", 1000},
{"scrap", 1000},
{"stones", 1000},
{"sulfur.ore", 1000},
{"sulfur", 1000},
{"targeting.computer", 64},
{"skull.wolf", 1},
{"wood", 1000},
{"healingtea.advanced", 10},
{"healingtea", 10},
{"healingtea.pure", 10},
{"maxhealthtea.advanced", 10},
{"maxhealthtea", 10},
{"maxhealthtea.pure", 10},
{"oretea.advanced", 10},
{"oretea", 10},
{"oretea.pure", 10},
{"radiationremovetea.advanced", 10},
{"radiationremovetea", 10},
{"radiationremovetea.pure", 10},
{"radiationresisttea.advanced", 10},
{"radiationresisttea", 10},
{"radiationresisttea.pure", 10},
{"scraptea.advanced", 10},
{"scraptea", 10},
{"scraptea.pure", 10},
{"woodtea.advanced", 10},
{"woodtea", 10},
{"woodtea.pure", 10},
{"supertea", 1},
{"antiradpills", 10},
{"tool.binoculars", 1},
{"explosive.timed", 10},
{"tool.camera", 1},
{"rf.detonator", 1},
{"fishingrod.handmade", 1},
{"flare", 5},
{"flashlight.held", 1},
{"geiger.counter", 1},
{"hosetool", 1},
{"jackhammer", 1},
{"keycard_blue", 1},
{"keycard_green", 1},
{"keycard_red", 1},
{"largemedkit", 1},
{"map", 1},
{"syringe.medical", 2},
{"rf_pager", 1},
{"building.planner", 1},
{"grenade.smoke", 3},
{"supply.signal", 1},
{"surveycharge", 10},
{"wiretool", 1},
{"vehicle.chassis.2mod", 1},
{"vehicle.chassis.3mod", 1},
{"vehicle.chassis.4mod", 1},
{"vehicle.chassis", 1},
{"vehicle.1mod.cockpit", 1},
{"vehicle.1mod.cockpit.armored", 1},
{"vehicle.1mod.cockpit.with.engine", 1},
{"vehicle.1mod.engine", 1},
{"vehicle.1mod.flatbed", 1},
{"vehicle.1mod.passengers.armored", 1},
{"vehicle.1mod.rear.seats", 1},
{"vehicle.1mod.storage", 1},
{"vehicle.1mod.taxi", 1},
{"vehicle.2mod.camper", 1},
{"vehicle.2mod.flatbed", 1},
{"vehicle.2mod.fuel.tank", 1},
{"vehicle.2mod.passengers", 1},
{"vehicle.module", 1},
{"boombox", 1},
{"fun.boomboxportable", 1},
{"cassette", 1},
{"cassette.medium", 1},
{"cassette.short", 1},
{"fun.casetterecorder", 1},
{"discoball", 5},
{"discofloor", 5},
{"discofloor.largetiles", 5},
{"connected.speaker", 5},
{"laserlight", 5},
{"megaphone", 1},
{"microphonestand", 5},
{"mobilephone", 1},
{"soundlight", 5},
{"telephone", 1},
{"weapon.mod.8x.scope", 1},
{"weapon.mod.flashlight", 1},
{"weapon.mod.holosight", 1},
{"weapon.mod.lasersight", 1},
{"weapon.mod.muzzleboost", 1},
{"weapon.mod.muzzlebrake", 1},
{"weapon.mod.simplesight", 1},
{"weapon.mod.silencer", 1},
{"weapon.mod.small.scope", 1},
{"rifle.ak", 1},
{"bandage", 3},
{"grenade.beancan", 5},
{"rifle.bolt", 1},
{"bone.club", 1},
{"knife.bone", 1},
{"bow.hunting", 1},
{"cakefiveyear", 1},
{"chainsaw", 1},
{"salvaged.cleaver", 1},
{"bow.compound", 1},
{"crossbow", 1},
{"shotgun.double", 1},
{"pistol.eoka", 1},
{"grenade.f1", 5},
{"flamethrower", 1},
{"multiplegrenadelauncher", 1},
{"knife.butcher", 1},
{"pitchfork", 1},
{"sickle", 1},
{"skull", 1},
{"hammer", 1},
{"hatchet", 1},
{"knife.combat", 1},
{"rifle.l96", 1},
{"rifle.lr300", 1},
{"lmg.m249", 1},
{"rifle.m39", 1},
{"pistol.m92", 1},
{"mace", 1},
{"machete", 1},
{"smg.mp5", 1},
{"pistol.nailgun", 1},
{"paddle", 1},
{"pickaxe", 1},
{"shotgun.waterpipe", 1},
{"pistol.python", 1},
{"pistol.revolver", 1},
{"rock", 1},
{"rocket.launcher", 1},
{"axe.salvaged", 1},
{"hammer.salvaged", 1},
{"icepick.salvaged", 1},
{"explosive.satchel", 10},
{"shotgun.pump", 1},
{"pistol.semiauto", 1},
{"rifle.semiauto", 1},
{"smg.2", 1},
{"shotgun.spas12", 1},
{"speargun", 1},
{"stonehatchet", 1},
{"stone.pickaxe", 1},
{"spear.stone", 1},
{"longsword", 1},
{"salvaged.sword", 1},
{"smg.thompson", 1},
{"toolgun", 1},
{"torch", 1},
{"bucket.water", 1},
{"spear.wooden", 1},
{"horse.armor.roadsign", 1},
{"horse.armor.wood", 1},
{"horse.saddle", 1},
{"horse.saddle.single", 1},
{"horse.saddle.double", 1},
{"horse.saddlebag", 1},
{"horse.shoes.advanced", 1},
{"horse.shoes.basic", 1},
{"hazmatsuit.nomadsuit", 1},
{"sofa.pattern", 2},
{"factorydoor", 1},
{"industrial.wall.light.green", 10},
{"industrial.wall.light", 10},
{"industrial.wall.light.red", 10},
{"firework.boomer.pattern", 20},
{"xmas.advent", 1},
{"xmas.double.door.garland", 10},
{"attire.snowman.helmet", 1},
{"skylantern", 20},
{"skylantern.skylantern.green", 20},
{"skylantern.skylantern.orange", 20},
{"skylantern.skylantern.purple", 20},
{"skylantern.skylantern.red", 20},
{"hat.tigermask", 1},
{"rhib", 1},
{"rowboat", 1},
{"snowmobile", 1},
{"snowmobiletomaha", 1},
{"hazmatsuit.arcticsuit", 1},
{"hazmatsuit_scientist_arctic", 1},
{"spraycan", 1},
{"rifle.ak.ice", 1},
{"bluedogtags", 5000},
{"dogtagneutral", 5000},
{"reddogtags", 5000},
{"attire.egg.suit", 1},
{"sign.egg.suit", 5},
{"wagon", 1},
{"spraycandecal", 10},
{"weapon.mod.extendedmags", 1},
{"hmlmg", 1},
{"locomotive", 1},
{"trophy", 1},
{"grenade.flashbang", 5},
{"grenade.molotov", 5},
{"hazmatsuit.lumberjack", 1},
{"chocolate", 10},
{"concretehatchet", 1},
{"concretepickaxe", 1},
{"lumberjack.hatchet", 1},
{"lumberjack.pickaxe", 1},
{"metal.facemask.hockey", 1},
{"mace.baseballbat", 1},
{"torch.torch.skull", 1},
{"weapon.mod.burstmodule", 1},
{"pistol.prototype17", 1},
{"metal.facemask.icemask", 1},
{"metal.plate.torso.icevest", 1},
{"chair.icethrone", 5},
{"gingerbreadsuit", 1},
{"hat.rabbitmask", 1},
{"electric.furnace", 1},
{"storageadaptor", 5},
{"industrial.combiner", 5},
{"industrial.conveyor", 5},
{"industrial.crafter", 5},
{"industrial.splitter", 5},
{"pipetool", 1},
{"ptz.cctv.camera", 64},
{"blueidtag", 5000},
{"grayidtag", 5000},
{"greenidtag", 5000},
{"orangeidtag", 5000},
{"pinkidtag", 5000},
{"purpleidtag", 5000},
{"redidtag", 5000},
{"whiteidtag", 5000},
{"yellowidtag", 5000},
};
private readonly List<string> _exclude = new List<string>
{
"water",
"water.salt",
"cardtable",
"ammo.snowballgun",
/*"rowboat",
"rhib"*/
};
private readonly Dictionary<string, string> _corrections = new Dictionary<string, string>
{
{"sunglasses02black", "Sunglasses Style 2"},
{"sunglasses02camo", "Sunglasses Camo"},
{"sunglasses02red", "Sunglasses Red"},
{"sunglasses03black", "Sunglasses Style 3"},
{"sunglasses03chrome", "Sunglasses Chrome"},
{"sunglasses03gold", "Sunglasses Gold"},
{"twitchsunglasses", "Sunglasses Purple"},
{"hazmatsuit_scientist_peacekeeper", "Peacekeeper Scientist Suit"},
{"skullspikes.candles", "Skull Spikes Candles"},
{"skullspikes.pumpkin", "Skull Spikes Pumpkin"},
{"skull.trophy.jar", "Skull Trophy Jar"},
{"skull.trophy.jar2", "Skull Trophy Jar 2"},
{"skull.trophy.table", "Skull Trophy Table"},
{"innertube.horse", "Inner Tube Horse"},
{"innertube.unicorn", "Inner Tube Unicorn"},
{"sled.xmas", "Xmas Sled"},
{"discofloor.largetiles", "Disco Floor Large"},
};
#endregion
#region Config
private PluginConfig _config;
private IEnumerator CheckConfig()
{
Puts("Checking Configuration Settings");
yield return CoroutineEx.waitForSeconds(0.30f);
// Added Debug code to sort out display names of items facepunch got too lazy to actually finish properly..
//var temp = new Dictionary<string, string>();
foreach (ItemDefinition item in ItemManager.itemList)
{
string categoryName = item.category.ToString();
Dictionary<string, _Items> stackCategory;
if (_exclude.Contains(item.shortname))
{
if (_config.StackCategories[categoryName].ContainsKey(item.shortname))
_config.StackCategories[categoryName].Remove(item.shortname);
continue;
}
/*if (!_config.StackCategories[categoryName].ContainsKey(item.shortname))
{
Puts($"{item.shortname}, {item.displayName.english}, {item.stackable}");
}*/
if (!_config.StackCategoryMultipliers.ContainsKey(categoryName))
_config.StackCategoryMultipliers[categoryName] = 0;
if (!_config.StackCategories.TryGetValue(categoryName, out stackCategory))
_config.StackCategories[categoryName] = stackCategory = new Dictionary<string, _Items>();
if (stackCategory.ContainsKey(item.shortname))
stackCategory[item.shortname].ItemId = item.itemid;
if (!stackCategory.ContainsKey(item.shortname))
{
stackCategory.Add(item.shortname, new _Items
{
ShortName = item.shortname,
ItemId = item.itemid,
DisplayName = item.displayName.english,
Modified = item.stackable,
});
}
if (_corrections.ContainsKey(item.shortname))
_config.StackCategories[categoryName][item.shortname].DisplayName = _corrections[item.shortname];
/*if (!_corrections.ContainsKey(item.shortname))
{
foreach (var i in _config.StackCategories[categoryName])
{
if (i.Value.DisplayName == item.displayName.english && i.Key != item.shortname)
{
if (!temp.ContainsKey(item.shortname))
temp.Add(item.shortname, item.displayName.english);
}
}
}*/
if (stackCategory.ContainsKey(item.shortname))
_config.StackCategories[categoryName][item.shortname].ShortName = item.shortname;
if (!_defaults.ContainsKey(item.shortname))
{
Puts($"Yo Tell Developer about missing defaults! {item.shortname}, {item.stackable}");
continue;
}
if (_config.StackCategories[categoryName][item.shortname].Disable)
item.stackable = 1;
else if (_config.StackCategoryMultipliers[categoryName] > 0 && _config.StackCategories[categoryName][item.shortname].Modified == _defaults[item.shortname])
item.stackable *= _config.StackCategoryMultipliers[categoryName];
else if (_config.StackCategories[categoryName][item.shortname].Modified > 0 && _config.StackCategories[categoryName][item.shortname].Modified != _defaults[item.shortname])
item.stackable = _config.StackCategories[categoryName][item.shortname].Modified;
if (item.stackable == 0)
{
if (_config.StackCategories[categoryName][item.shortname].Modified <= 0)
_config.StackCategories[categoryName][item.shortname].Modified = _defaults[item.shortname];
item.stackable = _defaults[item.shortname];
PrintError($"Error {item.shortname} server > {item.stackable} config > {_config.StackCategories[categoryName][item.shortname].Modified} \nStack size is set to ZERO this will break the item! Resetting to default!");
}
}
/*Puts($"temp that needs fixed is > {temp.Count}, {temp.ToSentence()}");
if (temp.Count > 0)
LogToFile("Needs_Correcting", $"{temp.ToList()}", this);*/
SaveConfig();
//Puts("First pass check seems fine modifications completed successfully?");
/*
yield return CoroutineEx.waitForSeconds(0.45f);
int corrected = 0;
StringBuilder sb = new StringBuilder();
foreach (ItemDefinition item in ItemManager.itemList)
{
string categoryName = item.category.ToString();
if (_exclude.Contains(item.shortname))
continue;
if (!_defaults.ContainsKey(item.shortname))
continue;
if (item.stackable > 0) continue;
sb.Append($"Error {item.shortname} less or equal to zero! server value {item.stackable}, config value {_config.StackCategories[categoryName][item.shortname].Modified}!? Repairing? || Resetting to default.\n");
corrected++;
if (_config.StackCategories[categoryName][item.shortname].Modified <= 0)
{
_config.StackCategories[categoryName][item.shortname].Modified = _defaults[item.shortname];
item.stackable = _defaults[item.shortname];
}
else
item.stackable = _config.StackCategories[categoryName][item.shortname].Modified;
}
if (corrected > 0)
{
LogToFile("Corrections Log", sb.ToString(), this, true);
Puts($"Corrections Log file created, {corrected} repairs to configuration file & server stacks have completed successfully!");
SaveConfig();
sb.Clear();
}
else
Puts("Final Check Succeeded, No Issues");
*/
Puts("Successfully updated all server stack sizes.");
Updating = null;
yield return null;
}
internal class PluginConfig : SerializableConfiguration
{
[JsonProperty("Revert to Vanilla Stacks on unload (Recommended true if removing plugin)")]
public bool Reset;
[JsonProperty("Disable Ammo/Fuel duplication fix (Recommended false)")]
public bool DisableFix;
[JsonProperty("Enable VendingMachine Ammo Fix (Recommended)")]
public bool VendingMachineAmmoFix = true;
[JsonProperty("Category Stack Multipliers", Order = 4)]
public Dictionary<string, int> StackCategoryMultipliers = new Dictionary<string, int>();
[JsonProperty("Stack Categories", Order = 5)]
public Dictionary<string, Dictionary<string, _Items>> StackCategories = new Dictionary<string, Dictionary<string, _Items>>();
[JsonProperty("Sets editor command")]
public string modifycommand = "stackmodifier";
public void ResetCategory(string cat)
{
if (cat == "All")
{
foreach (var cats in StackCategories.Values)
{
foreach (var i in cats)
i.Value.Modified = _defaults[i.Value.ShortName];
}
foreach (var value in StackCategories.Keys)
StackCategoryMultipliers[value] = 0;
}
else
{
if (!StackCategoryMultipliers.ContainsKey(cat)) return;
StackCategoryMultipliers[cat] = 0;
foreach (var item in StackCategories[cat].Values)
item.Modified = _defaults[item.ShortName];
}
}
public void SetCategory(string cat, int digit)
{
if (cat == "All")
{
foreach (var value in StackCategories.Keys)
StackCategoryMultipliers[value] = digit;
}
else
{
if (!StackCategoryMultipliers.ContainsKey(cat)) return;
StackCategoryMultipliers[cat] = digit;
}
}
public void SetItems(string cat, int digit)
{
if (digit == 0)
digit = 1;
if (cat == "All")
{
foreach (var cats in StackCategories.Values)
{
foreach (var i in cats)
i.Value.Modified = digit;
}
}
else
{
if (!StackCategoryMultipliers.ContainsKey(cat)) return;
foreach (var item in StackCategories[cat].Values)
item.Modified = digit;
}
}
public void ToggleCats(string cat, bool toggle)
{
if (cat == "All")
{
foreach (var cats in StackCategories.Values)
{
foreach (var i in cats)
i.Value.Disable = toggle;
}
}
else
{
if (!StackCategoryMultipliers.ContainsKey(cat)) return;
foreach (var item in StackCategories[cat].Values)
item.Disable = toggle;
}
}
}
private void CategorySearch(ref List<_Items> itemEntries, string searchName, string categoryName)
{
Dictionary<string, _Items> categoryItems;
if (!_config.StackCategories.TryGetValue(categoryName, out categoryItems))
return;
foreach (var itemEntry in categoryItems.Values)
{
if (itemEntry.DisplayName.Contains(searchName, StringComparison.OrdinalIgnoreCase))
itemEntries.Add(itemEntry);
}
}
private void AllCategorySearch(ref List<_Items> itemEntries, string searchName)
{
foreach (var categoryItemEntry in _config.StackCategories.Values)
{
foreach (var itemEntry in categoryItemEntry.Values)
{
if (itemEntry.DisplayName.Contains(searchName, StringComparison.OrdinalIgnoreCase))
itemEntries.Add(itemEntry);
}
}
}
public class _Items
{
public string ShortName;
public int ItemId;
public string DisplayName;
public int Modified;
public bool Disable;
}
#region Updater
internal class SerializableConfiguration
{
public string ToJson() => JsonConvert.SerializeObject(this);
public Dictionary<string, object> ToDictionary() => JsonHelper.Deserialize(ToJson()) as Dictionary<string, object>;
}
private static class JsonHelper
{
public static object Deserialize(string json) => ToObject(JToken.Parse(json));
private static object ToObject(JToken token)
{
switch (token.Type)
{
case JTokenType.Object:
return token.Children<JProperty>()
.ToDictionary(prop => prop.Name, prop => ToObject(prop.Value));
case JTokenType.Array:
return token.Select(ToObject).ToList();
default:
return ((JValue) token).Value;
}
}
}
private bool MaybeUpdateConfig(SerializableConfiguration config)
{
var currentWithDefaults = config.ToDictionary();
var currentRaw = Config.ToDictionary(x => x.Key, x => x.Value);
return MaybeUpdateConfigDict(currentWithDefaults, currentRaw);
}
private bool MaybeUpdateConfigDict(Dictionary<string, object> currentWithDefaults, Dictionary<string, object> currentRaw)
{
bool changed = false;
foreach (var key in currentWithDefaults.Keys)
{
object currentRawValue;
if (currentRaw.TryGetValue(key, out currentRawValue))
{
var defaultDictValue = currentWithDefaults[key] as Dictionary<string, object>;
var currentDictValue = currentRawValue as Dictionary<string, object>;
if (defaultDictValue != null)
{
if (currentDictValue == null)
{
currentRaw[key] = currentWithDefaults[key];
changed = true;
}
else if (MaybeUpdateConfigDict(defaultDictValue, currentDictValue))
changed = true;
}
}
else
{
currentRaw[key] = currentWithDefaults[key];
changed = true;
}
}
return changed;
}
#endregion
#endregion
#region Oxide
protected override void LoadDefaultConfig() => _config = new PluginConfig();
protected override void LoadConfig()
{
base.LoadConfig();
try
{
_config = Config.ReadObject<PluginConfig>();
if (_config == null)
{
PrintWarning($"Generating Config File for {Name}");
throw new JsonException();
}
if (MaybeUpdateConfig(_config))
{
PrintWarning("Configuration appears to be outdated; updating and saving");
SaveConfig();
}
}
catch (Exception ex)
{
PrintWarning("Failed to load config file (is the config file corrupt?) (" + ex.Message + ")");
}
}
protected override void SaveConfig() => Config.WriteObject(_config, true);
private Coroutine Updating = null;
private void Unload()
{
if (_config.Reset)
ResetStacks();
if (Updating != null)
ServerMgr.Instance.StopCoroutine(Updating);
_defaults = null;
}
private void OnServerShutdown()
{
SaveConfig();
_defaults = null;
}
private void Init() => Unsubscribe(nameof(OnItemAddedToContainer));
private void OnServerInitialized()
{
_defaults = _FB;
permission.RegisterPermission(Admin, this);
int count = 0;
foreach (var cat in _config.StackCategories)
foreach (var item in cat.Value.ToArray())
{
if (_defaults.ContainsKey(item.Key)) continue;
count++;
cat.Value.Remove(item.Key);
}
if (count > 0)
{
Puts($"Updated {count} outdated configuration options continuing to phase 2");
SaveConfig();
}
Updating = ServerMgr.Instance.StartCoroutine(CheckConfig());
//cmd.AddChatCommand(_config.modifycommand, this, CmdModify);