C#:
using UnityEngine;
using System;
using System.Linq;
using System.Collections.Generic;
using System.IO;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using Oxide.Core.Libraries.Covalence;
using Newtonsoft.Json;
/*TODO
* Add 'Sent' category // done
* Add ability to remove certain email // done
* Add ability to clear whole email // done
* Add localization // done
* Add new mail notification // done
*/
/* Changes in 0.1.4
* Added notification system via chat
* Give real-time notice to recipient(if he is online)
* Give notice to player on connect(if allowed in config)
* Edited the label in Received category
* All emails that are unread are a bit highlighted
*/
/* Changes in 0.1.3
* Added "Find Online Players" button in New Email category
* Added 2 new perms
* 1. permission to use New Email button
* 2. permission to view Sent and Received categories
* Added small changes to the GUI - those "x" symbols on the close buttons
*/
namespace Oxide.Plugins {
[Info("ZMail", "Zeeuss", "0.1.4")]
[Description("Ingame email for players to send messages to each other with nice gui")]
public class ZMail : CovalencePlugin {
#region Init
private const string permUse = "zmail.use";
private const string permView = "zmail.view";
private const string permSend = "zmail.send";
void Init() {
permission.RegisterPermission(permUse, this);
permission.RegisterPermission(permView, this);
permission.RegisterPermission(permSend, this);
if (!LoadConfigVariables()) return;
}
void Unload() {
foreach(BasePlayer player in BasePlayer.activePlayerList) {
CuiHelper.DestroyUi(player, "emailMainframe");
}
}
void OnPlayerConnected(BasePlayer player) {
if(configData.newEmails == true) {
DataFileSystem dataFile = new DataFileSystem($"{Interface.Oxide.DataDirectory}\\ZMail\\{player.UserIDString}");
Dictionary<string, string> idData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, string>>($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.UserIDString}{Path.DirectorySeparatorChar}unread");
if (Interface.Oxide.DataFileSystem.ExistsDatafile($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.UserIDString}{Path.DirectorySeparatorChar}unread") && idData.Count > 0) {
player.ChatMessage(String.Format(lang.GetMessage("conMails", this, player.UserIDString), idData.Count.ToString()));
}
else {
dataFile.SaveDatafile("unread");
}
}
}
#endregion
#region Localization
protected override void LoadDefaultMessages() {
lang.RegisterMessages(new Dictionary<string, string> {
["NoPerms"]
= "You don't have permission to use this!", ["noPlayerFound"] = "No player found!", ["foundPlayerToSend"] = "Recipient {0}", ["newEmailButton"] = "NEW Email", ["receivedEmailsButton"] = "Received", ["sentEmailsButton"] = "Sent", ["clearAllButton"] = "Clear All", ["succussfullySend"] = "Message succussfully sent!", ["selectedFieldID"] = "ID:", ["selectedFieldFrom"] = "From:", ["selectedFieldTo"] = "Sent to:", ["selectedFieldMessage"] = "Message:", ["defaultInputUser"] = ".....Set player username or id.....", ["defaultInputMessage"] = "Type your message here.....", ["noEmails"] = "You have not received any emails yet!", ["noSentEmails"] = "You have not sent any emails yet!", ["receivedEmails"] = "You have received {0} emails({1} Unread emails)", ["sentEmails"] = "You have sent {0} emails", ["pageOfMaxPages"] = "Page: {0} / {1}", ["previous"] = "Previous", ["next"] = "Next", ["findOnline"] = "Find Online Players", ["receivedNew"] = "[<color=#13ad0f>Z</color>Mail]\nYou have just received new mail from <color=#05ba00>{0}</color>\nYou have total amount of <color=#a10800>{1}</color> unread emails", ["conMails"] = "[<color=#13ad0f>Z</color>Mail]\nYou have total amount of <color=#a10800>{0}</color> unread emails",
}
, this);
}
#endregion
#region fields
Dictionary<IPlayer, IPlayer> recipientMap = new Dictionary<IPlayer, IPlayer>();
// Player-to-recipient mapping
Dictionary<IPlayer, IPlayer> senderMap = new Dictionary<IPlayer, IPlayer>();
Dictionary<IPlayer, string> message = new Dictionary<IPlayer, string>();
Dictionary<IPlayer, int> currentPageRec = new Dictionary<IPlayer, int>();
Dictionary<IPlayer, int> currentPageSen = new Dictionary<IPlayer, int>();
Dictionary<IPlayer, int> currentPage = new Dictionary<IPlayer, int>();
#endregion
#region Main menu command
[Command("zmail")]
void emailCommand(IPlayer player, string command, string[] args) {
if (!permission.UserHasPermission(player.Id, permUse)) {
player.Message(lang.GetMessage("NoPerms", this, player.Id));
return;
}
if(!currentPageRec.ContainsKey(player)) {
currentPageRec.Add(player, 1);
}
else {
currentPageRec.Remove(player);
currentPageRec.Add(player, 1);
}
if(!currentPageSen.ContainsKey(player)) {
currentPageSen.Add(player, 1);
}
else {
currentPageSen.Remove(player);
currentPageSen.Add(player, 1);
}
if (!currentPage.ContainsKey(player)) {
currentPage.Add(player, 0);
}
if (currentPage.ContainsKey(player)) {
currentPage.Remove(player);
currentPage.Add(player, 0);
}
BasePlayer bPlayer = BasePlayer.Find(player.Id);
CuiElementContainer menu = emailCui(player);
CuiHelper.DestroyUi(bPlayer, "emailMainframe");
DataFileSystem dataFile = new DataFileSystem($"{Interface.Oxide.DataDirectory}\\ZMail\\{player.Id.ToString()}");
if (Interface.Oxide.DataFileSystem.ExistsDatafile($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}received")) {
}
else {
dataFile.SaveDatafile("received");
}
if (Interface.Oxide.DataFileSystem.ExistsDatafile($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}sent")) {
}
else {
dataFile.SaveDatafile("sent");
}
if (Interface.Oxide.DataFileSystem.ExistsDatafile($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}unread")) {
}
else {
dataFile.SaveDatafile("unread");
}
CuiHelper.AddUi(bPlayer, menu);
}
#endregion
#region Action Commands
[Command("zmail.email.close")]
void closeAll(IPlayer player, string command, string[] args) {
BasePlayer bPlayer = BasePlayer.Find(player.Id);
CuiHelper.DestroyUi(bPlayer, "emailMainframe");
CuiHelper.DestroyUi(bPlayer, "selectedEmail");
}
[Command("zmail.open.online")]
void openOnlinePlayers(IPlayer player, string command, string[] args) {
BasePlayer bPlayer = BasePlayer.Find(player.Id);
CuiElementContainer menu = new CuiElementContainer();
List<BasePlayer> onlinePlayers = BasePlayer.activePlayerList.ToList();
if (!currentPage.ContainsKey(player)) {
currentPage.Add(player, 0);
}
if (currentPage.ContainsKey(player)) {
currentPage.Remove(player);
currentPage.Add(player, 0);
}
AddCuiPanel(menu, true, "0 0 0 0.95", "0.1 0.1", "0.9 0.9", null, null, "emailMainframe", "onlineMainframe");
int numPlayersDisplayed = 0;
int playersPerPage = 20;
int numColumns = 5;
int numRows = playersPerPage / numColumns;
int startIndex = currentPage[player] * playersPerPage;
float startY = 0.85f;
// Starting Y position for the first line
float startX = 0.15f;
// Spacing from the left edge
float buttonHeight = 0.13f;
// Height of each button
float lineHeight = 0.18f;
// Spacing between lines
float buttonWidth = 0.12f;
// Custom width of each button
float fadeIn = 0f;
float fadeInIncrease = 0.12f;
int numPlayers = onlinePlayers.Count;
int numPages = numPlayers / playersPerPage + (numPlayers % playersPerPage == 0 ? 0 : 1);
for (int row = 0; row < numRows; row++) {
for (int col = 0; col < numColumns; col++) {
fadeIn += fadeInIncrease;
int index = startIndex + (row * numColumns) + col;
if (index < onlinePlayers.Count) {
float xPos = startX + col * (buttonWidth + 0.02f);
float yPos = startY - (row * lineHeight + buttonHeight);
AddCuiFadedButton(menu, fadeIn, fadeIn, $"zmail.email.recipient {onlinePlayers[index].UserIDString}", "0.18 0.18 0.18 0.98", $"{xPos} {yPos}", $"{xPos + buttonWidth} {yPos + buttonHeight}", null, null, $"Select:\n{onlinePlayers[index].displayName}", "1 1 1 1", 12, TextAnchor.UpperCenter, "onlineMainframe", $"zmail.player.{index}");
}
}
}
if (startIndex > 0) {
AddCuiButton(menu, $"zmail.onlinepage.prev", "0.29 0.267 0.267 0.94", "0.1 0.05", "0.2 0.1", null, null, $"{lang.GetMessage("previous", this, player.Id)}", "1 1 1 1", 13, TextAnchor.MiddleCenter, "onlineMainframe", "zmail.prevbutton");
}
if (startIndex + numPlayersDisplayed < onlinePlayers.Count && currentPage[player] < numPages - 1) {
AddCuiButton(menu, $"zmail.onlinepage.next", "0.29 0.267 0.267 0.94", "0.8 0.05", "0.9 0.1", null, null, $"{lang.GetMessage("next", this, player.Id)}", "1 1 1 1", 13, TextAnchor.MiddleCenter, "onlineMainframe", "zmail.nextbutton");
}
AddCuiButton(menu, "0.878 0.047 0 1", "zmail.online.close", "0.93 0.96", "0.99 0.99", null, null, "x", "0 0 0 1", 10, TextAnchor.MiddleCenter, "onlineMainframe", "online.close");
CuiHelper.AddUi(bPlayer, menu);
}
[Command("zmail.online.close")]
void zmailCloseOnline(IPlayer player, string command, string[] args) {
BasePlayer ply = BasePlayer.Find(player.Id);
CuiHelper.DestroyUi(ply, "onlineMainframe");
}
[Command("zmail.onlinepage.next")]
private void NextPageCommand(IPlayer player, string command, string[] args) {
currentPage[player]++;
openOnlinePlayers(player, command, args);
}
[Command("zmail.onlinepage.prev")]
private void PrevPageCommand(IPlayer player, string command, string[] args) {
currentPage[player]--;
if (currentPage[player] < 0) {
currentPage[player] = 0;
}
openOnlinePlayers(player, command, args);
}
[Command("zmail.email.load")]
void newEmailMenuLoad(IPlayer player, string command, string[] args) {
if(!permission.UserHasPermission(player.Id, permSend)) {
player.Message(lang.GetMessage("NoPerms", this, player.Id));
return;
}
BasePlayer bPlayer = BasePlayer.Find(player.Id);
CuiHelper.DestroyUi(bPlayer, "emailInputBackground");
CuiHelper.DestroyUi(bPlayer, "emailInputScreen");
CuiHelper.DestroyUi(bPlayer, "emailInputBackgroundMessage");
CuiHelper.DestroyUi(bPlayer, "emailInputScreenMessage");
CuiHelper.DestroyUi(bPlayer, "emailSendButton");
CuiHelper.DestroyUi(bPlayer, "emailInputField");
CuiHelper.DestroyUi(bPlayer, "emailInputFieldMessage");
CuiHelper.DestroyUi(bPlayer, "receivedPanel");
CuiHelper.DestroyUi(bPlayer, "selectedEmail");
CuiHelper.DestroyUi(bPlayer, "playersFound");
CuiHelper.DestroyUi(bPlayer, "noReceived");
CuiHelper.DestroyUi(bPlayer, "clearBttn");
CuiHelper.DestroyUi(bPlayer, "sentPanel");
CuiHelper.DestroyUi(bPlayer, "email.find.online");
CuiHelper.DestroyUi(bPlayer, "onlineMainframe");
if (!currentPageRec.ContainsKey(player)) {
currentPageRec.Add(player, 1);
}
else {
currentPageRec.Remove(player);
currentPageRec.Add(player, 1);
}
if (!currentPageSen.ContainsKey(player)) {
currentPageSen.Add(player, 1);
}
else {
currentPageSen.Remove(player);
currentPageSen.Add(player, 1);
}
CuiElementContainer menu = newEmailCui(player);
CuiHelper.AddUi(bPlayer, menu);
}
[Command("zmail.sent.load")]
void sentEmailLoad(IPlayer player) {
if (!permission.UserHasPermission(player.Id, permView)) {
player.Message(lang.GetMessage("NoPerms", this, player.Id));
return;
}
BasePlayer bPlayer = BasePlayer.Find(player.Id);
CuiHelper.DestroyUi(bPlayer, "emailInputBackground");
CuiHelper.DestroyUi(bPlayer, "emailInputScreen");
CuiHelper.DestroyUi(bPlayer, "emailInputBackgroundMessage");
CuiHelper.DestroyUi(bPlayer, "emailInputScreenMessage");
CuiHelper.DestroyUi(bPlayer, "emailSendButton");
CuiHelper.DestroyUi(bPlayer, "emailInputField");
CuiHelper.DestroyUi(bPlayer, "emailInputFieldMessage");
CuiHelper.DestroyUi(bPlayer, "receivedPanel");
CuiHelper.DestroyUi(bPlayer, "selectedEmail");
CuiHelper.DestroyUi(bPlayer, "playersFound");
CuiHelper.DestroyUi(bPlayer, "noReceived");
CuiHelper.DestroyUi(bPlayer, "clearBttn");
CuiHelper.DestroyUi(bPlayer, "messageSent");
CuiHelper.DestroyUi(bPlayer, "sentPanel");
CuiHelper.DestroyUi(bPlayer, "email.find.online");
CuiHelper.DestroyUi(bPlayer, "onlineMainframe");
if (!currentPageRec.ContainsKey(player)) {
currentPageRec.Add(player, 1);
}
else {
}
if (!currentPageSen.ContainsKey(player)) {
currentPageSen.Add(player, 1);
}
else {
}
CuiElementContainer menu = sentEmails(player);
CuiHelper.AddUi(bPlayer, menu);
}
[Command("zmail.received.load")]
void receivedMenuLoad(IPlayer player) {
if (!permission.UserHasPermission(player.Id, permView)) {
player.Message(lang.GetMessage("NoPerms", this, player.Id));
return;
}
BasePlayer bPlayer = BasePlayer.Find(player.Id);
CuiHelper.DestroyUi(bPlayer, "emailInputBackground");
CuiHelper.DestroyUi(bPlayer, "emailInputScreen");
CuiHelper.DestroyUi(bPlayer, "emailInputBackgroundMessage");
CuiHelper.DestroyUi(bPlayer, "emailInputScreenMessage");
CuiHelper.DestroyUi(bPlayer, "emailSendButton");
CuiHelper.DestroyUi(bPlayer, "emailInputField");
CuiHelper.DestroyUi(bPlayer, "emailInputFieldMessage");
CuiHelper.DestroyUi(bPlayer, "playersFound");
CuiHelper.DestroyUi(bPlayer, "messageSent");
CuiHelper.DestroyUi(bPlayer, "receivedPanel");
CuiHelper.DestroyUi(bPlayer, "selectedEmail");
CuiHelper.DestroyUi(bPlayer, "noReceived");
CuiHelper.DestroyUi(bPlayer, "clearBttn");
CuiHelper.DestroyUi(bPlayer, "sentPanel");
CuiHelper.DestroyUi(bPlayer, "email.find.online");
CuiHelper.DestroyUi(bPlayer, "onlineMainframe");
CuiElementContainer menu = receivedCui(player);
CuiHelper.AddUi(bPlayer, menu);
}
[Command("zmail.email.clear")]
void clearAllEmails(IPlayer player) {
DataFileSystem dataFile = new DataFileSystem($"{Interface.Oxide.DataDirectory}\\ZMail\\{player.Id.ToString()}");
Dictionary<string, string> mailData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, string>>($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}received");
mailData.Clear();
Interface.Oxide.DataFileSystem.WriteObject($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}received", mailData);
Dictionary<string , string> idData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, string>>($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}unread");
idData.Clear();
Interface.Oxide.DataFileSystem.WriteObject($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}unread", idData);
receivedMenuLoad(player);
}
[Command("zmail.sent.clear")]
void clearAllSentEmails(IPlayer player) {
DataFileSystem dataFile = new DataFileSystem($"{Interface.Oxide.DataDirectory}\\ZMail\\{player.Id.ToString()}");
Dictionary<string, string> mailData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, string>>($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}sent");
mailData.Clear();
Interface.Oxide.DataFileSystem.WriteObject($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}sent", mailData);
sentEmailLoad(player);
}
#endregion
#region Other Commands
[Command("zmail.email.recipient")]
void newEmailRecipient(IPlayer player, string command, string[] args) {
if (args == null || args.Length == 0) return;
var recVar = players.FindPlayer(args[0]);
BasePlayer bPlayer = BasePlayer.Find(player.Id);
CuiHelper.DestroyUi(bPlayer, "onlineMainframe");
if (recVar == null) {
CuiElementContainer menu = NoPlayerFound(player);
CuiHelper.DestroyUi(bPlayer, "playersFound");
CuiHelper.AddUi(bPlayer, menu);
return;
}
recipientMap[player] = recVar;
// Use assignment to update the existing key's value
CuiHelper.DestroyUi(bPlayer, "playersFound");
CuiElementContainer menu1 = FoundPlayers(player, recVar.Name);
CuiHelper.AddUi(bPlayer, menu1);
}
[Command("zmail.email.message")]
void newEmailMessage(IPlayer player, string command, string[] args) {
if (args == null || args.Length == 0) return;
string msg = string.Join(" ", args);
message[player] = msg;
}
void emailSender(IPlayer player) {
senderMap[player] = player;
}
[Command("zmail.send.email")]
void sendEmail(IPlayer player, string command, string[] args) {
emailSender(player);
if (!recipientMap.ContainsKey(player)) return;
if (!message.ContainsKey(player)) return;
if (!senderMap.ContainsKey(player)) return;
string msg = "";
foreach(var v in message) {
if(v.Key == player) {
msg = v.Value;
break;
}
}
if (msg.Length <= 0) return;
IPlayer sender = null;
IPlayer recipient = null;
foreach(var i in recipientMap) {
if(i.Key == player) {
recipient = i.Value;
break;
}
}
foreach(var j in senderMap) {
if(j.Key == player) {
sender = j.Value;
break;
}
}
BasePlayer bPlayer = BasePlayer.Find(player.Id);
BasePlayer bRecipient = BasePlayer.Find(recipient.Id);
DataFileSystem dataFile = new DataFileSystem($"{Interface.Oxide.DataDirectory}\\ZMail\\{recipient.Id.ToString()}");
CuiElementContainer menuMessage = MessageSent(player);
if (Interface.Oxide.DataFileSystem.ExistsDatafile($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{recipient.Id.ToString()}{Path.DirectorySeparatorChar}received")) {
Dictionary<string, string> mailData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, string>>($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{recipient.Id.ToString()}{Path.DirectorySeparatorChar}received");
int nextId = mailData.Keys.Select(k => int.Parse(k.Split('_')[0])).DefaultIfEmpty(0).Max() + 1;
mailData.Add($"{nextId}_ID {sender.Id}", $"{msg}");
Interface.Oxide.DataFileSystem.WriteObject($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{recipient.Id.ToString()}{Path.DirectorySeparatorChar}received", mailData);
if (Interface.Oxide.DataFileSystem.ExistsDatafile($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{recipient.Id.ToString()}{Path.DirectorySeparatorChar}unread")) {
Dictionary<string, string> idData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, string>>($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{recipient.Id.ToString()}{Path.DirectorySeparatorChar}unread");
idData.Add($"{nextId}_ID", "");
Interface.Oxide.DataFileSystem.WriteObject($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{recipient.Id.ToString()}{Path.DirectorySeparatorChar}unread", idData);
}
else {
dataFile.SaveDatafile("unread");
Dictionary<string, string> idData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, string>>($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{recipient.Id.ToString()}{Path.DirectorySeparatorChar}unread");
idData.Add($"{nextId}_ID", "");
Interface.Oxide.DataFileSystem.WriteObject($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{recipient.Id.ToString()}{Path.DirectorySeparatorChar}unread", idData);
}
if(bRecipient != null && configData.realTimeNotify != false) {
Dictionary<string, string> idData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, string>>($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{recipient.Id.ToString()}{Path.DirectorySeparatorChar}unread");
bRecipient.ChatMessage(String.Format(lang.GetMessage("receivedNew", this, bRecipient.UserIDString), bPlayer.displayName, idData.Count.ToString()));
}
CuiHelper.DestroyUi(bPlayer, "emailInputBackground");
CuiHelper.DestroyUi(bPlayer, "emailInputScreen");
CuiHelper.DestroyUi(bPlayer, "emailInputBackgroundMessage");
CuiHelper.DestroyUi(bPlayer, "emailInputScreenMessage");
CuiHelper.DestroyUi(bPlayer, "emailSendButton");
CuiHelper.DestroyUi(bPlayer, "emailInputField");
CuiHelper.DestroyUi(bPlayer, "emailInputFieldMessage");
CuiHelper.DestroyUi(bPlayer, "playersFound");
CuiHelper.AddUi(bPlayer, menuMessage);
timer.Once(1.5f, () => {
CuiHelper.DestroyUi(bPlayer, "messageSent");
}
);
}
else {
dataFile.SaveDatafile("received");
Dictionary<string, string> mailData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, string>>($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{recipient.Id.ToString()}{Path.DirectorySeparatorChar}received");
int nextId = mailData.Keys.Select(k => int.Parse(k.Split('_')[0])).DefaultIfEmpty(0).Max() + 1;
mailData.Add($"{nextId}_ID {sender.Id}", $"{msg}");
Interface.Oxide.DataFileSystem.WriteObject($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{recipient.Id.ToString()}{Path.DirectorySeparatorChar}received", mailData);
if (Interface.Oxide.DataFileSystem.ExistsDatafile($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{recipient.Id.ToString()}{Path.DirectorySeparatorChar}unread")) {
Dictionary<string, string> idData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, string>>($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{recipient.Id.ToString()}{Path.DirectorySeparatorChar}unread");
idData.Add($"{nextId}_ID", "");
Interface.Oxide.DataFileSystem.WriteObject($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{recipient.Id.ToString()}{Path.DirectorySeparatorChar}unread", idData);
}
else {
dataFile.SaveDatafile("unread");
Dictionary<string, string> idData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, string>>($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{recipient.Id.ToString()}{Path.DirectorySeparatorChar}unread");
idData.Add($"{nextId}_ID", "");
Interface.Oxide.DataFileSystem.WriteObject($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{recipient.Id.ToString()}{Path.DirectorySeparatorChar}unread", idData);
}
CuiHelper.DestroyUi(bPlayer, "emailInputBackground");
CuiHelper.DestroyUi(bPlayer, "emailInputScreen");
CuiHelper.DestroyUi(bPlayer, "emailInputBackgroundMessage");
CuiHelper.DestroyUi(bPlayer, "emailInputScreenMessage");
CuiHelper.DestroyUi(bPlayer, "emailSendButton");
CuiHelper.DestroyUi(bPlayer, "emailInputField");
CuiHelper.DestroyUi(bPlayer, "emailInputFieldMessage");
CuiHelper.DestroyUi(bPlayer, "playersFound");
CuiHelper.AddUi(bPlayer, menuMessage);
timer.Once(1.5f, () => {
CuiHelper.DestroyUi(bPlayer, "messageSent");
}
);
}
dataFile = new DataFileSystem($"{Interface.Oxide.DataDirectory}\\ZMail\\{player.Id.ToString()}");
if (Interface.Oxide.DataFileSystem.ExistsDatafile($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}sent")) {
Dictionary<string, string> mailData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, string>>($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}sent");
int nextId = mailData.Keys.Select(k => int.Parse(k.Split('_')[0])).DefaultIfEmpty(0).Max() + 1;
mailData.Add($"{nextId}_ID {recipient.Id}", $"{msg}");
Interface.Oxide.DataFileSystem.WriteObject($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}sent", mailData);
CuiHelper.DestroyUi(bPlayer, "emailInputBackground");
CuiHelper.DestroyUi(bPlayer, "emailInputScreen");
CuiHelper.DestroyUi(bPlayer, "emailInputBackgroundMessage");
CuiHelper.DestroyUi(bPlayer, "emailInputScreenMessage");
CuiHelper.DestroyUi(bPlayer, "emailSendButton");
CuiHelper.DestroyUi(bPlayer, "emailInputField");
CuiHelper.DestroyUi(bPlayer, "emailInputFieldMessage");
CuiHelper.DestroyUi(bPlayer, "playersFound");
}
else {
dataFile.SaveDatafile("sent");
Dictionary<string, string> mailData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, string>>($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}sent");
int nextId = mailData.Keys.Select(k => int.Parse(k.Split('_')[0])).DefaultIfEmpty(0).Max() + 1;
mailData.Add($"{nextId}_ID {recipient.Id}", $"{msg}");
Interface.Oxide.DataFileSystem.WriteObject($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}sent", mailData);
CuiHelper.DestroyUi(bPlayer, "emailInputBackground");
CuiHelper.DestroyUi(bPlayer, "emailInputScreen");
CuiHelper.DestroyUi(bPlayer, "emailInputBackgroundMessage");
CuiHelper.DestroyUi(bPlayer, "emailInputScreenMessage");
CuiHelper.DestroyUi(bPlayer, "emailSendButton");
CuiHelper.DestroyUi(bPlayer, "emailInputField");
CuiHelper.DestroyUi(bPlayer, "emailInputFieldMessage");
CuiHelper.DestroyUi(bPlayer, "playersFound");
}
foreach(var v in message) {
if(message.ContainsKey(player)) {
message.Remove(player);
break;
}
}
foreach(var i in recipientMap) {
if(recipientMap.ContainsKey(player)) {
recipientMap.Remove(player);
break;
}
}
foreach(var j in senderMap) {
if(senderMap.ContainsKey(player)) {
senderMap.Remove(player);
break;
}
}
CuiHelper.DestroyUi(bPlayer, "email.find.online");
}
[Command("zmail.received.next")]
void nextReceivedPage(IPlayer player) {
//////////// Basically fix for Nullreference exceptions
DataFileSystem dataFile = new DataFileSystem($"{Interface.Oxide.DataDirectory}\\ZMail\\{player.Id.ToString()}");
if (Interface.Oxide.DataFileSystem.ExistsDatafile($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}received")) {
}
else {
dataFile.SaveDatafile("received");
}
if (dataFile.GetDatafile("received") == null) {
dataFile.SaveDatafile("received");
}
Dictionary<string, string> mailData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, string>>($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}received");
////////////
int pageSize = 20;
// Number of logs to show per page
int locVal = 1;
foreach(var v in currentPageRec) {
if(v.Key == player) {
locVal = v.Value;
break;
}
}
int startIndex = (locVal - 1) * pageSize;
int endIndex = Math.Min(startIndex + pageSize, mailData.Count);
// Check if already on the last page
if (endIndex == mailData.Count) return;
int i = 0;
foreach (var v in currentPageRec) {
if (v.Key == player) {
i = v.Value;
currentPageRec.Remove(v.Key);
currentPageRec.Add(player, i += 1);
break;
}
}
receivedMenuLoad(player);
}
[Command("zmail.received.previous")]
void previousReceivedPage(IPlayer player) {
foreach(var v in currentPageRec) {
if(v.Key == player) {
int i = v.Value;
currentPageRec.Remove(player);
currentPageRec.Add(player, Math.Max(1, i - 1));
break;
}
}
receivedMenuLoad(player);
}
[Command("zmail.open.selected")]
void openSelectedMail(IPlayer player, string command, string[] args) {
if (!permission.UserHasPermission(player.Id, permUse)) {
player.Message(lang.GetMessage("NoPerms", this, player.Id));
return;
}
Dictionary<string, string> idData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, string>>($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}unread");
string id = args[0];
foreach(var v in idData) {
if(v.Key.Contains(id)) {
idData.Remove(v.Key);
Interface.Oxide.DataFileSystem.WriteObject<Dictionary<string, string>>($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}unread", idData);
break;
}
}
IPlayer whoSendPlayer = players.FindPlayer(args[1]);
string text = string.Join(" ", args.Skip(2));
string whoSend = whoSendPlayer.Name;
BasePlayer bPlayer = BasePlayer.Find(player.Id);
CuiHelper.DestroyUi(bPlayer, "selectedEmail");
CuiElementContainer menu = openSelectedCui(player, id, whoSend, text);
CuiHelper.AddUi(bPlayer, menu);
CuiHelper.DestroyUi(bPlayer, "receivedPanel");
CuiHelper.DestroyUi(bPlayer, "clearBttn");
}
[Command("zmail.open.selected.sent")]
void openSelectedSent(IPlayer player, string command, string[] args) {
if (!permission.UserHasPermission(player.Id, permUse)) {
player.Message(lang.GetMessage("NoPerms", this, player.Id));
return;
}
string id = args[0];
IPlayer whoSendPlayer = players.FindPlayer(args[1]);
string text = string.Join(" ", args.Skip(2));
string whoSend = whoSendPlayer.Name;
BasePlayer bPlayer = BasePlayer.Find(player.Id);
CuiHelper.DestroyUi(bPlayer, "selectedEmail");
CuiElementContainer menu = openSelectedSentCui(player, id, whoSend, text);
CuiHelper.AddUi(bPlayer, menu);
CuiHelper.DestroyUi(bPlayer, "receivedPanel");
CuiHelper.DestroyUi(bPlayer, "clearBttn");
}
[Command("zmail.selected.close")]
void closeSelected(IPlayer player) {
BasePlayer bPlayer = BasePlayer.Find(player.Id);
CuiHelper.DestroyUi(bPlayer, "selectedEmail");
receivedMenuLoad(player);
}
[Command("zmail.selected.close.sent")]
void closeSelectedSent(IPlayer player) {
BasePlayer bPlayer = BasePlayer.Find(player.Id);
CuiHelper.DestroyUi(bPlayer, "selectedEmail");
sentEmailLoad(player);
}
[Command("zmail.email.remove")]
void removeSelected(IPlayer player, string command, string[] args) {
DataFileSystem dataFile = new DataFileSystem($"{Interface.Oxide.DataDirectory}\\ZMail\\{player.Id.ToString()}");
Dictionary<string, string> mailData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, string>>($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}received");
foreach (var dataLine in mailData.Keys.ToList()) {
if (dataLine.Contains(args[0])) {
mailData.Remove(dataLine);
break;
}
}
Interface.Oxide.DataFileSystem.WriteObject($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}received", mailData);
BasePlayer bPlayer = BasePlayer.Find(player.Id);
CuiHelper.DestroyUi(bPlayer, "selectedEmail");
receivedMenuLoad(player);
}
[Command("zmail.sent.remove")]
void removeSelectedSent(IPlayer player, string command, string[] args) {
DataFileSystem dataFile = new DataFileSystem($"{Interface.Oxide.DataDirectory}\\ZMail\\{player.Id.ToString()}");
Dictionary<string, string> mailData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, string>>($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}sent");
foreach (var dataLine in mailData.Keys.ToList()) {
if (dataLine.Contains(args[0])) {
mailData.Remove(dataLine);
break;
}
}
Interface.Oxide.DataFileSystem.WriteObject($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}sent", mailData);
BasePlayer bPlayer = BasePlayer.Find(player.Id);
CuiHelper.DestroyUi(bPlayer, "selectedEmail");
sentEmailLoad(player);
}
[Command("zmail.sent.next")]
void nextSentPage(IPlayer player) {
//////////// Basically fix for Nullreference exceptions
DataFileSystem dataFile = new DataFileSystem($"{Interface.Oxide.DataDirectory}\\ZMail\\{player.Id.ToString()}");
if (Interface.Oxide.DataFileSystem.ExistsDatafile($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}sent")) {
}
else {
dataFile.SaveDatafile("sent");
}
if (dataFile.GetDatafile("sent") == null) {
dataFile.SaveDatafile("sent");
}
Dictionary<string, string> mailData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, string>>($"{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}ZMail{Path.DirectorySeparatorChar}{player.Id.ToString()}{Path.DirectorySeparatorChar}sent");
////////////
int pageSize = 20;
// Number of logs to show per page
int locVal = 1;
foreach (var v in currentPageSen) {
if (v.Key == player) {
locVal = v.Value;
break;
}
}
int startIndex = (locVal - 1) * pageSize;
int endIndex = Math.Min(startIndex + pageSize, mailData.Count);
// Check if already on the last page
if (endIndex == mailData.Count) return;
int i = 0;
foreach (var v in currentPageSen) {
if (v.Key == player) {
i = v.Value;
currentPageSen.Remove(v.Key);
currentPageSen.Add(player, i += 1);
break;
}
}
sentEmailLoad(player);
}
[Command("zmail.sent.previous")]
void previousSentPage(IPlayer player) {
foreach (var v in currentPageSen) {
if (v.Key == player) {
int i = v.Value;
currentPageSen.Remove(player);
currentPageSen.Add(player, Math.Max(1, i - 1));
break;
}
}
sentEmailLoad(player);
}
#endregion
#region Main Menu Cui
CuiElementContainer emailCui(IPlayer player) {
var elements = new CuiElementContainer();
// Main panel, where all other things are
AddCuiPanel(elements, true, "0.39 0.39 0.39 0.93", "0.2 0.2", "0.8 0.8", "-50 -50", "50 50", "Hud", "emailMainframe");
// Button to close email ui
AddCuiButton(elements, "0.878 0.047 0 1", "zmail.email.close", "0.94 0.97", "0.995 0.995", null, null, "x", "0 0 0 1", 10, TextAnchor.MiddleCenter, "emailMainframe", "emailClose");
// Button send email category
AddCuiButton(elements, "0.878 0.353 0.067 1", "zmail.email.load", "0.02 0.8", "0.1 0.85", null, null, lang.GetMessage("newEmailButton", this, player.Id), null, 10, TextAnchor.MiddleCenter, "emailMainframe", "newEmailBttn");
// Button received emails category
AddCuiButton(elements, "0.878 0.353 0.067 1", "zmail.received.load", "0.02 0.7", "0.1 0.75", null, null, lang.GetMessage("receivedEmailsButton", this, player.Id), null, 10, TextAnchor.MiddleCenter, "emailMainframe", "receivedBttn");
// Button sent emails category
AddCuiButton(elements, "0.878 0.353 0.067 1", "zmail.sent.load", "0.02 0.6", "0.1 0.65", null, null, lang.GetMessage("sentEmailsButton", this, player.Id), null, 10, TextAnchor.MiddleCenter, "emailMainframe", "sentBttn");
return elements;
}
#endregion
#region Help CUI
CuiElementContainer NoPlayerFound(IPlayer player) {
var elements = new CuiElementContainer();
AddCuiLabel(elements, "0.37 0.8", "0.5 0.85", null, null, lang.GetMessage("noPlayerFound", this, player.Id), "1 0 0 1", 10, TextAnchor.MiddleCenter, "emailMainframe", "playersFound");
return elements;
}
CuiElementContainer FoundPlayers(IPlayer player, string targetName) {
var elements = new CuiElementContainer();
AddCuiLabel(elements, "0.37 0.8", "0.5 0.85", null, null, $"{String.Format(lang.GetMessage("foundPlayerToSend", this, player.Id), targetName)}", "0 1 0 1", 10, TextAnchor.MiddleCenter, "emailMainframe", "playersFound");
return elements;
}
CuiElementContainer MessageSent(IPlayer player) {
var elements = new CuiElementContainer();
var label = elements.Add(new CuiLabel {
RectTransform = {
AnchorMin = "0.37 0.8", AnchorMax = "0.5 0.85"
}
, Text = {
Text = lang.GetMessage("succussfullySend", this, player.Id), Align = TextAnchor.MiddleCenter, FontSize = 10
}
}
, "emailMainframe", "messageSent");
return elements;
}
CuiElementContainer openSelectedCui(IPlayer player, string id, string whoSend, string text) {
var elements = new CuiElementContainer();
AddCuiPanel(elements, true, "0.412 0.412 0.412 1", "0.2 0.2", "0.8 0.8", null, null, "Hud", "selectedEmail");
AddCuiButton(elements, "0.878 0.047 0 1", "zmail.selected.close", "0.94 0.97", "0.995 0.995", null, null, "x", "0 0 0 1", 10, TextAnchor.MiddleCenter, "selectedEmail", "closeBttn");
AddCuiLabel(elements, "0.01 0.9", "0.15 0.96", null, null, $"{lang.GetMessage("selectedFieldID", this, player.Id)} {id}", null, 15, TextAnchor.MiddleLeft, "selectedEmail", "idLabel");
AddCuiLabel(elements, "0.01 0.83", "0.7 0.89", null, null, $"{lang.GetMessage("selectedFieldFrom", this, player.Id)} {whoSend}", null, 15, TextAnchor.MiddleLeft, "selectedEmail", "whoSendLabel");
AddCuiLabel(elements, "0.01 0.76", "0.7 0.82", null, null, $"{lang.GetMessage("selectedFieldMessage", this, player.Id)}", null, 15, TextAnchor.MiddleLeft, "selectedEmail", "messageLabel");
AddCuiPanel(elements, true, "0.239 0.239 0.239 1", "0.01 0.04", "0.991 0.755", null, null, "selectedEmail", "messageBoxPanel");
AddCuiLabel(elements, "0.005 0.005", "0.995 0.995", null, null, $"{text}", null, 13, TextAnchor.UpperLeft, "messageBoxPanel", "messageBoxText");
AddCuiButton(elements, "0.878 0.047 0 1", $"zmail.email.remove {id}", "0.9 0.76", "0.99 0.82", null, null, "REMOVE", null, 10, TextAnchor.MiddleCenter, "selectedEmail", "removeBttn");
return elements;
}
CuiElementContainer openSelectedSentCui(IPlayer player, string id, string whoSend, string text) {
var elements = new CuiElementContainer();
AddCuiPanel(elements, true, "0.412 0.412 0.412 1", "0.2 0.2", "0.8 0.8", null, null, "Hud", "selectedEmail");
AddCuiButton(elements, "0.878 0.047 0 1", "zmail.selected.close.sent", "0.94 0.97", "0.995 0.995", null, null, "x", "0 0 0 1", 10, TextAnchor.MiddleCenter, "selectedEmail", "closeBttn");
AddCuiLabel(elements, "0.01 0.9", "0.15 0.96", null, null, $"{lang.GetMessage("selectedFieldID", this, player.Id)} {id}", null, 15, TextAnchor.MiddleLeft, "selectedEmail", "idLabel");
AddCuiLabel(elements, "0.01 0.83", "0.7 0.89", null, null, $"{lang.GetMessage("selectedFieldTo", this, player.Id)} {whoSend}", null, 15, TextAnchor.MiddleLeft, "selectedEmail", "whoSendLabel");
AddCuiLabel(elements, "0.01 0.76", "0.7 0.82", null, null, $"{lang.GetMessage("selectedFieldMessage", this, player.Id)}", null, 15, TextAnchor.MiddleLeft, "selectedEmail", "messageLabel");
AddCuiPanel(elements, true, "0.239 0.239 0.239 1", "0.
// ... [Code preview truncated due to length. Full source in attached file] ...