Hello,
I have this plugin but i get error after last update of Rust game
// Requires: MonumentFinder
using Newtonsoft.Json;
using Oxide.Core.Plugins;
using System.Collections.Generic;
using UnityEngine;
using System;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries.Covalence;
namespace Oxide.Plugins
{
[Info("Puzzle Points", "Rustonauts", "1.3.2")]
[Description("Rewards players with scrap, economics, or RP for swiping puzzle cards and completing missions. Broadcasting this is defaulted true.")]
class PuzzlePoints : RustPlugin
{
MonumentFinder MonumentFinder;
[PluginReference]
private Plugin Economics, ServerRewards, MonumentLock, MonumentNames, SuperCard;
private double economicsAmount;
private int scrapAmount;
private int rewardsAmount;
private string cardtype = "green";
private List<Dictionary<string, object>> _monuments;
private Configuration configData;
private StoredData storedData;
#region Configuration
class Configuration
{
[JsonProperty(PropertyName = "Show Console Messages")]
public bool consoleMessages = true;
[JsonProperty(PropertyName = "Show Global Chat Monument Messages (eg. Player swipped card at Launch)")]
public bool broadcastSwipe = true;
[JsonProperty(PropertyName = "Use Scrap")]
public bool useScrap = true;
[JsonProperty(PropertyName = "Use Economics")]
public bool useEconomics = true;
[JsonProperty(PropertyName = "Use Server Rewards")]
public bool useServerRewards = true;
[JsonProperty(PropertyName = "Debug Mode")]
public bool debugMode = false;
[JsonProperty(PropertyName = "Red Card Swipe Scrap")]
public int redCardScrap = 300;
[JsonProperty(PropertyName = "Blue Card Swipe Scrap")]
public int blueCardScrap = 100;
[JsonProperty(PropertyName = "Green Card Swipe Scrap")]
public int greenCardScrap = 25;
[JsonProperty(PropertyName = "Red Card Swipe RP")]
public int redCardRP = 3;
[JsonProperty(PropertyName = "Blue Card Swipe RP")]
public int blueCardRP = 2;
[JsonProperty(PropertyName = "Green Card Swipe RP")]
public int greenCardRP = 1;
[JsonProperty(PropertyName = "Red Card Swipe Money")]
public double redCardMoney = 300.00;
[JsonProperty(PropertyName = "Blue Card Swipe Money")]
public double blueCardMoney = 150.00;
[JsonProperty(PropertyName = "Green Card Swipe Money")]
public double greenCardMoney = 50.00;
[JsonProperty(PropertyName = "Cooldown: Amount of time (secs) a player must wait before getting rewarded to avoid swipe spam")]
public int cooldown = 600;
}
private void SaveConfig(Configuration config)
{
Config.WriteObject(config, true);
}
private void Init()
{
MonumentFinder = (MonumentFinder)Manager.GetPlugin("MonumentFinder");
configData = Config.ReadObject<Configuration>();
LoadData();
}
protected override void LoadDefaultConfig()
{
configData = new Configuration();
SaveConfig(configData);
}
#endregion Configuration
#region DataFile
private class MSession
{
[JsonProperty("Player Id")]
public string player_id;
[JsonProperty("Session started_at")]
private string started_at;
public MSession(string _player_id)
{
player_id = _player_id;
started_at = DateTime.Now.ToString();
}
public string GetPlayerId() {return player_id;}
public BasePlayer GetPlayer(string _player_id){return BasePlayer.FindAwakeOrSleeping(_player_id);}
public bool InCooldown(int _cooldown)
{
DateTime dt1 = DateTime.Now;
DateTime dt2 = DateTime.Parse(started_at);
TimeSpan lock_time = dt1-dt2;
if(Math.Truncate(lock_time.TotalSeconds) < _cooldown) return true;
return false;
}
}
private class StoredData
{
public List<MSession> m_sessions { get; set; } = new List<MSession>();
public StoredData()
{
}
public StoredData(List<MSession> _sessions)
{
m_sessions = _sessions;
}
}
private void LoadData()
{
try
{
Puts("loading datafile..{0}", Name.ToString());
storedData = Interface.Oxide.DataFileSystem.ReadObject<StoredData>(Name);
Puts("Datafile loaded");
}
catch
{
storedData = null;
}
if (storedData == null)
{
Puts("-- no datafile, creating new..");
ClearData();
}
}
private void SaveData()
{
Puts("-- saving data..");
Interface.Oxide.DataFileSystem.WriteObject(Name, storedData);
Puts("-- data saved!");
}
private void ClearData()
{
storedData = new StoredData();
SaveData();
}
#endregion
#region API_Hooks
object OnCardSwipe(CardReader cardReader, Keycard card, BasePlayer player)
{
Puts("OnCardSwipe works!");
return null;
}
//if still in cooldown, abort rewards
foreach(MSession _session in storedData.m_sessions) {
//player has a session
if(_session.player_id == player.UserIDString) {
//if in cooldown, abort
if(_session.InCooldown(configData.cooldown)) return null;
//otherwise, remove session and continue w/ rewards
storedData.m_sessions.Remove(_session);
SaveData();
}
}
bool isOn = (bool) cardReader.IsOn();
var playerId = player.userID.ToString();
var gridPosition = GetGridPosition(player.ServerPosition);
var item = card.GetItem();
var dictMonument = IsInMonument(player);
var _shortName = dictMonument["ShortName"].ToString();
if(configData.debugMode || (!isOn && item.conditionNormalized > 0f) )
{
//make sure the card reader and card are the same access levels
if (cardReader.accessLevel == card.accessLevel || card.accessLevel == 0)
{
var playerName = player.displayName;
//assigning the correct reward values from config based on card
if(cardReader.accessLevel == 1)
{
scrapAmount = configData.greenCardScrap;
economicsAmount = configData.greenCardMoney;
rewardsAmount = configData.greenCardRP;
cardtype = GetLang("GreenCardLabel", playerId);
}
else if(cardReader.accessLevel == 2)
{
scrapAmount = configData.blueCardScrap;
economicsAmount = configData.blueCardMoney;
rewardsAmount = configData.blueCardRP;
cardtype = GetLang("BlueCardLabel", playerId);
}
else
{
scrapAmount = configData.redCardScrap;
economicsAmount = configData.redCardMoney;
rewardsAmount = configData.redCardRP;
cardtype = GetLang("RedCardLabel", playerId);
}
//if we're not using MonumentLock, or if we are and cardswipe passes, value is null
if (Interface.Call("OnPPSwipe", player, cardtype, cardReader, _shortName, gridPosition) != null)
{
return 1;
}
//all good, so lets add a new session
storedData.m_sessions.Add(new MSession(player.UserIDString));
SaveData();
Reward(player);
BroadcastSwipe(player, cardtype);
}
}
return null;
}
#endregion API_Hooks
#region PuzzlePointsCore
private void Reward(BasePlayer player)
{
//are we using economics and has it been turned on
if (UseEconomics())
{
//api call to economics
bool isDeposit = (bool) Economics.Call("Deposit", player.UserIDString, (double)economicsAmount);
if(configData.consoleMessages && isDeposit)
{
SendReply(player, GetLang("EconomicsAwarded", player.UserIDString, economicsAmount, cardtype));
}
}
//are we rewarding with scrap
if(configData.useScrap)
{
Puts($"giving scrap: {scrapAmount}");
//api call to gift scrap
player.inventory.GiveItem(ItemManager.CreateByItemID(-932201673, scrapAmount));
if(configData.consoleMessages)
{
SendReply(player, GetLang("ScrapAwarded", player.UserIDString, scrapAmount, cardtype));
}
}
//are we using ServerRewards and has it been turned on
if (UseRewards())
{
//api call to server rewards
bool isAdd = (bool) ServerRewards.Call("AddPoints", player.UserIDString, (int)rewardsAmount);
if(configData.consoleMessages && isAdd)
{
SendReply(player, GetLang("PointsAwarded", player.UserIDString, rewardsAmount, cardtype));
}
}
}
private void BroadcastSwipe(BasePlayer player, string cardType)
{
var dictMonument = IsInMonument(player);
var gridPosition = GetGridPosition(player.ServerPosition);
var _shortName = dictMonument["ShortName"].ToString();
if(configData.broadcastSwipe && MonumentLock == null)
{
//PrintToChat($"{GetLang("CardSwipedAt", player.UserIDString, player.displayName, cardType, GetDisplayName(_shortName), gridPosition)}");
BroadcastToChat("CardSwipedAt", player.displayName, cardType, GetDisplayName(_shortName), gridPosition);
}
if(configData.consoleMessages)
{
Puts(GetLang("CardSwipedAt", null, player.displayName, cardType, GetDisplayName(_shortName), gridPosition));
}
}
private Dictionary<string, object> IsInMonument(BasePlayer player)
{
var dictClosestMonument = MonumentFinder?.Call("API_GetClosestMonument", player.ServerPosition) as Dictionary<string, object>;
var IsInBounds = ((Func<Vector3, bool>)dictClosestMonument["IsInBounds"]).Invoke(player.ServerPosition);
if(IsInBounds) return dictClosestMonument;
return null;
}
#endregion PuzzlePointsCore
#region Helpers
private void BroadcastToChat(string langkey, params object[] args)
{
for (int i=0; i < BasePlayer.activePlayerList.Count; i++)
{
BasePlayer player = BasePlayer.activePlayerList[i];
player.ChatMessage(GetLang(langkey, player.UserIDString, args));
}
}
private string GetDisplayName(string _shortName)
{
if(UseMonumentNames()) return MonumentNames.Call("GetDisplayName", _shortName) as string;
return _shortName;
}
private bool UseMonumentNames()
{
if(MonumentNames == null) return false;
if(!MonumentNames.IsLoaded) return false;
return true;
}
private bool UseEconomics()
{
if(!configData.useEconomics) return false;
if(Economics == null) return false;
if(!Economics.IsLoaded) return false;
return true;
}
private bool UseRewards()
{
if(!configData.useServerRewards) return false;
if(ServerRewards == null) return false;
if(!ServerRewards.IsLoaded) return false;
return true;
}
//copied from DiscordLogger
private string GetGridPosition(Vector3 position) => PhoneController.PositionToGridCoord(position);
//copied from Give
private string GetLang(string langKey, string playerId = null, params object[] args)
{
return string.Format(lang.GetMessage(langKey, this, playerId), args);
}
#endregion Helpers
#region Localization
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["EconomicsAwarded"] = "${0} awarded for {1} card swipe!",
["PointsAwarded"] = "{0} Reward Points awarded for {1} card swipe!",
["ScrapAwarded"] = "{0} scrap awarded for {1} card swipe!",
["CardSwipedAt"] = "{0} swiped a {1} card at {2} ({3})!",
["GreenCardLabel"] = "green",
["BlueCardLabel"] = "blue",
["RedCardLabel"] = "red",
}, this);
}
#endregion Localization
}
}
Someone can help me