Для исправления ошибки "ItemCraftTask' does not contain a definition for 'owner'", попробуем найти другой способ обращения к игроку в задаче крафта. Вот возможное исправление:
C#:
private void OnItemCraftFinished(ItemCraftTask task, Item item)
{
BasePlayer player = task.blueprint.user;
if (task.skinID == 0)
{
if (!StoredData[player.userID].Skins.ContainsKey(item.info.shortname) || !permission.UserHasPermission(player.UserIDString, "xskinmenu.craft")) return;
if (!StoredData[player.userID].ChangeSG && StoredData[player.userID].ChangeSC)
{
SetSkinCraftGive(player, item);
}
}
}
Здесь я заменил
task.owner
на
task.blueprint.user
для получения игрока, связанного с задачей крафта. Попробуйте использовать это исправление в вашем коде и проверьте, помогает ли оно устранить ошибку.
Если у вас остались вопросы или нужна дополнительная помощь, не стесняйтесь обращаться. Я готов помочь!
Дороботай код
using System;
using System.Collections.Generic;
namespace Oxide.Plugins {
[Info("Anti Loot Attack", "DropZxc", "0.0.1")]
class AntiLootAttack : RustPlugin {
#region Comment
/*
Данный плагин создан для сервера "GOLD RUST".
*/
#endregion
#region Fields
// Буфер типа (ИД игрока, ИД предмета) создан для хранения последнего дропнутого предмета
private Dictionary<ulong, int> LastItemDropped = new Dictionary<ulong, int>();
// Буфер типа (ИД игрока, кол-во) создан для хранения количества повторов дропа предмета
private Dictionary<ulong, int> LastItemDroppedMultiply = new Dictionary<ulong, int>();
// Буфер (ИД игрока, временной штамп) создан для высчета кд между дропом
private Dictionary<ulong, int> LastItemDroppedTime = new Dictionary<ulong, int>();
#endregion
#region Utils
int GetTimestamp()
{
return (int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds;
}
#endregion
#region Functions
// Метод для обновления буфера с сброшенным предметом
void UpdateDroppedItem(ulong userId, int itemId)
{
if(LastItemDropped.ContainsKey(userId)) {
LastItemDropped[userId] = itemId;
} else {
LastItemDropped.Add(userId, itemId);
}
}
// Метод для обновления буфера с множетелем сброшенного предмета
void UpdateDroppedItemMultiply(ulong userId, int multiply)
{
if(LastItemDroppedMultiply.ContainsKey(userId)) {
LastItemDroppedMultiply[userId] = multiply;
} else {
LastItemDroppedMultiply.Add(userId, multiply);
}
}
// Метод для обновления буфера с штампом текущего времени
void UpdateDroppedItemTime(ulong userId)
{
int timeStamp = GetTimestamp();
if(LastItemDroppedTime.ContainsKey(userId)) {
LastItemDroppedTime[userId] = timeStamp;
} else {
LastItemDroppedTime.Add(userId, timeStamp);
}
}
#endregion
#region Hooks
void OnItemDropped(Item item, BaseEntity entity)
{
// Проверка равняется ли айтем нулю (возможно уже удален сетью или другим хуком, поэтому да)
if(item == null) return;
// Получаем дропнувшего игрока
BasePlayer player = item.GetOwnerPlayer();
if(player == null) return;
// ИД игрока
ulong userId = player.userID;
// ИД предмета
int itemId = item.info.itemid;
// Проверяем ли содержит буфер ИД игрока
if(LastItemDropped.ContainsKey(userId)) {
// Проверяем соответствует-ли предмет из буффера текущему
if(LastItemDropped[userId] == itemId) {
// Проверяем не прошел ли Timeout (15 секунд)
bool isTimeout = ((GetTimestamp() - LastItemDroppedTime[userId]) > 15);
// Если Timeout не прошел, то добавляется +1 мультиплай, если прошел то ставится единица
if(!isTimeout) {
UpdateDroppedItemMultiply(userId, LastItemDroppedMultiply[userId] += 1);
} else {
UpdateDroppedItemMultiply(userId, 1);
}
// Проверяем если мультиплай больше 10 то предмет удаляется
if(LastItemDroppedMultiply[userId] > 10) {
Puts($"У игрока {player.displayName} (SteamID: {userId}) прошла попытка диспавна {item.info.displayName.translated} / {itemId} в кол-ве {item.amount}");
entity.Kill();
}
} else {
// Если предмет не является текущим предметом из буфера то записываем его и выставляем мультиплай 1
UpdateDroppedItem(userId, itemId);
UpdateDroppedItemMultiply(userId, 1);
}
} else {
// Если игрока нет в буфере то добавляем дропнутый предмет и выставляем ему мультиплай 1
UpdateDroppedItem(userId, itemId);
UpdateDroppedItemMultiply(userId, 1);
}
UpdateDroppedItemTime(userId);
}
#endregion
#region Commands
[ConsoleCommand("drop_clean")]
void CleanDropCommand(ConsoleSystem.Arg arg)
{
// Проверка на админку
bool allowUse = (arg.IsAdmin || arg.IsRcon);
if(!allowUse) {
arg.ReplyWith("Для использования комманды необходимы права администратора!");
return;
}
// Форечим массив с дропнутыми предметами
foreach(DroppedItem item in UnityEngine.Object.FindObjectsOfType<DroppedItem>()) {
// Если айтем мертв, то пропускаем
if(item == null || item.IsDestroyed) continue;
item.Kill();
}
}
#endregion
}
}