C#:
// Reference: System.Drawing
using Network;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Oxide.Plugins {
[Info("RustMap", "", "1.2.7")]
class RustMap : RustPlugin {
#region Classes
[PluginReference]
Plugin Clans;
[PluginReference]
Plugin Friends;
[PluginReference]
Plugin MutualPermission;
[PluginReference]
Plugin NTeleportation;
[PluginReference]
Plugin Teleport;
[PluginReference]
Plugin Teleportation;
[PluginReference]
Plugin CustomQuarry;
[PluginReference]
Plugin HomesGUI;
class MapMarker {
public Transform transform;
public int Rotation = -1;
public Vector2 anchorPosition {
get {
return m_Instance.ToScreenCoords(position);
}
}
public Vector2 position = Vector2.zero;
public string name;
public string png;
public bool rotSupport = false;
public string text;
public float size;
public float alpha;
public int fontsize;
public ulong counter = 0;
public bool inMap = true;
protected MapMarker(Transform transform) {
this.transform = transform;
}
public virtual bool NeedRedraw() {
if (transform == null) return false;
var lastRot = Rotation;
if (rotSupport) Rotation = GetRotation(transform.eulerAngles.y);
var lastPos = position;
position = transform.position;
position.y = 0;
if (rotSupport && Rotation != lastRot) {
position = lastPos;
return true;
}
if (Vector3.Distance(position, lastPos) > 0.5) return true;
position = lastPos;
return false;
}
public static MapMarker Create(Transform transform) {
return new MapMarker(transform);
}
}
class MapPlayer : MapMarker {
public BasePlayer player;
public List<MapPlayer> clanTeam = new List<MapPlayer>();
protected MapPlayer(BasePlayer player) : base(player.transform) {
this.player = player;
}
public override bool NeedRedraw() {
var lastRot = Rotation;
if (player == null || transform == null) return false;
Rotation = GetRotation(player.eyes.rotation.eulerAngles.y);
var lastPos = position;
position = transform.position;
position.y = 0;
if (Rotation != lastRot) {
position = lastPos;
return true;
}
if (Vector3.Distance(position, lastPos) > 0.5) {
return true;
}
position = lastPos;
return false;
}
public void OnCloseMap() {
Rotation = -1;
position = Vector2.zero;
clanTeam?.ForEach(p => p.OnCloseMap());
}
public static MapPlayer Create(BasePlayer player) {
return new MapPlayer(player) {
alpha = m_Instance.playerIconAlpha, size = m_Instance.playerIconSize
}
;
}
}
#endregion
#region Configuration
string beancanKey;
float mapAlpha;
float mapSize;
bool clanSupport;
bool friendsSupport;
float playerIconSize;
float playerIconAlpha;
bool playerCoordinates;
bool monuments;
bool caves;
bool powersub;
float monumentIconSize;
float monumentIconAlpha;
bool monumentIconNames;
bool raidhomes;
float raidhomeSIze;
int monumentsFontSize;
bool bradley;
float bradleyIconSize;
float bradleyIconAlpha;
bool car;
bool plane;
float planeIconSize;
float planeIconAlpha;
bool planeDrop;
bool sethome;
float sethomeIconSize;
float planeDropIconSize;
float planeDropIconAlpha;
bool heli;
float heliIconSize;
float heliIconAlpha;
bool heliDrop;
bool quarry;
float quarryIconAlpha;
float quarryIconSize;
float heliDropIconSize;
float heliDropIconAlpha;
bool vendingMachine;
bool vendingMachineEmpty;
float vendingMachineIconSize;
float vendingMachineIconAlpha;
string textColor;
string textColor1;
float bannedSize;
string mapUrl;
string MapText;
private string version;
protected override void LoadDefaultConfig() {
Config["Ключ Beancan (Генерация карты с beancan.io)"] = beancanKey = GetConfig("Ключ Beancan (Генерация карты с beancan.io)", "");
Config["Кастомная карта (http:// или с папки data/RustMap)"] = mapUrl = GetConfig("Кастомная карта (http:// или с папки data/RustMap)", "");
Config["Прозрачность карты"] = mapAlpha = GetConfig("Прозрачность карты", 1f);
Config["Размер карты"] = mapSize = GetConfig("Размер карты", 0.5f);
Config["Отображать местоположение карьеров (CustomQuarry)"] = quarry = GetConfig("Отображать местоположение карьеров(CustomQuarry)", false);
Config["Размер иконки карьера"] = quarryIconSize = GetConfig("Размер иконки карьера", 0.03f);
Config["Прозрачность иконки карьера"] = quarryIconAlpha = GetConfig("Прозрачность иконки карьера", 0.99f);
Config["Версия конфигурации карты"] = version = GetConfig("Версия конфигурации карты", "1.2.45");
Config["Отображать дома, который рейдят"] = raidhomes = GetConfig("Отображать дома, который рейдят", true);
Config["Размер иконок домов, которые рейдят"] = raidhomeSIze = GetConfig("Размер иконок домов, которые рейдят", 0.06f);
Config["Отображать местоположение соклановцев"] = clanSupport = GetConfig("Отображать местоположение соклановцев", false);
Config["Отображать местоположение друзей"] = friendsSupport = GetConfig("Отображать местоположение друзей", false);
Config["Цвет текста (RED, GREEN, BLUE, ALPHA)"] = textColor = GetConfig("Цвет текста (RED, GREEN, BLUE, ALPHA)", "0 0.7 0 0.7");
Config["Цвет текста кастомных иконок (Homes)"] = textColor1 = GetConfig("Цвет текста кастомных иконок (Homes)", "1 1 1 1");
Config["Текст внизу карты (советуем оставить /map help)"] = MapText = GetConfig("Текст внизу карты (советуем оставить /map help)", "Помощь по карте <color=#EF015A>/map help</color>");
Config["Отображать местоположение SETHOME игроков? (Поддержка NTeleportation, Teleport, HomesGUI)"] = sethome = GetConfig("Отображать местоположение SETHOME игроков? (Поддержка NTeleportation, Teleport, HomesGUI)", false);
Config["Размер иконок SETHOME"] = sethomeIconSize = GetConfig("Размер иконок SETHOME", 0.03f);
Config["Размер иконки игрока"] = playerIconSize = GetConfig("Размер иконки игрока", 0.03f);
Config["Прозрачность иконки игрока"] = playerIconAlpha = GetConfig("Прозрачность иконки игрока", 0.99f);
Config["Показывать текущие координаты игрока"] = playerCoordinates = GetConfig("Показывать текущие координаты игрока", true);
Config["Отображать местоположение монументов"] = monuments = GetConfig("Отображать местоположение монументов", true);
Config["Показывать пещеры"] = caves = GetConfig("Показывать пещеры", true);
Config["Показывать подстанции"] = powersub = GetConfig("Показывать подстанции", true);
Config["Размер иконок монументов"] = monumentIconSize = GetConfig("Размер иконок монументов", 0.03f);
Config["Размер иконки забаненого игрока"] = bannedSize = GetConfig("Размер иконки забаненого игрока", 0.04f);
Config["Прозрачность иконок монументов"] = monumentIconAlpha = GetConfig("Прозрачность иконок монументов", 0.99f);
Config["Показывать название монументов"] = monumentIconNames = GetConfig("Показывать название монументов", true);
Config["Размер шрифта монументов"] = monumentsFontSize = GetConfig("Размер шрифта монументов", 13);
Config["Отображать местоположение самолета"] = plane = GetConfig("Отображать местоположение самолета", true);
Config["Размер иконок самолёта"] = planeIconSize = GetConfig("Размер иконок самолёта", 0.035f);
Config["Прозрачность иконок самолёта"] = planeIconAlpha = GetConfig("Прозрачность иконок самолёта", 0.99f);
Config["Отображать местоположение танка"] = bradley = GetConfig("Отображать местоположение танка", true);
Config["Размер иконки танка"] = bradleyIconSize = GetConfig("Размер иконки танка", 0.05f);
Config["Прозрачность иконки танка"] = bradleyIconAlpha = GetConfig("Прозрачность иконки танка", 0.99f);
Config["Отображать местоположение вертолёта"] = heli = GetConfig("Отображать местоположение вертолёта", true);
Config["Размер иконок вертолёта"] = heliIconSize = GetConfig("Размер иконок вертолёта", 0.035f);
Config["Прозрачность иконок вертолёта"] = heliIconAlpha = GetConfig("Прозрачность иконок вертолёта", 0.99f);
Config["Отображать местоположение cброшенного груза"] = planeDrop = GetConfig("Отображать местоположение cброшенного груза", true);
Config["Размер иконок cброшенного груза"] = planeDropIconSize = GetConfig("Размер иконок cброшенного груза", 0.045f);
Config["Прозрачность иконок cброшенного груза"] = planeDropIconAlpha = GetConfig("Прозрачность иконок cброшенного груза", 0.95f);
Config["Отображать местоположение ящиков с вертолёта"] = heliDrop = GetConfig("Отображать местоположение ящиков с вертолёта", true);
Config["Размер иконок ящиков с вертолёта"] = heliDropIconSize = GetConfig("Размер иконок ящиков с вертолёта", 0.03f);
Config["Прозрачность иконок ящиков с вертолёта"] = heliDropIconAlpha = GetConfig("Прозрачность иконок ящиков с вертолёта", 0.99f);
Config["Отображать местоположение торговых автоматов"] = vendingMachine = GetConfig("Отображать местоположение торговых автоматов", true);
Config["Отображать местоположение пустых торговых автоматов"] = vendingMachineEmpty = GetConfig("Отображать местоположение пустых торговых автоматов", true);
Config["Размер иконок торговых автоматов"] = vendingMachineIconSize = GetConfig("Размер иконок торговых автоматов", 0.02f);
Config["Прозрачность иконок торговых автоматов"] = vendingMachineIconAlpha = GetConfig("Прозрачность иконок торговых автоматов", 0.99f);
SaveConfig();
if (!string.IsNullOrEmpty(mapUrl)) {
if (!mapUrl.ToLower().Contains("http")) {
mapUrl = "file://" + Interface.Oxide.DataDirectory + Path.DirectorySeparatorChar + "RustMap" + Path.DirectorySeparatorChar + mapUrl;
}
}
}
T GetConfig<T>(string name, T defaultValue) => Config[name] == null ? defaultValue : (T)Convert.ChangeType(Config[name], typeof(T));
#endregion
#region Fields
static RustMap m_Instance;
private string mapIconJson = @"[{""name"":""{0}"",""parent"":""map_mainImage"",""components"":[{""type"":""UnityEngine.UI.RawImage"",""sprite"":""assets/content/textures/generic/fulltransparent.tga"",""png"":""{3}"",""color"":""1 1 1 {4}""},{""type"":""RectTransform"",""anchormin"":""{1}"",""anchormax"":""{2}""}]}]";
private string mapIconTextJson = @"[{""name"":""{0}"",""parent"":""map_mainImage"",""components"":[{""type"":""UnityEngine.UI.Text"",""text"":""{3}"",""align"":""MiddleCenter"",""fontSize"":12,""color"":""{color}""},{""type"": ""UnityEngine.UI.Outline"",""color"": ""0 0 0 1""},{""type"":""RectTransform"",""anchormin"":""{1}"",""anchormax"":""{2}""}]}]";
private string mapIconTextJsonIcon = @"[{""name"":""{0}"",""parent"":""map_mainImage"",""components"":[{""type"":""UnityEngine.UI.Text"",""text"":""{3}"",""align"":""MiddleCenter"",""fontSize"":9,""color"":""{color1}""},{""type"": ""UnityEngine.UI.Outline"",""color"": ""0 0 0 1""},{""type"":""RectTransform"",""anchormin"":""{1}"",""anchormax"":""{2}""}]}]";
private string mapJson = "[{\"name\":\"map_mainImage\",\"parent\":\"Overlay\",\"components\":[{\"type\":\"UnityEngine.UI.RawImage\",\"sprite\":\"Assets/Content/UI/UI.Background.Tile.psd\",\"color\":\"1 1 1 {1}\",\"png\":\"{0}\"},{\"type\":\"RectTransform\",\"anchormin\":\"{2}\",\"anchormax\":\"{3}\"}]}]";
private string mapCoordsTextJson = @"[{""name"":""map_coordinates"",""parent"":""map_mainImage"",""components"":[{""type"":""UnityEngine.UI.Text"",""text"":""{0}"",""align"":""MiddleCenter"",""fontSize"":18},{""type"": ""UnityEngine.UI.Outline"",""color"": ""0 0 0 1"",""distance"": ""0.5 -0.5""},{""type"":""RectTransform"",""anchormin"":""0 0.95"",""anchormax"":""1 1""}]}]";
private string mapHelpJson = @"[{""name"":""map_help"",""parent"":""map_mainImage"",""components"":[{""type"":""UnityEngine.UI.Text"",""text"":""{0}"",""align"":""MiddleLeft"",""fontSize"":16},{""type"": ""UnityEngine.UI.Outline"",""color"": ""0 0 0 1"",""distance"": ""0.5 -0.5""},{""type"":""RectTransform"",""anchormin"":""0.02 0.001"",""anchormax"":""1 0.05""}]}]";
Dictionary<BasePlayer, MapPlayer> mapPlayers = new Dictionary<BasePlayer, MapPlayer>();
Dictionary<BasePlayer, MapPlayer> subscribers = new Dictionary<BasePlayer, MapPlayer>();
List<MapMarker> temporaryMarkers = new List<MapMarker>();
const string MARKER_BANNED_PERM = "rustmap.banned";
const string MAP_ADMIN = "rustmap.admin";
static float mapSize1;
static string mapSeed;
static int worldSize;
static string level;
string monumentsJson;
bool init = false;
#endregion
#region Oxide Hooks
private List<BasePlayer> AllPlayerUsers = new List<BasePlayer>();
[ChatCommand("map")]
void cmdMapControl(BasePlayer player, string command, string[] args) {
if (!init || player == null) {
SendReply(player, "Извините! В данный момент карта не активирована");
return;
}
if (sethome) {
if (args.Count() >= 1 && args[0] == "homes123") {
if (data.MapPlayerData[player.userID].Homes == true) {
data.MapPlayerData[player.userID].Homes = data.MapPlayerData[player.userID].Homes = false;
SendReply(player, $"<color=orange>Map homes</color>: False");
PlayerSaveData();
return;
}
if (data.MapPlayerData[player.userID].Homes == false) {
data.MapPlayerData[player.userID].Homes = data.MapPlayerData[player.userID].Homes = true;
PlayerSaveData();
SendReply(player, $"<color=orange>Map homes</color>: True");
return;
}
}
}
if (friendsSupport) {
if (args.Count() >= 1 && args[0] == "friends123") {
if (data.MapPlayerData[player.userID].Friends == true) {
data.MapPlayerData[player.userID].Friends = data.MapPlayerData[player.userID].Friends = false;
SendReply(player, $"<color=orange>Map friends</color>: False");
PlayerSaveData();
return;
}
if (data.MapPlayerData[player.userID].Friends == false) {
data.MapPlayerData[player.userID].Friends = data.MapPlayerData[player.userID].Friends = true;
PlayerSaveData();
SendReply(player, $"<color=orange>Map Friends</color>: True");
return;
}
}
}
if (clanSupport) {
if (args.Count() >= 1 && args[0] == "clans123") {
if (data.MapPlayerData[player.userID].Clans == true) {
data.MapPlayerData[player.userID].Clans = data.MapPlayerData[player.userID].Clans = false;
SendReply(player, $"<color=orange>Map Clans</color>: False");
PlayerSaveData();
return;
}
if (data.MapPlayerData[player.userID].Clans == false) {
data.MapPlayerData[player.userID].Clans = data.MapPlayerData[player.userID].Clans = true;
PlayerSaveData();
SendReply(player, $"<color=orange>Map Clans</color>: True");
return;
}
}
}
if (permission.UserHasPermission(player.UserIDString, MAP_ADMIN)) {
if (args.Count() >= 1 && args[0] == "players123") {
if (data.MapPlayerData[player.userID].AllPlayers == true) {
data.MapPlayerData[player.userID].AllPlayers = data.MapPlayerData[player.userID].AllPlayers = false;
PlayerSaveData();
SendReply(player, $"<color=orange>Map AllPlayers</color>: False");
return;
}
if (data.MapPlayerData[player.userID].AllPlayers == false) {
data.MapPlayerData[player.userID].AllPlayers = data.MapPlayerData[player.userID].AllPlayers = true;
PlayerSaveData();
SendReply(player, $"<color=orange>Map AllPlayers</color>: True");
return;
}
}
if (args.Count() >= 1 && args[0] == "bans123") {
if (data.MapPlayerData[player.userID].BanPlayers == true) {
data.MapPlayerData[player.userID].BanPlayers = data.MapPlayerData[player.userID].BanPlayers = false;
SendReply(player, $"<color=orange>Map BanPlayers</color>: False");
PlayerSaveData();
return;
}
if (data.MapPlayerData[player.userID].BanPlayers == false) {
data.MapPlayerData[player.userID].BanPlayers = data.MapPlayerData[player.userID].BanPlayers = true;
PlayerSaveData();
SendReply(player, $"<color=orange>Map BanPlayers</color>: True");
return;
}
}
}
if (subscribers.Keys.Contains(player)) {
CloseMap(player);
}
else {
if (permission.UserHasPermission(player.UserIDString, MAP_ADMIN)) {
if (args.Count() >= 1 && args[0] == "help123") {
SendReply(player, "<size=16>Помощь по карте:</size>\n" + $"<color=orange>Homes</color>: {data.MapPlayerData[player.userID].Homes}\n" + $"<color=orange>Friends</color>: {data.MapPlayerData[player.userID].Friends}\n" + $"<color=orange>Clans</color>: {data.MapPlayerData[player.userID].Clans}\n" + $"<color=orange>Banned Players</color>: {data.MapPlayerData[player.userID].BanPlayers}\n" + $"<color=orange>All Players</color>: {data.MapPlayerData[player.userID].AllPlayers}");
return;
}
if (data.MapPlayerData[player.userID].AllPlayers == true) {
AllPlayerUsers.Add(player);
}
if (data.MapPlayerData[player.userID].AllPlayers == false) {
if (AllPlayerUsers.Contains(player)) AllPlayerUsers.Remove(player);
}
OpenMap(player);
return;
}
if (args.Count() >= 1 && args[0] == "help123") {
if (clanSupport && friendsSupport && sethome) {
SendReply(player, "<size=16>Map</size> by <size=16>RustPlugin.ru</size>\n" + $"<color=orange>Homes</color>: {data.MapPlayerData[player.userID].Homes}\n" + $"<color=orange>Friends</color>: {data.MapPlayerData[player.userID].Friends}\n" + $"<color=orange>Clans</color>: {data.MapPlayerData[player.userID].Clans}");
return;
}
if (!clanSupport && friendsSupport && sethome) {
SendReply(player, "<size=16>Map</size> by <size=16>RustPlugin.ru</size>\n" + $"<color=orange>Homes</color>: {data.MapPlayerData[player.userID].Homes}\n" + $"<color=orange>Friends</color>: {data.MapPlayerData[player.userID].Friends}\n");
return;
}
if (!friendsSupport && clanSupport && sethome) {
SendReply(player, "<size=16>Map</size> by <size=16>RustPlugin.ru</size>\n" + $"<color=orange>Homes</color>: {data.MapPlayerData[player.userID].Homes}\n" + $"<color=orange>Clans</color>: {data.MapPlayerData[player.userID].Clans}");
return;
}
if (friendsSupport && clanSupport && !sethome) {
SendReply(player, "<size=16>Map</size> by <size=16>RustPlugin.ru</size>\n" + $"<color=orange>Friends</color>: {data.MapPlayerData[player.userID].Friends}\n" + $"<color=orange>Clans</color>: {data.MapPlayerData[player.userID].Clans}");
return;
}
if (friendsSupport && !clanSupport && !sethome) {
SendReply(player, "<size=16>Map</size> by <size=16>RustPlugin.ru</size>\n" + $"<color=orange>Friends</color>: {data.MapPlayerData[player.userID].Friends}\n");
return;
}
if (!friendsSupport && clanSupport && !sethome) {
SendReply(player, "<size=16>Map</size> by <size=16>RustPlugin.ru</size>\n" + $"<color=orange>Clans</color>: {data.MapPlayerData[player.userID].Clans}");
return;
}
if (!friendsSupport && !clanSupport && sethome) {
SendReply(player, "<size=16>Map</size> by <size=16>RustPlugin.ru</size>\n" + $"<color=orange>Homes</color>: {data.MapPlayerData[player.userID].Homes}");
return;
}
if (!friendsSupport && !clanSupport && !sethome) {
return;
}
}
OpenMap(player);
}
}
[ConsoleCommand("map.wipe")]
private void CmdTest(ConsoleSystem.Arg arg) {
if (arg.connection != null) return;
m_FileManager.WipeData();
Interface.Oxide.ReloadPlugin(Title);
}
[ConsoleCommand("map.open")]
void ConsoleMap(ConsoleSystem.Arg arg) {
var player = arg.Player();
if (subscribers.Keys.Contains(player)) {
CloseMap(player);
}
else {
OpenMap(player);
}
return;
}
void OnServerInitialized() {
foreach (var player in BasePlayer.activePlayerList) player.SendConsoleCommand("bind m chat.say /map");
m_Instance = this;
worldSize = (int)World.Size;
mapSeed = World.Seed.ToString();
level = ConVar.Server.level;
mapSize1 = TerrainMeta.Size.x;
MapPlayerData = Interface.Oxide.DataFileSystem.GetFile("RustMap/MapPlayerData");
LoadData();
PermissionService.RegisterPermissions(this, new List<string>() {
MARKER_BANNED_PERM, MAP_ADMIN
}
);
LoadDefaultConfig();
worldSize = (int)World.Size;
var anchorMin = new Vector2(0.5f - mapSize * 0.5f, 0.5f - mapSize * 0.800f);
var anchorMax = new Vector2(0.5f + mapSize * 0.5f, 0.5f + mapSize * 0.930f);
mapJson = mapJson.Replace("{2}", $"{anchorMin.x} {anchorMin.y}").Replace("{3}", $"{anchorMax.x} {anchorMax.y}");
mapIconTextJson = mapIconTextJson.Replace("{color}", textColor);
mapIconTextJsonIcon = mapIconTextJsonIcon.Replace("{color1}", textColor1);
InitFileManager();
m_FileManager.StartCoroutine(DownloadMapImage());
foreach (var player in BasePlayer.activePlayerList) OnPlayerInit(player);
timer.Every(0.1f, () => {
foreach (var mm in temporaryMarkers) if (mm.NeedRedraw()) {
++mm.counter;
foreach (var sub in subscribers) DrawMapMarker(sub.Key, mm);
}
foreach (var sub in subscribers) {
RedrawPlayers(sub.Value);
}
}
);
BansUpdate();
timer.Every(20f, BansUpdate);
foreach (var entity in BaseNetworkable.serverEntities.Select(p => p as BaseEntity).Where(p => p != null)) OnEntitySpawned(entity);
}
#region PlayerData
void LoadData() {
try {
data = Interface.GetMod().DataFileSystem.ReadObject<DataStorage>("RustMap/MapPlayerData");
}
catch {
data = new DataStorage();
}
}
private void PlayerSaveData() {
MapPlayerData.WriteObject(data);
}
class DataStorage {
public Dictionary<ulong, MAPDATA> MapPlayerData = new Dictionary<ulong, MAPDATA>();
public DataStorage() {
}
}
class MAPDATA {
public string Name;
public bool Homes;
public bool Friends;
public bool Clans;
public bool AllPlayers;
public bool BanPlayers;
}
DataStorage data;
private DynamicConfigFile MapPlayerData;
#endregion
void OnPlayerInit(BasePlayer player) {
if (!mapPlayers.ContainsKey(player)) mapPlayers[player] = MapPlayer.Create(player);
if (!data.MapPlayerData.ContainsKey(player.userID)) {
data.MapPlayerData.Add(player.userID, new MAPDATA() {
Name = player.displayName, Homes = true, Friends = true, Clans = false, AllPlayers = false, BanPlayers = false,
}
);
PlayerSaveData();
}
else {
data.MapPlayerData[player.userID].Name = player.displayName.ToString();
LoadData();
}
}
void OnNewSave() {
PrintWarning("Обнаружен вайп.Обновляем карту!");
Interface.Oxide.DataFileSystem.WriteObject("RustMap/Images", new Dictionary<string, FileInfo>());
Interface.Oxide.ReloadPlugin(Title);
}
void Unload() {
if (m_FileManager != null) {
m_FileManager.SaveData();
PlayerSaveData();
}
if (!init) return;
foreach (var sub in subscribers.Keys) {
CuiHelper.DestroyUi(sub, "map_mainImage");
}
UnityEngine.Object.Destroy(FileManagerObject);
}
void OnEntitySpawned(BaseEntity entity) {
if (entity == null) return;
if (plane && entity is CargoPlane) AddTemporaryMarker("plane", true, planeIconSize, planeIconAlpha, entity.transform);
if (planeDrop && entity is SupplyDrop) {
AddTemporaryMarker("mapsupply", false, planeDropIconSize, planeDropIconAlpha, entity.transform);
}
if (heli && entity is BaseHelicopter) {
AddTemporaryMarker("heli", true, heliIconSize, heliIconAlpha, entity.transform);
}
if (heliDrop && entity is HelicopterDebris) {
AddTemporaryMarker("helidebris", false, heliDropIconSize, heliDropIconAlpha, entity.transform);
}
}
void OnEntityKill(BaseNetworkable entity) {
if (entity?.net?.ID == null) return;
if (entity is CargoPlane || entity is SupplyDrop || entity is BaseHelicopter || entity is HelicopterDebris) {
var transform = entity.transform;
var mm = temporaryMarkers.Find(p => p.transform == transform);
if (mm != null) RemoveTemporaryMarker(mm);
}
}
#endregion
#region Core
void OpenMap(BasePlayer player) {
CuiHelper.AddUi(player, mapJson);
CuiHelper.AddUi(player, monumentsJson);
foreach (var mm in temporaryMarkers) DrawMapMarker(player, mm);
List<ulong> members = new List<ulong>();
if (PermissionService.HasPermission(player.userID, MARKER_BANNED_PERM)) {
if (data.MapPlayerData[player.userID].BanPlayers == true) {
foreach (var mm in bannedMarkers.Values) DrawMapMarker(player, mm);
}
}
if (data.MapPlayerData[player.userID].AllPlayers == true) {
// if (AllPlayerUsers.Contains(player))
//{
mapPlayers[player].clanTeam = BasePlayer.activePlayerList.Where(p => p != player).Select(MapPlayer.Create).ToList();
//}
}
else {
mapPlayers[player].clanTeam = new List<MapPlayer>();
if (clanSupport) {
if (data.MapPlayerData[player.userID].Clans == true) {
var clanmates = Clans.Call("GetClanMembers", player.userID);
if (clanmates != null) members.AddRange(clanmates as List<ulong>);
}
}
if (friendsSupport) {
if (data.MapPlayerData[player.userID].Friends == true) {
var friends = Friends?.Call("GetFriends", player.userID);
if (friends != null) members.AddRange(friends as ulong[]);
var MutualFr = MutualPermission?.Call("GetFriends", player.userID) as ulong[];
if (MutualFr != null) members.AddRange(MutualFr as ulong[]);
}
}
}
var homes = GetHomes(player);
if (sethome && homes != null) foreach (var home in homes) {
var anchors = ToAnchors(home.Value, sethomeIconSize);
if (data.MapPlayerData[player.userID].Homes == true) {
DrawIconNull(player, "sethome" + home.Key, "sethome" + home.Key, anchors, images["sethome"], 1.0f, $"Дом: \"{home.Key}\"", 8, false);
}
}
if (quarry && CustomQuarry != null) {
var playerQuarries = GetPlayerQuarries(player.userID);
if (playerQuarries != null) {
foreach (var quarry in playerQuarries) {
var anchors = ToAnchors(quarry.Key, quarryIconSize);
DrawIconNull(player, "quarry" + quarry.Value, "quarry" + quarry.Value, anchors, images["quarry"], 1.0f, "Топливо: " + quarry.Value, 2, false);
}
}
}
if (members != null && members.Count > 0) {
var onlineMembers = BasePlayer.activePlayerList.Where(p => members.Contains(p.userID) && p != player).ToList();
mapPlayers[player].clanTeam.AddRange(onlineMembers.Select(MapPlayer.Create).ToList());
}
if (raidhomes) {
var zones = GetRaidZones(player);
if (zones != null) foreach (var zone in zones) {
var anchors = ToAnchors(zone, raidhomeSIze);
DrawIcon(player, "raidhome" + zone, "raidhome" + zone, anchors, images["raidhome"], 0.95f, null, 12, false);
}
}
subscribers[player] = mapPlayers[player];
RedrawPlayers(mapPlayers[player]);
}
[PluginReference]
Plugin NoEscape;
List<Vector3> GetRaidZones(BasePlayer player) {
return (List<Vector3>)NoEscape?.Call("ApiGetOwnerRaidZones", player.userID);
}
void OnPlayerDisconnected(BasePlayer player, string reason) {
subscribers.Remove(player);
mapPlayers.Remove(player);
foreach (var sub in mapPlayers) {
var toRemove = sub.Value.clanTeam.Where(p => p.player == player).ToList();
foreach (var teammate in toRemove) {
CuiHelper.DestroyUi(sub.Key, teammate.name + teammate.counter);
CuiHelper.DestroyUi(sub.Key, teammate.name + teammate.counter + "text");
}
toRemove.ForEach(p => sub.Value.clanTeam.Remove(p));
}
}
void RedrawPlayers(MapPlayer mapPlayer) {
var player = mapPlayer.player;
if (mapPlayer.clanTeam != null) {
foreach (var tmMapPlayer in mapPlayer.clanTeam) {
DrawMapPlayer(player, tmMapPlayer, true);
}
}
DrawMapPlayer(player, mapPlayer);
}
// HOME
void CloseMap(BasePlayer player) {
subscribers.Remove(player);
mapPlayers[player].OnCloseMap();
CuiHelper.DestroyUi(player, "map_mainImage");
}
void DrawMapPlayer(BasePlayer player, MapPlayer mp, bool friend = false) {
if (mp.NeedRedraw()) {
if (!friend && playerCoordinates) {
CuiHelper.DestroyUi(player, "map_coordinates");
var curX = ((float)Math.Round(mp.transform.position.x, 1)).ToString();
var curZ = ((float)Math.Round(mp.transform.position.z, 1)).ToString();
CuiHelper.AddUi(player, Format(mapCoordsTextJson, "<size=20>" + curX + " <color=#EF015A>/</color> " + curZ + "</size>"));
}
var pos = mp.player.transform.position;
var anchors = ToAnchors(pos, playerIconSize);
var png = !friend ? PlayerPng(mp.Rotation) : FriendPng(mp.Rotation);
if (png == null) {
PrintError($"{friend}", mp.Rotation.ToString());
png = FriendPng(mp.Rotation - 2);
}
if (!InMap(pos)) {
CuiHelper.DestroyUi(player, "mapPlayer" + mp.player.userID + (mp.counter));
CuiHelper.DestroyUi(player, "mapPlayer" + mp.player.userID + (mp.counter) + "text");
return;
}
DrawIcon(player, "mapPlayer" + mp.player.userID + (mp.counter), "mapPlayer" + mp.player.userID + (++mp.counter), anchors, png, mp.alpha, mp.player.displayName);
}
}
void AddTemporaryMarker(string png, bool rotSupport, float size, float alpha, Transform transform, string name = "") {
var mm = MapMarker.Create(transform);
mm.name = string.IsNullOrEmpty(name) ? transform.GetInstanceID().ToString() : name;
mm.png = png;
mm.rotSupport = rotSupport;
mm.size = size;
mm.alpha = alpha;
mm.fontsize = 12;
mm.position = transform.position;
temporaryMarkers.Add(mm);
foreach (var sub in subscribers) DrawMapMarker(sub.Key, mm);
}
void RemoveTemporaryMarkerByName(string name) {
var mm = temporaryMarkers.FirstOrDefault(p => p.name == name);
if (mm != null) RemoveTemporaryMarker(mm);
}
void RemoveTemporaryMarker(MapMarker mm) {
temporaryMarkers.Remove(mm);
foreach (var sub in subscribers) CuiHelper.DestroyUi(sub.Key, mm.transform.GetInstanceID().ToString() + mm.counter);
}
void DrawIcon(BasePlayer player, string lastName, string name, string[] anchors, string png, float alpha, string text = null, int fontsize = 12, bool destroy = true) {
if (destroy) {
timer.Once(0.05f, () => {
CuiHelper.DestroyUi(player, lastName);
}
);
CuiHelper.DestroyUi(player, lastName + "text");
}
CuiHelper.AddUi(player, Format(mapHelpJson, $"{MapText}"));
CuiHelper.AddUi(player, Format(mapIconJson, name, anchors[0], anchors[1], png, alpha));
if (!string.IsNullOrEmpty(text)) CuiHelper.AddUi(player, Format(mapIconTextJson, name + "text", anchors[2], anchors[3], text.Replace("\"", ""), fontsize));
}
void DrawIconNull(BasePlayer player, string lastName, string name, string[] anchors, string png, float alpha, string text = null, int fontsize = 12, bool destroy = true) {
if (destroy) {
timer.Once(0.05f, () => {
CuiHelper.DestroyUi(player, lastName);
}
);
CuiHelper.DestroyUi(player, lastName + "text");
}
CuiHelper.AddUi(player, Format(mapIconJson, name, anchors[0], anchors[1], png, alpha));
if (!string.IsNullOrEmpty(text)) CuiHelper.AddUi(player, Format(mapIconTextJsonIcon, name + "text", anchors[2], anchors[3], text.Replace("\"", ""), fontsize));
}
void DrawMapMarker(BasePlayer player, MapMarker mm) {
if (mm.transform == null) return;
var pos = mm.transform.position;
var anchors = ToAnchors(pos, mm.size);
var png = mm.png;
if (mm.rotSupport) png += GetRotation(mm.transform.rotation.eulerAngles.y);
if (images[png] == null) {
PrintError("PNG = NULL: " + png);
}
if (mm.inMap && !InMap(pos)) {
CuiHelper.DestroyUi(player, mm.name + (mm.counter - 1) + "text");
CuiHelper.DestroyUi(player, mm.name + (mm.counter - 1));
mm.inMap = false;
return;
}
mm.inMap = InMap(pos);
if (!mm.inMap) {
return;
}
DrawIcon(player, mm.name + (mm.counter - 1), mm.name + (mm.counter), anchors, images[png], mm.alpha, mm.text);
}
bool InMap(Vector3 pos) {
float halfSize = (int)TerrainMeta.Size.x * 0.5f;
return pos.x < halfSize && pos.x > -halfSize && pos.z < halfSize && pos.z > -halfSize;
}
#endregion
#region Banned
List<ulong> bannedCache = new List<ulong>();
Dictionary<BasePlayer, MapMarker> bannedMarkers = new Dictionary<BasePlayer, MapMarker>();
void AddBannedMarker(BasePlayer player) {
var transform = player.transform;
var mm = MapMarker.Create(transform);
mm.png = "banned";
mm.rotSupport = false;
mm.name = transform.GetInstanceID().ToString();
mm.alpha = 1f;
mm.size = bannedSize;
mm.position = transform.position;
bannedMarkers[player] = mm;
foreach (var sub in subscribers) if (PermissionService.HasPermission(sub.Key.userID, MARKER_BANNED_PERM)) DrawMapMarker(sub.Key, mm);
}
void RemoveBannedMarker(BasePlayer player) {
var mm = bannedMarkers[player];
bannedMarkers.Remove(player);
foreach (var sub in subscribers) CuiHelper.DestroyUi(sub.Key, mm.transform.GetInstanceID().ToString() + mm.counter);
}
void BansUpdate() {
var unlisted = ServerUsers.GetAll(ServerUsers.UserGroup.Banned).Select(p => p.steamid).Except(bannedCache).ToList();
bannedCache.AddRange(unlisted);
if (unlisted.Count == 0) return;
foreach (var player in BasePlayer.sleepingPlayerList) {
if (unlisted.Contains(player.userID)) {
AddBannedMarker(player);
}
}
}
void OnPlayerBanned(Connection connection, string reason) {
var userId = connection.userid;
if (bannedCache.Contains(userId)) return;
var user = BasePlayer.activePlayerList.Find(p => p.userID == userId);
if (user == null) {
user = BasePlayer.sleepingPlayerList.Find(p => p.userID == userId);
if (user == null) return;
AddBannedMarker(user);
return;
}
AddBannedMarker(user);
}
void OnEntityDeath(BaseCombatEntity entity) {
var player = entity as BasePlayer;
if (player == null || !player.IsSleeping()) return;
if (bannedMarkers.ContainsKey(player)) {
RemoveBannedMarker(player);
}
}
#endregion
#region Markers
void FindStaticMarkers() {
if (!this.monuments) {
monumentsJson = "";
return;
}
var monuments = UnityEngine.Object.FindObjectsOfType<MonumentInfo>();
var container = new CuiElementContainer();
foreach (var monument in monuments) {
var anchors = ToAnchors(monument.transform.position, monumentIconSize);
string png;
string text = null;
if (monument.Type == MonumentType.Cave && caves) png = "cave";
else if (monument.name.Contains("lighthouse")) {
png = "lighthouse";
text = "Маяк";
}
else if (monument.name.Contains("powerplant_1")) {
png = "powerplant";
text = "Атомная станция";
}
else if (monument.name.Contains("military_tunnel_1")) {
png = "militarytunnel";
text = "Тоннель";
}
else if (monument.name.Contains("airfield_1")) {
png = "airfield";
text = "Аэропорт";
}
else if (monument.name.Contains("trainyard_1")) {
png = "trainyard";
text = "Депо";
}
else if (monument.name.Contains("junkyard_1")) {
png = "junkyard";
text = "Свалка";
}
else if (monument.name.Contains("water_treatment_plant_1")) {
png = "watertreatment";
text = "Водонапорная станция";
}
else if (monument.name.Contains("warehouse")) {
png = "warehouse";
text = "Склад";
}
else if (monument.name.Contains("satellite_dish")) {
png = "satellitedish";
text = "Антенны";
}
else if (monument.name.Contains("gas_station")) {
png = "gasstation";
text = "Заправка";
}
else if (monument.name.Contains("supermarket")) {
png = "supermarket";
text = "Супермаркет";
}
else if (monument.name.Contains("sphere_tank")) {
png = "spheretank";
text = "Сфера";
}
else if (monument.name.Contains("harbor")) {
png = "harbor";
text = "Порт";
}
else if (monument.name.Contains("radtown_small_3")) {
png = "radtown";
text = "Радтаун";
}
else if (monument.name.Contains("power_sub") && powersub) png = "powersub";
else if (monument.name.Contains("water_well_a")) {
png = "water_well";
text = "";
}
else if (monument.name.Contains("water_well_b")) {
png = "water_well";
text = "";
}
else if (monument.name.Contains("water_well_c")) {
png = "water_well";
text = "";
}
else if (monument.name.Contains("water_well_d")) {
png = "water_well";
text = "";
}
else if (monument.name.Contains("water_well_e")) {
png = "water_well";
text = "";
}
else if (monument.name.Contains("mining_quarry_a")) png = "cquarry";
else if (monument.name.Contains("mining_quarry_b")) png = "cquarry";
else if (monument.name.Contains("mining_quarry_с")) png = "cquarry";
else if (monument.name.Contains("launch_site_1")) {
png = "launchsite";
text = "Аэродром";
}
else {
Puts("MAP IGNORE: " + monument.name);
continue;
}
container.Add(new CuiElement() {
Name = CuiHelper.GetGuid(), Parent = "map_mainImage", Components = {
new CuiRawImageComponent() {
Sprite = "assets/content/textures/generic/fulltransparent.tga", Png = images[png], Color = $"1 1 1 {monumentIconAlpha}"
}
, new CuiRectTransformComponent() {
AnchorMin = anchors[0], AnchorMax = anchors[1]
}
}
}
);
if (!string.IsNullOrEmpty(text) && monumentIconNames) {
container.Add(new CuiElement() {
Name = CuiHelper.GetGuid(), Parent = "map_mainImage", Components = {
new CuiTextComponent() {
Text = text, FontSize = monumentsFontSize, Align = TextAnchor.MiddleCenter,
}
, new CuiOutlineComponent() {
Color = "0 0 0 1"
}
, new CuiRectTransformComponent() {
// ... [Code preview truncated due to length. Full source in attached file] ...