C#:
/*
*
* Chat commands:
* /setlvl <lvl> <nickname / steamid>
* /addlvl <lvl> <nickname / steamid>
* /resetlvl <nickname / steamid>
* /showone <nickname / steamid>
* /showall <page:optional>
* /addxp <points> <nickname / steamid>
*
* Console commands:
* setlvl <lvl> <nickname / steamid>
* addlvl <lvl> <nickname / steamid>
* resetlvl <nickname / steamid>
* showone <nickname / steamid>
* showall <page:optional>
* addxp <points> <nickname / steamid>
*
* API:
* object XPCSetLVL(ulong userID, int level) // Returns true if successful, otherwise returns null
* object XPCAddLVL(ulong userID, int level) // Returns true if successful, otherwise returns null
* void XPCResetLVL(ulong userID)
* void XPCAddXP(ulong userID, int xp)
*
*/
using Oxide.Core.Plugins;
using Rust.Xp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using UnityEngine;
namespace Oxide.Plugins {
[Info("XP Control", "miRror", "5.0.0", ResourceId = 2013)]
class XpControl : RustPlugin {
private int maxLevel = 99;
// fix for current game version
private void Init() {
lang.RegisterMessages(new Dictionary<string, string> {
["formataddlvl"]
= "/addlvl <уровень> <ник игрока / стим id>\n con.addlvl <уровень> <ник игрока / стим id> #Deko", ["formatsetlvl"] = "/setlvl <уровень> <ник игрока / стим id>\n con.setlvl <уровень> <ник игрока / стим id> #Deko", ["formatresetlvl"] = "/resetlvl <ник игрока / стим id>\n con.resetlvl <ник игрока / стим id> #Deko", ["formatshowone"] = "/showone <ник игрока / стим id>\n con.showone <ник игрока / стим id> #Deko", ["formataddxp"] = "/addxp <кол-во> <ник игрока стим id>\n con.addxp <кол-во> <ник игрока / стим id> #Deko", ["StringFormat"] = "Формат строки:\n <color=yellow>{0}</color> #Deko", ["NoPlayers"] = "Игрок не найден! #Deko", ["LevelValidNum"] = "Уровень должен быть положительным числом! (уберите минус) #Deko", ["PageValidNum"] = "Страница должна быть положительным числом! #Deko", ["LevelLimit"] = "<color=yellow>Ошибка!</color> Игрок может достичь максимального уровня с этим номером.Текущий уровень игрока: <color=yellow>{0}</color> #Deko", ["AddLevelSuccess"] = "Новый уровень игрока <color=yellow>{0}</color>: <color=yellow>{1}</color> #Deko", ["PointsValidNum"] = "Количество xp должно быть положительным!#Deko", ["AddXpSuccess"] = "Игрок <color=yellow>{0}</color> got <color=yellow>{1} XP</color>#Deko", ["ResetLevelSuccess"] = "Уровень игрока(ов) <color=yellow>{0}</color> был успешно сброшен!", ["FormatValidLevel"] = "Этот уровень не может быть установлен для игрока.Допустимые значения: <color=yellow>1 < x < {0}</color> #Deko", ["SetLevelSuccess"] = "Игрок <color=yellow>{0}</color> got lvl: <color=yellow>{1}</color>", ["ShowOneSuccess"] = "Игрок <color=yellow>{0}</color> has: <color=#24C63D>{1}</color> LVL and <color=#3E82D0>{2}</color> XP #Deko", ["ListPlayers"] = "Список онлайн игроков#Deko", ["ChangePage"] = "Изменить страницу: showall <страница>#Deko", ["Page"] = "страница #Deko", ["CheckConsole"] = "<color=yellow>Проверьте вашу консоль!</color> #Deko"
}
, this);
}
private void Loaded() {
List<string> commands = new List<string>() {
"setlvl", "addlvl", "resetlvl", "showone", "addxp", "showall"
}
;
foreach(string command in commands) {
permission.RegisterPermission("xpcontrol." + command, this);
cmd.AddChatCommand(command, this, "cmdChatHandler");
cmd.AddConsoleCommand("global." + command, this, "cmdConsoleHandler");
}
}
//Other methods
private void Action(BasePlayer player, ConsoleSystem.Arg arg, string cmd, string[] args) {
if(arg != null) player = arg.Player();
Agent agent;
BasePlayer target;
bool isServer = player == null;
int level, xp;
string str, userID = player?.UserIDString;
switch(cmd) {
case "setlvl" : target = GetPlayer(player, arg, cmd, args, 2, isServer, userID);
if(target == null) return;
if(!Int32.TryParse(args[0], out level) || level < 1 || level > maxLevel) {
Reply(player, arg, string.Format(Lang("FormatValidLevel", userID), maxLevel), isServer);
return;
}
agent = BasePlayer.FindXpAgent(target.userID);
agent.Reset();
agent.Add(Definitions.Cheat, Rust.Xp.Config.LevelToXp(level));
Reply(player, arg, string.Format(Lang("SetLevelSuccess", userID), target.displayName, level), isServer);
break;
case "addlvl" : target = GetPlayer(player, arg, cmd, args, 2, isServer, userID);
if(target == null) return;
if(!Int32.TryParse(args[0], out level) || level < 1) {
Reply(player, arg, string.Format(Lang("LevelValidNum", userID)), isServer);
return;
}
agent = BasePlayer.FindXpAgent(target.userID);
int newLevel = (int)agent.CurrentLevel + level;
if(newLevel > maxLevel) {
Reply(player, arg, string.Format(Lang("LevelLimit", userID), (int)agent.CurrentLevel), isServer);
return;
}
agent.Add(Definitions.Cheat, Rust.Xp.Config.LevelToXp(newLevel) - agent.EarnedXp);
Reply(player, arg, string.Format(Lang("AddLevelSuccess", userID), target.displayName, newLevel), isServer);
break;
case "resetlvl" : target = GetPlayer(player, arg, cmd, args, 1, isServer, userID);
if(target == null) return;
BasePlayer.FindXpAgent(target.userID).Reset();
Reply(player, arg, string.Format(Lang("ResetLevelSuccess", userID), target.displayName), isServer);
break;
case "showone" : target = GetPlayer(player, arg, cmd, args, 1, isServer, userID);
if(target == null) return;
agent = BasePlayer.FindXpAgent(target.userID);
Reply(player, arg, string.Format(Lang("ShowOneSuccess", userID), target.displayName, (int)agent.CurrentLevel, (int)agent.UnspentXp), isServer);
break;
case "showall" : if(!isServer && !player.IsAdmin() && !permission.UserHasPermission(player.UserIDString, "xpcontrol." + cmd)) return;
int cntPlayers = BasePlayer.activePlayerList.Count;
int currentPage = 1;
int playersOnPage = 50;
int allPages = (int)Math.Ceiling(1.0f * cntPlayers / playersOnPage);
if(cntPlayers == 0) {
Reply(player, arg, string.Format(Lang("NoPlayers", userID)), isServer);
return;
}
if(args.Length > 0 && !Int32.TryParse(args[0], out currentPage) || currentPage < 1 || currentPage > allPages) {
Reply(player, arg, string.Format(Lang("PageValidNum", userID)), isServer);
return;
}
if(!isServer) player.SendConsoleCommand("clear");
// fix for bad parsing tags
str = "<color=#C65624>" + new String('-', 70) + "\n" + Lang("ListPlayers", userID).PadRight(26) + ("<color=#24C63D>LVL</color>").PadRight(50) + ("<color=#3E82D0>XP</color>").PadRight(28) + "| " + Lang("Page", userID) + $" {currentPage}/{allPages} |\n" + new String('-', 70) + "</color>\n";
List<BasePlayer> players = BasePlayer.activePlayerList.GetRange((currentPage - 1) * playersOnPage, currentPage == 1 ? Math.Min(cntPlayers, playersOnPage) : (cntPlayers - ((currentPage - 1) * playersOnPage)));
foreach(BasePlayer t in players) str += $"<color=orange>{t.displayName, -25}</color> <color=#24C63D>{t.xp.CurrentLevel, -25:#;minus #}</color> <color=#3E82D0>{t.xp.UnspentXp:#;minus #}</color>\n";
str += "<color=#C65624>" + new String('-', 70) + "\n" + Lang("ChangePage", userID) + "\n" + new String('-', 70) + "</color>\n";
if(isServer) Reply(player, arg, "\n" + str, isServer);
else {
if(arg == null) SendReply(player, Lang("CheckConsole", userID));
PrintToConsole(player, str);
}
break;
case "addxp" : target = GetPlayer(player, arg, cmd, args, 2, isServer, userID);
if(target == null) return;
if(!Int32.TryParse(args[0], out xp) || xp < 1) {
Reply(player, arg, string.Format(Lang("PointsValidNum", userID)), isServer);
return;
}
BasePlayer.FindXpAgent(target.userID).Add(Definitions.Cheat, xp);
Reply(player, arg, string.Format(Lang("AddXpSuccess", userID), target.displayName, xp), isServer);
break;
}
}
private BasePlayer GetPlayer(BasePlayer player, ConsoleSystem.Arg arg, string cmd, string[] args, int needArgs, bool isServer, string userID) {
if(!isServer && !player.IsAdmin() && !permission.UserHasPermission(player.UserIDString, "xpcontrol." + cmd)) return null;
if(args.Length < needArgs) {
Reply(player, arg, string.Format(Lang("StringFormat", userID), Lang("format" + cmd, userID)), isServer);
return null;
}
string strNameOrIDOrIP = string.Join(" ", needArgs > 1 ? args.Skip(1).ToArray() : args);
BasePlayer target = rust.FindPlayer(strNameOrIDOrIP);
if(target == null) {
Reply(player, arg, Lang("NoPlayers", userID), isServer);
return null;
}
return target;
}
private string Lang(string key, string userID) => lang.GetMessage(key, this, userID);
private void Reply(BasePlayer player, ConsoleSystem.Arg arg, string message, bool isServer) {
if(isServer) message = Regex.Replace(message, "<.*?>", string.Empty);
if(arg == null) SendReply(player, message);
else SendReply(arg, message);
}
//Chat commands
private void cmdChatHandler(BasePlayer player, string cmd, string[] args) => Action(player, null, cmd, args);
//Console commands
private void cmdConsoleHandler(ConsoleSystem.Arg arg) => Action(null, arg, arg.cmd.name, arg.HasArgs() ? arg.Args : new string[0]);
//API
[HookMethod("XPCSetLVL")]
public object XPCSetLVL(ulong userID, int level) {
if(level < 1 || level > maxLevel) return null;
Agent agent = BasePlayer.FindXpAgent(userID);
agent.Reset();
agent.Add(Definitions.Cheat, Rust.Xp.Config.LevelToXp(level));
return true;
}
[HookMethod("XPCAddLVL")]
public object XPCAddLVL(ulong userID, int level) {
Agent agent = BasePlayer.FindXpAgent(userID);
int newLevel = (int)agent.CurrentLevel + level;
if(newLevel > maxLevel) return null;
agent.Add(Definitions.Cheat, Rust.Xp.Config.LevelToXp(newLevel) - agent.EarnedXp);
return true;
}
[HookMethod("XPCResetLVL")]
public void XPCResetLVL(ulong userID) => BasePlayer.FindXpAgent(userID).Reset();
[HookMethod("XPCAddXP")]
public void XPCAddXP(ulong userID, int xp) => BasePlayer.FindXpAgent(userID).Add(Definitions.Cheat, xp);
}
}