C#:
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using Oxide.Game.Rust.Cui;
using System.IO;
using System.Linq;
using Oxide.Core;
using Oxide.Core.Configuration;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("MapBags", "Ryamkk", "1.0.1")]
class MapBags : RustPlugin
{
public Dictionary<ulong, string> playerDic = new Dictionary<ulong, string>();
public int ImageSize = 280;
public bool loaded = false;
public static string Layer = "MapBags";
void OnServerInitialized()
{
InitFileManager();
ServerMgr.Instance.StartCoroutine(LoadImages());
}
private Dictionary<string, string> images = new Dictionary<string, string>()
{
["Map"] = "https://cdn.discordapp.com/attachments/956598122560233492/969216948216934400/COOKIEMAPBEST.map_1.png",
["SbagCD"] = "https://cdn.discordapp.com/attachments/845688011597021244/845688089967984680/SbagCD.png",
["Sbag"] = "https://cdn.discordapp.com/attachments/845688011597021244/845688091002798090/Sbag.png",
["Death"] = "https://cdn.discordapp.com/attachments/845688011597021244/845688113346510868/Death.png",
};
IEnumerator LoadImages()
{
foreach (var name in images.Keys.ToList())
{
yield return m_FileManager.StartCoroutine(m_FileManager.LoadFile(name, images[name]));
images[name] = m_FileManager.GetPng(name);
}
loaded = true;
}
void Unload()
{
UnityEngine.Object.Destroy(FileManagerObject);
foreach (BasePlayer player in BasePlayer.activePlayerList)
{
CuiHelper.DestroyUi(player, Layer);
}
}
private void OnPlayerRespawn(BasePlayer player)
{
if (player.IsReceivingSnapshot)
{
NextTick(() => OnPlayerRespawn(player));
return;
}
CuiHelper.DestroyUi(player, Layer);
}
private void OnPlayerRespawned(BasePlayer player)
{
if (player.IsReceivingSnapshot)
{
NextTick(() => OnPlayerRespawned(player));
return;
}
CuiHelper.DestroyUi(player, Layer);
}
private void OnPlayerInit(BasePlayer player)
{
if (player.IsReceivingSnapshot)
{
NextTick(() => OnPlayerInit(player));
return;
}
if (player.IsDead())
{
DDrawMapBags(player);
}
}
private void OnEntityDeath(BasePlayer player, HitInfo info)
{
if (!player.IsConnected) return;
if (playerDic.ContainsKey(player.userID)) playerDic.Remove(player.userID);
playerDic.Add(player.userID, player.transform.position.ToString());
timer.Once(0.5f, () => { DDrawMapBags(player); });
}
private void DDrawMapBags(BasePlayer player)
{
CuiHelper.DestroyUi(player, Layer);
CuiElementContainer container = new CuiElementContainer();
container.Add(new CuiPanel
{
CursorEnabled = true,
Image = { FadeIn = 2.5f, Color = "0 0 0 0" },
RectTransform = { AnchorMin = "0.4 0.4", AnchorMax = "0.4 0.4", OffsetMin = $"{-ImageSize} {-ImageSize}", OffsetMax = $"{ImageSize} {ImageSize}" },
}, "Overlay", Layer);
container.Add(new CuiElement
{
Parent = Layer,
Name = Layer + ".BG",
Components =
{
new CuiRawImageComponent { FadeIn = 2.5f, Color = "1 1 1 1", Png = images["Map"] },
new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1" }
}
});
if (SleepingBag.FindForPlayer(player.userID, true) != null)
{
int bcount = 0;
foreach (var cBag in SleepingBag.FindForPlayer(player.userID, true))
{
var anchors = ToAnchors(cBag.transform.position, 0.05f);
if (cBag.unlockSeconds > 0)
{
container.Add(new CuiElement
{
Parent = Layer + ".BG",
Name = Layer + ".BG" + ".Button",
Components =
{
new CuiRawImageComponent { FadeIn = 2.5f, Color = "1 1 1 1", Png = images["SbagCD"] },
new CuiRectTransformComponent {AnchorMin = anchors[0], AnchorMax = anchors[1]}
}
});
}
else
{
container.Add(new CuiElement
{
Parent = Layer + ".BG",
Name = Layer + ".BG" + ".Button",
Components =
{
new CuiRawImageComponent { FadeIn = 2.5f, Color = "1 1 1 1", Png = images["Sbag"] },
new CuiRectTransformComponent {AnchorMin = anchors[0], AnchorMax = anchors[1]}
}
});
}
container.Add(new CuiButton
{
Button = { Color = "0 0 0 0", Command = $"respawn_sleepingbag {cBag.net.ID}" },
RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" },
Text = { Text = "" }
}, Layer + ".BG" + ".Button");
bcount++;
}
}
if (playerDic.ContainsKey(player.userID))
{
var anchorsDic = ToAnchors(playerDic[player.userID].ToVector3(), 0.03f);
container.Add(new CuiElement
{
Parent = Layer + ".BG",
Components =
{
new CuiRawImageComponent { FadeIn = 2.5f, Color = "1 1 1 1", Png = images["Death"] },
new CuiRectTransformComponent { AnchorMin = anchorsDic[0], AnchorMax = anchorsDic[1] }
}
});
}
CuiHelper.AddUi(player, container);
}
string[] ToAnchors(Vector3 position, float size)
{
Vector2 center = new Vector2((position.x + (int)World.Size * 0.5f) / (int)World.Size, (position.z + (int)World.Size * 0.5f) / (int)World.Size);
size *= 0.5f;
return new[]
{
$"{center.x - size} {center.y - size}",
$"{center.x + size} {center.y + size}",
$"{center.x - 0.1} {center.y - size-0.04f}",
$"{center.x + 0.1} {center.y - size+0.02}"
};
}
private GameObject FileManagerObject;
private FileManager m_FileManager;
void InitFileManager()
{
FileManagerObject = new GameObject("MAP_FileManagerObject");
m_FileManager = FileManagerObject.AddComponent<FileManager>();
}
class FileManager : MonoBehaviour
{
int loaded = 0;
int needed = 0;
public bool IsFinished => needed == loaded;
const ulong MaxActiveLoads = 10;
Dictionary<string, FileInfo> files = new Dictionary<string, FileInfo>();
DynamicConfigFile dataFile = Interface.Oxide.DataFileSystem.GetFile("Images");
private class FileInfo
{
public string Url;
public string Png;
}
public void SaveData()
{
dataFile.WriteObject(files);
}
public string GetPng(string name) => files[name].Png;
private void Awake()
{
files = dataFile.ReadObject<Dictionary<string, FileInfo>>() ?? new Dictionary<string, FileInfo>();
}
public IEnumerator LoadFile(string name, string url, int size = -1)
{
if (files.ContainsKey(name) && files[name].Url == url && !string.IsNullOrEmpty(files[name].Png)) yield break;
files[name] = new FileInfo() { Url = url };
needed++;
yield return StartCoroutine(LoadImageCoroutine(name, url, size));
}
IEnumerator LoadImageCoroutine(string name, string url, int size = -1)
{
using (WWW www = new WWW(url))
{
yield return www;
{
if (string.IsNullOrEmpty(www.error))
{
var bytes = size == -1 ? www.bytes : Resize(www.bytes, size);
var entityId = CommunityEntity.ServerInstance.net.ID;
var crc32 = FileStorage.server.Store(www.bytes, FileStorage.Type.png, entityId).ToString();
files[name].Png = crc32;
}
}
}
loaded++;
}
static byte[] Resize(byte[] bytes, int size)
{
Image img = (Bitmap)(new ImageConverter().ConvertFrom(bytes));
Bitmap cutPiece = new Bitmap(size, size);
System.Drawing.Graphics graphic = System.Drawing.Graphics.FromImage(cutPiece);
graphic.DrawImage(img, new Rectangle(0, 0, size, size), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel);
graphic.Dispose();
MemoryStream ms = new MemoryStream();
cutPiece.Save(ms, ImageFormat.Jpeg);
return ms.ToArray();
}
}
}
}