C#:
using System.Collections.Generic;
using System.Linq;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("PainUnlockAll", "PainRust", "1.9.0")]
[Description("Разблокирует DLC + Steam Inventory + скины при крафте + wear DLC шмоток")]
public class PainUnlockAll : RustPlugin
{
private static readonly HashSet<string> DLCItemShortnames = new HashSet<string>
{
// ===== Sunburn Pack (пляжное DLC) =====
"abovegroundpool", "paddlingpool",
"beachchair", "beachparasol", "beachtable", "beachtowel",
"boogieboard", "innertube", "innertube.horse", "innertube.unicorn",
"sunglasses", "sunglasses02shadow", "sunglasses02black", "sunglasses02red",
"sunglasses03chrome", "sunglasses03gold", "sunglasses03blue",
"gun.water", "pistol.water",
"tool.instant_camera",
"photoframe.landscape", "photoframe.portrait",
"photoframe.large", "photoframe.exlarge",
"secretlabchair",
// ===== Instruments Pack =====
"fun.bass", "fun.cowbell", "drumkit", "fun.flute",
"fun.jerrycanguitar", "piano", "fun.tambourine",
"fun.trumpet", "fun.tuba", "xylophone",
"fun.guitar", "fun.piano",
// ===== Halloween =====
"skull.trophy", "skull.trophy.jar", "skull.trophy.jar2", "skull.trophy.table",
"skull.fire.pit", "scarecrow", "ghostsheet",
"skullspikes.candles", "skullspikes.pumpkin",
"graveyard.fence", "cursed.cauldron", "hallowen.lootbag.small",
"lootbag.small", "candle.hat", "spookyspeaker",
"halloween.mummysuit", "halloween.surgeonsuit", "halloween.scarecrowsuit",
// ===== Christmas =====
"snowman", "xmas.present.small", "xmas.present.medium", "xmas.present.large",
"xmas.lightstring", "xmas.advent", "xmas.tree", "xmas.door.wreath",
"xmas.window.garland", "xmas.double.door.garland", "xmas.stocking",
"candycaneclub", "snowballgun", "snowball", "santahat",
"attire.snowman.helmet", "attire.reindeer.headband",
// ===== Lunar New Year =====
"newyeargong", "lunar.lantern.red", "lunar.lantern.white",
"chineselantern", "chineselantern.white",
"firework.romancandle.blue", "firework.romancandle.red",
"firework.romancandle.green", "firework.romancandle.violet",
"firework.romancandle.champagne",
"firework.volcano", "firework.volcano.violet", "firework.volcano.gold",
"firework.mortar.blue", "firework.mortar.red", "firework.mortar.green",
"firework.mortar.violet", "firework.mortar.champagne",
// ===== Easter =====
"easterdoor.garland", "egg.basket", "easter.bunny.ears", "rabbit.onesie",
"attire.bunny.onesie",
// ===== Misc / Inventory items =====
"mask.bandana", "mask.balaclava",
"hat.cap", "hat.boonie", "hat.beenie", "hat.miner",
"hat.candle", "hat.wolf", "deer.skull.mask",
"attire.hide.skirt", "attire.hide.boots", "attire.hide.helterneck",
"attire.hide.pants", "attire.hide.poncho", "attire.hide.vest",
"attire.ninja.suit", "attire.banditscarf",
"clatter.helmet", "tunic.gladiator",
"movembermoustachecard", "movembermoustache", "twitchhat",
"shorts.green", "shorts.blue", "shorts.red", "shorts.pink",
"waterpipe",
"diving.mask", "diving.fins", "diving.tank", "diving.wetsuit",
"speargun", "spear.speargun", "fishingrod.handmade",
"toolgun",
"sofa", "sofa.pattern", "rug", "rug.bear", "table", "chair",
"horseshoes", "deck.of.cards",
};
private List<ItemBlueprint> _dlcBlueprints = new List<ItemBlueprint>();
#region [Init]
private void OnServerInitialized()
{
int detectedByFlags = 0;
int detectedByName = 0;
foreach (var bp in ItemManager.bpList)
{
try
{
if (bp == null || bp.targetItem == null) continue;
bool isDlcOrInventory = bp.NeedsSteamItem
|| bp.NeedsSteamDLC
|| bp.targetItem.steamItem != null
|| bp.targetItem.steamDlc != null;
if (isDlcOrInventory)
{
if (!_dlcBlueprints.Contains(bp))
{
_dlcBlueprints.Add(bp);
detectedByFlags++;
}
}
}
catch { }
}
foreach (var name in DLCItemShortnames)
{
try
{
var def = ItemManager.FindItemDefinition(name);
if (def?.Blueprint == null) continue;
if (!_dlcBlueprints.Contains(def.Blueprint))
{
_dlcBlueprints.Add(def.Blueprint);
detectedByName++;
}
}
catch { }
}
Puts($"[PainUnlockAll] Cached DLC BPs: {_dlcBlueprints.Count} (byFlags={detectedByFlags}, byName={detectedByName})");
int patched = 0;
foreach (var bp in _dlcBlueprints)
{
try
{
bp.NeedsSteamItem = false;
bp.userCraftable = true;
if (bp.targetItem != null)
{
bp.targetItem.steamItem = null;
bp.targetItem.steamDlc = null;
}
patched++;
}
catch { }
}
Puts($"[PainUnlockAll] Blueprints patched: {patched}");
int dlcPatched = 0;
foreach (var dlc in Resources.FindObjectsOfTypeAll<SteamDLCItem>())
{
try { dlc.bypassLicenseCheck = true; dlcPatched++; }
catch { }
}
Puts($"[PainUnlockAll] SteamDLCItem bypassLicenseCheck=true: {dlcPatched}");
int uwPatched = 0;
foreach (var uw in Resources.FindObjectsOfTypeAll<Underwear>())
{
try
{
if (uw == null) continue;
if (uw.steamItem != null) uw.steamItem = null;
if (uw.steamDLC != null) uw.steamDLC = null;
if (uw.adminOnly) uw.adminOnly = false;
uwPatched++;
}
catch { }
}
Puts($"[PainUnlockAll] Underwear cleared: {uwPatched}");
foreach (var player in BasePlayer.activePlayerList)
UnlockDLCForPlayer(player);
Puts("[PainUnlockAll] Initialization complete!");
}
#endregion
#region [Hooks]
private void OnPlayerConnected(BasePlayer player)
{
timer.Once(2f, () => UnlockDLCForPlayer(player));
}
private void OnPlayerSleepEnded(BasePlayer player)
{
timer.Once(1f, () => UnlockDLCForPlayer(player));
}
// ===== РАЗРЕШАЕМ НАДЕВАТЬ DLC ШМОТКИ (мумия, пляжное и т.д.) =====
private object OnPlayerWear(BasePlayer player, Item item)
{
return null;
}
private object CanWearItem(PlayerInventory inventory, Item item, int targetSlot)
{
return null;
}
// ===== СКИНЫ: применяем после завершения крафта =====
// НЕ используем CanCraft / OnItemCraft - они ломают research table!
private void OnItemCraftFinished(ItemCraftTask task, Item item)
{
if (task == null || item == null) return;
try
{
ulong skinId = (ulong)task.skinID;
if (skinId > 0 && item.skin != skinId)
{
item.skin = skinId;
var held = item.GetHeldEntity();
if (held != null)
{
held.skinID = skinId;
held.SendNetworkUpdate();
}
item.MarkDirty();
Puts($"[Skin] Applied skinid={skinId} to {item.info.shortname}");
}
}
catch (System.Exception ex)
{
PrintWarning($"[Skin] error: {ex.Message}");
}
}
#endregion
#region [Methods]
private void UnlockDLCForPlayer(BasePlayer player)
{
if (player == null || !player.IsConnected) return;
if (player.blueprints == null) return;
try
{
int unlocked = 0;
foreach (var bp in _dlcBlueprints)
{
if (bp?.targetItem == null) continue;
if (!player.blueprints.IsUnlocked(bp.targetItem))
{
player.blueprints.Unlock(bp.targetItem);
unlocked++;
}
}
if (unlocked > 0)
{
player.SendNetworkUpdateImmediate();
if (player.Connection != null)
player.ClientRPCPlayer(null, player, "UnlockedBlueprint", 0);
Puts($"[PainUnlockAll] Unlocked {unlocked} DLC BPs for {player.displayName}");
}
}
catch (System.Exception ex)
{
PrintWarning($"[PainUnlockAll] error: {ex.Message}");
}
}
[ChatCommand("unlockdlc")]
private void CmdUnlockDLC(BasePlayer player, string command, string[] args)
{
if (!player.IsAdmin) return;
UnlockDLCForPlayer(player);
player.ChatMessage("<color=#00ff00>DLC разблокированы!</color>");
}
[ChatCommand("finddlc")]
private void CmdFindDlc(BasePlayer player, string command, string[] args)
{
if (!player.IsAdmin) return;
try
{
var allDefs = ItemManager.GetItemDefinitions();
int total = 0;
player.ChatMessage("<color=#00ff00>=== ITEMS с DLC признаками ===</color>");
foreach (var def in allDefs)
{
if (def == null) continue;
bool hasSteamItem = def.steamItem != null;
bool hasSteamDlc = def.steamDlc != null;
bool bpHasFlags = def.Blueprint != null &&
(def.Blueprint.NeedsSteamItem || def.Blueprint.NeedsSteamDLC);
if (hasSteamItem || hasSteamDlc || bpHasFlags)
{
string info = $"{def.shortname}";
if (hasSteamItem) info += " [steamItem]";
if (hasSteamDlc) info += $" [DLC:{def.steamDlc?.dlcAppID}]";
if (bpHasFlags) info += " [BP-flags]";
Puts($"[FindDLC] {info}");
total++;
}
}
player.ChatMessage($"<color=#ffff00>Найдено: {total} (см. server.log)</color>");
}
catch (System.Exception ex)
{
player.ChatMessage($"<color=#ff0000>Error: {ex.Message}</color>");
}
}
[ChatCommand("searchitem")]
private void CmdSearchItem(BasePlayer player, string command, string[] args)
{
if (!player.IsAdmin) return;
if (args.Length < 1) { player.ChatMessage("Usage: /searchitem <часть_имени>"); return; }
string query = args[0].ToLower();
int found = 0;
foreach (var def in ItemManager.GetItemDefinitions())
{
if (def == null) continue;
if (def.shortname.ToLower().Contains(query) ||
(def.displayName?.english?.ToLower().Contains(query) ?? false))
{
player.ChatMessage($"<color=#ffff00>{def.shortname}</color> = {def.displayName?.english}");
found++;
if (found >= 20) break;
}
}
if (found == 0) player.ChatMessage("<color=#ff0000>Не найдено</color>");
}
[ChatCommand("toolgun")]
private void CmdToolgun(BasePlayer player, string command, string[] args)
{
if (!player.IsAdmin) return;
var def = ItemManager.FindItemDefinition("toolgun");
if (def == null) { player.ChatMessage("<color=#ff0000>Tool Gun не найден!</color>"); return; }
var item = ItemManager.Create(def, 1);
if (item != null) { player.GiveItem(item); player.ChatMessage("<color=#00ff00>Tool Gun выдан!</color>"); }
}
[ChatCommand("mybp")]
private void CmdMyBP(BasePlayer player, string command, string[] args)
{
if (!player.IsAdmin) return;
try
{
int total = 0, defaultCount = 0, dlcCount = 0, otherCount = 0;
foreach (var bp in ItemManager.bpList)
{
if (bp == null || bp.targetItem == null) continue;
if (player.blueprints.IsUnlocked(bp.targetItem))
{
total++;
if (bp.defaultBlueprint) defaultCount++;
else if (_dlcBlueprints.Contains(bp)) dlcCount++;
else otherCount++;
}
}
player.ChatMessage($"<color=#00ff00>Изучено всего: {total}</color>");
player.ChatMessage($"<color=#ffff00> Default: {defaultCount}</color>");
player.ChatMessage($"<color=#ffff00> DLC: {dlcCount}</color>");
player.ChatMessage($"<color=#ff8800> Other: {otherCount}</color>");
}
catch { }
}
[ChatCommand("resetbp")]
private void CmdResetBP(BasePlayer player, string command, string[] args)
{
if (!player.IsAdmin) return;
try
{
if (player.blueprints == null) return;
player.blueprints.Reset();
player.ChatMessage("<color=#ffff00>[1/3]</color> Сброс выполнен");
timer.Once(1f, () =>
{
if (player == null || !player.IsConnected) return;
int defCount = 0;
foreach (var bp in ItemManager.bpList)
{
if (bp?.targetItem == null) continue;
if (bp.defaultBlueprint && !player.blueprints.IsUnlocked(bp.targetItem))
{
player.blueprints.Unlock(bp.targetItem);
defCount++;
}
}
player.ChatMessage($"<color=#ffff00>[2/3]</color> Default BP: {defCount}");
});
timer.Once(2f, () =>
{
if (player == null || !player.IsConnected) return;
UnlockDLCForPlayer(player);
player.ChatMessage("<color=#ffff00>[3/3]</color> DLC восстановлены");
});
timer.Once(3f, () =>
{
if (player == null || !player.IsConnected) return;
try
{
player.SendNetworkUpdateImmediate();
if (player.Connection != null)
player.ClientRPCPlayer(null, player, "UnlockedBlueprint", 0);
}
catch { }
player.ChatMessage("<color=#00ff00>✅ ГОТОВО!</color>");
});
}
catch (System.Exception ex)
{
player.ChatMessage($"<color=#ff0000>{ex.Message}</color>");
}
}
#endregion
}
}