Overwrite

Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
Unstable Kitsune
2023-11-28 23:20:26 -05:00
parent 3cd54811de
commit b918192e4e
11608 changed files with 2644205 additions and 47 deletions

View File

@@ -0,0 +1,138 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using System.Drawing;
using Server;
using Server.Misc;
using Server.Mobiles;
using VitaNex.SuperGumps;
#endregion
namespace VitaNex.Modules.Voting
{
public class VotingStone : Item
{
public override bool DisplayLootType => false;
public override bool DisplayWeight => false;
private int _SiteUID;
[CommandProperty(Voting.Access)]
public int SiteUID
{
get => _SiteUID;
set
{
_SiteUID = value;
InvalidateProperties();
}
}
[CommandProperty(Voting.Access)]
public KnownColor UsageColor { get; set; }
[Constructable]
public VotingStone()
: this(4963)
{ }
[Constructable]
public VotingStone(int siteUID)
: base(4963)
{
SiteUID = siteUID;
UsageColor = KnownColor.SkyBlue;
Name = "Voting Stone";
LootType = LootType.Blessed;
Weight = 0;
}
public VotingStone(Serial serial)
: base(serial)
{ }
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
var site = Voting.FindSite(SiteUID);
if (site != null && !site.Deleted && site.Valid)
{
list.Add("Use: Cast a vote for {0} at '{1}'".WrapUOHtmlColor(UsageColor), ServerList.ServerName, site.Name);
}
else
{
list.Add("[No Vote Site Available]".WrapUOHtmlColor(Color.OrangeRed));
}
}
public override void OnDoubleClick(Mobile from)
{
var voter = from as PlayerMobile;
if (voter == null || voter.Deleted)
{
return;
}
var site = Voting.FindSite(SiteUID);
if (site != null)
{
site.Vote(voter);
}
else if (voter.AccessLevel >= Voting.Access)
{
SuperGump.Send(new VoteAdminGump(voter));
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
var version = writer.SetVersion(0);
switch (version)
{
case 0:
{
writer.WriteFlag(UsageColor);
writer.Write(_SiteUID);
}
break;
}
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
var version = reader.GetVersion();
switch (version)
{
case 0:
{
UsageColor = reader.ReadFlag<KnownColor>();
_SiteUID = reader.ReadInt();
}
break;
}
}
}
}

View File

@@ -0,0 +1,65 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using Server;
using VitaNex.Items;
#endregion
namespace VitaNex.Modules.Voting
{
public sealed class VoteToken : VendorToken
{
[Constructable]
public VoteToken()
: this(1)
{ }
[Constructable]
public VoteToken(int amount)
: base(amount)
{
Name = "Vote Token";
Hue = 2955;
}
public VoteToken(Serial serial)
: base(serial)
{ }
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
var version = writer.SetVersion(0);
switch (version)
{
case 0:
break;
}
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
var version = reader.GetVersion();
switch (version)
{
case 0:
break;
}
}
}
}

View File

@@ -0,0 +1,75 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using Server;
using VitaNex.Items;
using VitaNex.Mobiles;
#endregion
namespace VitaNex.Modules.Voting
{
public class VoteVendor : AdvancedVendor
{
[Constructable]
public VoteVendor()
: base("the vote registrar", typeof(VoteToken), "Vote Tokens", "VT")
{ }
public VoteVendor(Serial serial)
: base(serial)
{ }
protected override void InitBuyInfo()
{
AddStock<ThrowableStinkBomb>(2);
AddStock<ThrowableCat>(2);
AddStock<ThrowableRock>(2);
AddStock<StrobeLantern>(100);
AddStock<BroadcastScroll>(1);
AddStock<BroadcastScroll_3Uses>(3);
AddStock<BroadcastScroll_5Uses>(5);
AddStock<BroadcastScroll_10Uses>(10);
AddStock<BroadcastScroll_30Uses>(30);
AddStock<BroadcastScroll_50Uses>(50);
AddStock<BroadcastScroll_100Uses>(100);
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
var version = writer.SetVersion(0);
switch (version)
{
case 0:
break;
}
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
var version = reader.GetVersion();
switch (version)
{
case 0:
break;
}
}
}
}

View File

@@ -0,0 +1,374 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using Server;
using Server.Accounting;
using Server.Mobiles;
#endregion
namespace VitaNex.Modules.Voting
{
public sealed class VoteProfileEntry
{
public DateTime VoteTime { get; set; }
public IVoteSite VoteSite { get; set; }
public int TokenAmount { get; set; }
public VoteProfileEntry(DateTime when, IVoteSite site, int tokens)
{
VoteTime = when;
VoteSite = site;
TokenAmount = tokens;
}
public VoteProfileEntry(GenericReader reader)
{
Deserialize(reader);
}
public string ToHtmlString(bool technical = false)
{
var html = new StringBuilder();
if (technical)
{
html.AppendLine(
String.Format(
"[{0}]: Vote at '{1}' ({2}) for {3} tokens.",
VoteTime.ToSimpleString(Voting.CMOptions.DateFormat),
VoteSite.Name,
VoteSite.Link,
TokenAmount.ToString("#,0")));
}
else
{
html.AppendLine(
String.Format(
"[{0}]: Vote at '{1}' for {2} tokens.",
VoteTime.ToSimpleString(Voting.CMOptions.DateFormat),
VoteSite.Name,
TokenAmount.ToString("#,0")));
}
return html.ToString();
}
public void Serialize(GenericWriter writer)
{
var version = writer.SetVersion(0);
switch (version)
{
case 0:
{
writer.Write(VoteTime);
writer.Write(VoteSite.UID);
}
break;
}
}
public void Deserialize(GenericReader reader)
{
var version = reader.GetVersion();
switch (version)
{
case 0:
{
VoteTime = reader.ReadDateTime();
VoteSite = Voting.FindSite(reader.ReadInt());
}
break;
}
}
}
public sealed class VoteProfile
{
public bool Deleted { get; private set; }
public PlayerMobile Owner { get; private set; }
private static readonly IPAddress[] _DefaultIPs = new IPAddress[0];
public IPAddress[] LoginIPs => Owner != null && Owner.Account is Account ? ((Account)Owner.Account).LoginIPs : _DefaultIPs;
public Dictionary<TimeStamp, List<VoteProfileEntry>> History { get; private set; }
public VoteProfile(PlayerMobile owner)
{
Owner = owner;
History = new Dictionary<TimeStamp, List<VoteProfileEntry>>();
}
public VoteProfile(GenericReader reader)
{
Deserialize(reader);
}
private static TimeStamp GenerateKey(ref DateTime when)
{
return (when = new DateTime(when.Year, when.Month, when.Day)).ToTimeStamp();
}
public bool TransferTokens(IVoteSite site, int amount, bool message = true)
{
if (site == null || Deleted || Owner == null || Owner.Deleted)
{
return false;
}
var limitReached = false;
var total = GetTokenTotal(DateTime.UtcNow);
if (Voting.CMOptions.DailyLimit > 0)
{
if (total >= Voting.CMOptions.DailyLimit)
{
limitReached = true;
amount = 0;
}
else if ((total + amount) > Voting.CMOptions.DailyLimit)
{
limitReached = true;
amount = (total + amount) - Voting.CMOptions.DailyLimit;
}
}
if (amount > 0)
{
new VoteToken(amount).GiveTo(Owner);
}
if (limitReached && message)
{
Owner.SendMessage(0x22, "You have reached your daily token limit of {0:#,0}.", Voting.CMOptions.DailyLimit);
}
RegisterTokens(site, amount);
return true;
}
public void RegisterTokens(IVoteSite site, int amount)
{
if (site == null)
{
return;
}
var now = DateTime.UtcNow;
var when = now;
var key = GenerateKey(ref when);
if (!History.ContainsKey(key))
{
History.Add(key, new List<VoteProfileEntry>());
}
var e = GetHistory(now).FirstOrDefault(s => s.VoteSite == site);
if (e == null)
{
History[key].Add(new VoteProfileEntry(now, site, amount));
}
else
{
e.VoteTime = now;
e.TokenAmount += amount;
}
}
public void ClearHistory(DateTime when)
{
var key = GenerateKey(ref when);
if (!History.ContainsKey(key))
{
return;
}
History[key].Free(true);
History.Remove(key);
}
public void ClearHistory()
{
History.Values.Free(true);
History.Clear();
}
public IEnumerable<VoteProfileEntry> GetHistory(DateTime when, int limit = 0)
{
return GetHistory(GenerateKey(ref when), limit);
}
public IEnumerable<VoteProfileEntry> GetHistory(TimeStamp key, int limit = 0)
{
var list = History.GetValue(key);
if (list == null || list.Count <= 0)
{
return Enumerable.Empty<VoteProfileEntry>();
}
IEnumerable<VoteProfileEntry> ie = list.OrderByDescending(e => e.VoteTime);
if (limit > 0)
{
ie = ie.Take(limit);
}
return ie;
}
public IEnumerable<VoteProfileEntry> GetHistory(int limit = 0)
{
IEnumerable<VoteProfileEntry> ie = History.SelectMany(kv => kv.Value).OrderByDescending(e => e.VoteTime);
if (limit > 0)
{
ie = ie.Take(limit);
}
return ie;
}
public int GetTokenTotal(DateTime when)
{
var val = 0;
var h = History.GetValue(GenerateKey(ref when));
if (h != null)
{
val = h.Aggregate(val, (c, e) => c + e.TokenAmount);
}
return val;
}
public int GetTokenTotal()
{
return History.SelectMany(kv => kv.Value).Aggregate(0, (c, e) => c + e.TokenAmount);
}
public void Delete()
{
if (Deleted)
{
return;
}
ClearHistory();
Deleted = true;
this.Remove();
}
public string ToHtmlString(Mobile viewer = null)
{
var html = new StringBuilder();
html.AppendLine(String.Format("Vote Profile for <big>{0}</big>", Owner.RawName));
html.AppendLine();
var totalToday = GetTokenTotal(DateTime.UtcNow);
var totalAllTime = GetTokenTotal();
var limitToday = Voting.CMOptions.DailyLimit;
if (limitToday <= 0)
{
html.AppendLine(String.Format("Tokens Collected Today: <big>{0}</big>", totalToday.ToString("#,0")));
}
else
{
html.AppendLine(
String.Format(
"Tokens Collected Today: <big>{0}</big>/<big>{1}</big>",
totalToday.ToString("#,0"),
limitToday.ToString("#,0")));
}
html.AppendLine(String.Format("Tokens Collected Total: <big>{0}</big>", totalAllTime.ToString("#,0")));
return html.ToString();
}
public void Serialize(GenericWriter writer)
{
var version = writer.SetVersion(0);
switch (version)
{
case 0:
{
writer.Write(Owner);
writer.Write(Deleted);
if (!Deleted)
{
writer.WriteBlockDictionary(
History,
(w1, k, v) =>
{
w1.Write(k.Stamp);
w1.WriteBlockList(v, (w2, e) => e.Serialize(w2));
});
}
}
break;
}
}
public void Deserialize(GenericReader reader)
{
var version = reader.GetVersion();
switch (version)
{
case 0:
{
Owner = reader.ReadMobile<PlayerMobile>();
Deleted = reader.ReadBool();
if (!Deleted)
{
History = reader.ReadBlockDictionary(
r1 =>
{
TimeStamp k = r1.ReadDouble();
var v = r1.ReadBlockList(r2 => new VoteProfileEntry(r2));
return new KeyValuePair<TimeStamp, List<VoteProfileEntry>>(k, v);
});
}
}
break;
}
if (History != null)
{
foreach (var h in History.Values)
{
h.Prune(true, e => e.VoteSite);
}
}
}
}
}

View File

@@ -0,0 +1,36 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using Server;
#endregion
namespace VitaNex.Modules.Voting
{
public class VoteRequestEventArgs : EventArgs
{
public VoteRequestEventArgs(Mobile from, IVoteSite site, int tokens, bool message)
{
Mobile = from;
Site = site;
Tokens = tokens;
Message = message;
}
public Mobile Mobile { get; private set; }
public IVoteSite Site { get; private set; }
public int Tokens { get; set; }
public bool Message { get; set; }
public bool HandledTokens { get; set; }
}
}

View File

@@ -0,0 +1,413 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using System.Linq;
using Server;
using Server.Mobiles;
#endregion
namespace VitaNex.Modules.Voting
{
public interface IVoteSite
{
int UID { get; }
bool Valid { get; }
bool Deleted { get; }
bool Enabled { get; set; }
string Name { get; set; }
string Link { get; set; }
TimeSpan Interval { get; set; }
int Tokens { get; set; }
int BonusTokens { get; set; }
int BonusTokensChance { get; set; }
bool CanVote(PlayerMobile voter, bool message = true);
void Serialize(GenericWriter writer);
void Deserialize(GenericReader reader);
bool ValidateLink();
bool Vote(PlayerMobile voter, bool message = true);
void Delete();
}
public class VoteSite : PropertyObject, IVoteSite, IEquatable<IVoteSite>
{
public static VoteSite Empty = new VoteSite(String.Empty, String.Empty, TimeSpan.Zero, 0, 0, 0);
private int _BonusTokens;
private int _BonusTokensChance;
private string _Link;
public int UID { get; private set; }
public bool Deleted { get; private set; }
[CommandProperty(Voting.Access)]
public bool Enabled { get; set; }
[CommandProperty(Voting.Access)]
public string Name { get; set; }
[CommandProperty(Voting.Access)]
public string Link
{
get => _Link;
set
{
_Link = value;
ValidateLink();
}
}
[CommandProperty(Voting.Access)]
public TimeSpan Interval { get; set; }
[CommandProperty(Voting.Access)]
public int Tokens { get; set; }
[CommandProperty(Voting.Access)]
public int BonusTokens { get => _BonusTokens; set => _BonusTokens = Math.Max(0, value); }
[CommandProperty(Voting.Access)]
public int BonusTokensChance
{
get => _BonusTokensChance;
set => _BonusTokensChance = Math.Max(0, Math.Min(100, value));
}
[CommandProperty(Voting.Access)]
public bool Valid => (!Deleted && !String.IsNullOrWhiteSpace(Name) && ValidateLink());
public VoteSite()
: this("Vita-Nex", "http://core.vita-nex.com", TimeSpan.Zero, 0, 0, 0)
{ }
public VoteSite(string name, string link, TimeSpan interval, int tokens, int bonusTokens, int bonusTokensChance)
{
UID = (int)TimeStamp.UtcNow.Stamp;
Name = name;
Link = link;
Interval = interval;
Tokens = tokens;
BonusTokens = bonusTokens;
BonusTokensChance = bonusTokensChance;
}
public VoteSite(GenericReader reader)
: base(reader)
{ }
public virtual bool CanVote(PlayerMobile voter, bool message = true)
{
if (voter == null || voter.Deleted)
{
return false;
}
if (!Valid || !Enabled || Deleted)
{
if (message)
{
voter.SendMessage(0x22, "This vote site is currently disabled.");
}
return false;
}
var p = Voting.EnsureProfile(voter);
if (p == null || p.Deleted)
{
if (message)
{
voter.SendMessage(0x22, "Your vote profile can't be accessed right now.");
}
return false;
}
var now = DateTime.UtcNow;
if (Interval <= TimeSpan.Zero)
{
return true;
}
TimeSpan time;
var entry = p.GetHistory(now - Interval).FirstOrDefault(e => e.VoteSite == this);
if (entry != null)
{
time = Interval - (now - entry.VoteTime);
if (time > TimeSpan.Zero)
{
if (message)
{
voter.SendMessage(0x22, "You can't vote at this site yet. Try again in {0}", time.ToSimpleString("h:m:s"));
}
return false;
}
}
if (!Voting.CMOptions.RestrictByIP)
{
return true;
}
p = Voting.Profiles.Values.FirstOrDefault(o => o != p && o.Owner.Account.IsSharedWith(p.Owner.Account));
if (p == null)
{
return true;
}
entry = p.GetHistory(now - Interval).FirstOrDefault(e => e.VoteSite == this);
if (entry == null)
{
return true;
}
time = Interval - (now - entry.VoteTime);
if (time <= TimeSpan.Zero)
{
return true;
}
if (message)
{
voter.SendMessage(
"You have already cast a vote from this IP recently. Try again in {0}",
time.ToSimpleString("h:m:s"));
}
return false;
}
public virtual bool Vote(PlayerMobile voter, bool message = true)
{
if (voter == null || voter.Deleted || !CanVote(voter, message))
{
return false;
}
var p = Voting.EnsureProfile(voter);
if (p == null || p.Deleted)
{
if (message)
{
voter.SendMessage("Your vote profile can't be accessed right now.");
}
return false;
}
if (message)
{
voter.SendMessage("Thanks for voting, {0}! Every vote counts!", voter.RawName);
}
var tokens = Tokens;
if (Voting.CMOptions.GiveBonusTokens && BonusTokens > 0 && Utility.RandomMinMax(0, 100) <= BonusTokensChance)
{
tokens += BonusTokens;
if (message)
{
voter.SendMessage("You've just earned {0} bonus tokens!", BonusTokens);
}
}
var e = new VoteRequestEventArgs(voter, this, tokens, message);
VitaNexCore.TryCatch(e.Invoke, Voting.CMOptions.ToConsole);
if (tokens != e.Tokens)
{
tokens = Math.Max(0, e.Tokens);
}
message = e.Message;
if (!e.HandledTokens)
{
p.TransferTokens(this, tokens, message);
}
else
{
p.RegisterTokens(this, tokens);
}
Timer.DelayCall(Voting.CMOptions.BrowserDelay, () => voter.LaunchBrowser(Link));
return true;
}
public bool ValidateLink()
{
if (String.IsNullOrWhiteSpace(_Link))
{
return false;
}
var link = _Link;
if (!Insensitive.StartsWith(link, Uri.UriSchemeHttp) && !Insensitive.StartsWith(link, Uri.UriSchemeHttps))
{
link = Uri.UriSchemeHttp + link;
}
if (Uri.TryCreate(link, UriKind.Absolute, out var test))
{
_Link = test.ToString();
return true;
}
return false;
}
public void Delete()
{
if (Deleted)
{
return;
}
Deleted = true;
this.Remove();
}
public override void Clear()
{
Enabled = false;
Name = String.Empty;
Link = String.Empty;
Interval = TimeSpan.Zero;
Tokens = 0;
}
public override void Reset()
{
Enabled = false;
Name = String.Empty;
Link = String.Empty;
Interval = TimeSpan.FromHours(24.0);
Tokens = 1;
}
public override string ToString()
{
return Link;
}
public override int GetHashCode()
{
return UID;
}
public override bool Equals(object obj)
{
return obj is IVoteSite && Equals((IVoteSite)obj);
}
public bool Equals(IVoteSite other)
{
return !ReferenceEquals(other, null) && UID == other.UID;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
var version = writer.SetVersion(0);
switch (version)
{
case 0:
{
writer.Write(UID);
writer.Write(Enabled);
writer.Write(Name);
writer.Write(Link);
writer.Write(Interval);
writer.Write(Tokens);
writer.Write(BonusTokens);
writer.Write(BonusTokensChance);
}
break;
}
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
var version = reader.GetVersion();
switch (version)
{
case 0:
{
UID = reader.ReadInt();
Enabled = reader.ReadBool();
Name = reader.ReadString();
Link = reader.ReadString();
Interval = reader.ReadTimeSpan();
Tokens = reader.ReadInt();
BonusTokens = reader.ReadInt();
BonusTokensChance = reader.ReadInt();
}
break;
}
}
public static bool operator ==(VoteSite l, VoteSite r)
{
return ReferenceEquals(l, null) ? ReferenceEquals(r, null) : l.Equals(r);
}
public static bool operator !=(VoteSite l, VoteSite r)
{
return ReferenceEquals(l, null) ? !ReferenceEquals(r, null) : !l.Equals(r);
}
public static bool operator ==(VoteSite l, IVoteSite r)
{
return ReferenceEquals(l, null) ? ReferenceEquals(r, null) : l.Equals(r);
}
public static bool operator !=(VoteSite l, IVoteSite r)
{
return ReferenceEquals(l, null) ? !ReferenceEquals(r, null) : !l.Equals(r);
}
public static bool operator ==(IVoteSite l, VoteSite r)
{
return ReferenceEquals(l, null) ? ReferenceEquals(r, null) : l.Equals(r);
}
public static bool operator !=(IVoteSite l, VoteSite r)
{
return ReferenceEquals(l, null) ? !ReferenceEquals(r, null) : !l.Equals(r);
}
}
}

View File

@@ -0,0 +1,214 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using Server;
using Server.Commands;
using Server.Mobiles;
using VitaNex.SuperGumps;
#endregion
namespace VitaNex.Modules.Voting
{
public sealed class VotingOptions : CoreModuleOptions
{
private string _AdminCommand;
private string _ProfilesCommand;
private string _VoteCommand;
[CommandProperty(Voting.Access)]
public string AdminCommand
{
get => _AdminCommand;
set => CommandUtility.Replace(_AdminCommand, Voting.Access, HandleAdminCommand, (_AdminCommand = value));
}
[CommandProperty(Voting.Access)]
public string ProfilesCommand
{
get => _ProfilesCommand;
set => CommandUtility.Replace(_ProfilesCommand, AccessLevel.Player, HandleProfilesCommand, (_ProfilesCommand = value));
}
[CommandProperty(Voting.Access)]
public string VoteCommand
{
get => _VoteCommand;
set => CommandUtility.Replace(_VoteCommand, AccessLevel.Player, HandleVoteCommand, (_VoteCommand = value));
}
[CommandProperty(Voting.Access)]
public string DateFormat { get; set; }
[CommandProperty(Voting.Access)]
public int DailyLimit { get; set; }
[CommandProperty(Voting.Access)]
public bool GiveBonusTokens { get; set; }
[CommandProperty(Voting.Access)]
public bool RestrictByIP { get; set; }
[CommandProperty(Voting.Access)]
public TimeSpan BrowserDelay { get; set; }
public VotingOptions()
: base(typeof(Voting))
{
AdminCommand = "VoteConfig";
ProfilesCommand = "VoteProfiles";
VoteCommand = "Vote";
DateFormat = "m/d/y";
DailyLimit = 0;
GiveBonusTokens = false;
BrowserDelay = TimeSpan.FromSeconds(2.0);
}
public VotingOptions(GenericReader reader)
: base(reader)
{ }
public void HandleAdminCommand(CommandEventArgs e)
{
var m = e.Mobile as PlayerMobile;
if (m == null || m.Deleted || m.NetState == null)
{
return;
}
if (ModuleEnabled && m.AccessLevel >= Voting.Access)
{
SuperGump.Send(new VoteAdminGump(m));
}
else
{
m.SendMessage(0x22, "Voting is currently out of service.");
}
}
public void HandleProfilesCommand(CommandEventArgs e)
{
var m = e.Mobile as PlayerMobile;
if (m == null || m.Deleted || m.NetState == null)
{
return;
}
if (ModuleEnabled || m.AccessLevel >= Voting.Access)
{
SuperGump.Send(new VoteProfilesGump(m));
}
else
{
m.SendMessage(0x22, "Voting is currently out of service.");
}
}
public void HandleVoteCommand(CommandEventArgs e)
{
var m = e.Mobile as PlayerMobile;
if (m == null || m.Deleted || m.NetState == null)
{
return;
}
if (ModuleEnabled || m.AccessLevel >= Voting.Access)
{
SuperGump.Send(new VoteGump(m));
}
else
{
m.SendMessage(0x22, "Voting is currently out of service.");
}
}
public override void Clear()
{
base.Clear();
DailyLimit = 0;
GiveBonusTokens = false;
RestrictByIP = false;
BrowserDelay = TimeSpan.Zero;
}
public override void Reset()
{
base.Reset();
AdminCommand = "VoteConfig";
ProfilesCommand = "VoteProfiles";
VoteCommand = "Vote";
DailyLimit = 0;
GiveBonusTokens = false;
RestrictByIP = false;
BrowserDelay = TimeSpan.FromSeconds(2.0);
}
public override string ToString()
{
return "Voting Config";
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
var version = writer.SetVersion(0);
switch (version)
{
case 0:
{
writer.Write(AdminCommand);
writer.Write(ProfilesCommand);
writer.Write(VoteCommand);
writer.Write(DateFormat);
writer.Write(DailyLimit);
writer.Write(GiveBonusTokens);
writer.Write(BrowserDelay);
writer.Write(RestrictByIP);
}
break;
}
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
var version = reader.GetVersion();
switch (version)
{
case 0:
{
AdminCommand = reader.ReadString();
ProfilesCommand = reader.ReadString();
VoteCommand = reader.ReadString();
DateFormat = reader.ReadString();
DailyLimit = reader.ReadInt();
GiveBonusTokens = reader.ReadBool();
BrowserDelay = reader.ReadTimeSpan();
RestrictByIP = reader.ReadBool();
}
break;
}
}
}
}

View File

@@ -0,0 +1,251 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using Server;
using Server.Gumps;
using VitaNex.SuperGumps.UI;
using VitaNex.Targets;
#endregion
namespace VitaNex.Modules.Voting
{
public sealed class VoteAdminGump : ListGump<IVoteSite>
{
public VoteAdminGump(Mobile user, Gump parent = null)
: base(user, parent, emptyText: "There are no sites to display.", title: "Voting Control Panel")
{
ForceRecompile = true;
}
public override string GetSearchKeyFor(IVoteSite key)
{
return key != null ? key.Name : base.GetSearchKeyFor(null);
}
protected override int GetLabelHue(int index, int pageIndex, IVoteSite entry)
{
return entry != null ? (entry.Enabled ? HighlightHue : ErrorHue) : base.GetLabelHue(index, pageIndex, null);
}
protected override string GetLabelText(int index, int pageIndex, IVoteSite entry)
{
return entry != null ? String.Format("{0}", entry.Name) : base.GetLabelText(index, pageIndex, null);
}
protected override void CompileList(List<IVoteSite> list)
{
list.Clear();
list.AddRange(Voting.VoteSites.Values);
base.CompileList(list);
}
protected override void CompileMenuOptions(MenuGumpOptions list)
{
if (User.AccessLevel >= Voting.Access)
{
list.AppendEntry(new ListGumpEntry("System Options", OpenConfig, HighlightHue));
list.AppendEntry(new ListGumpEntry("Add Vote Site", AddSite, HighlightHue));
}
list.AppendEntry(new ListGumpEntry("View Profiles", ShowProfiles));
list.AppendEntry(new ListGumpEntry("Help", ShowHelp));
base.CompileMenuOptions(list);
}
protected override void SelectEntry(GumpButton button, IVoteSite entry)
{
base.SelectEntry(button, entry);
var opts = new MenuGumpOptions();
if (User.AccessLevel >= Voting.Access)
{
opts.AppendEntry(
new ListGumpEntry(
"Options",
b =>
{
Refresh();
var pg = new PropertiesGump(User, Selected)
{
X = b.X,
Y = b.Y
};
User.SendGump(pg);
},
HighlightHue));
opts.AppendEntry(
new ListGumpEntry(
entry.Enabled ? "Disable" : "Enable",
b1 =>
{
entry.Enabled = !entry.Enabled;
Refresh(true);
},
entry.Enabled ? ErrorHue : HighlightHue));
opts.AppendEntry(new ListGumpEntry("Delete", DeleteSite, ErrorHue));
opts.AppendEntry(
new ListGumpEntry(
"Add To Stone",
b =>
{
Minimize(b);
User.SendMessage(0x55, "Select a compatible Voting Stone...");
ItemSelectTarget<VotingStone>.Begin(
User,
(u, s) =>
{
if (s != null && !s.Deleted)
{
s.SiteUID = entry.UID;
User.SendMessage(0x55, "The Voting Stone site was changed to {0}.", entry.Name);
}
else
{
User.SendMessage(0x22, "That is not a compatible Voting Stone.");
}
Maximize();
},
u => Maximize());
}));
opts.AppendEntry(
new ListGumpEntry(
"Create Stone",
b => Send(
new ConfirmDialogGump(User, this)
{
Title = "Create Voting Stone?",
Html = "You didn't select a compatible Voting Stone.\nDo you want to create one in your pack?\n" +
"Click OK to create a new Voting Stone for this site.",
AcceptHandler = ab =>
{
var stone = new VotingStone(entry.UID);
if (User.AddToBackpack(stone))
{
User.SendMessage(0x22, "The new Voting Stone was placed in your pack.");
}
else
{
stone.MoveToWorld(User.Location, User.Map);
User.SendMessage(0x22, "The new Voting Stone was placed at your feet.");
}
}
})));
opts.AppendEntry(new ListGumpEntry("Cancel", b => { }));
}
Send(new MenuGump(User, Refresh(), opts, button));
}
private void DeleteSite()
{
if (Selected == null)
{
return;
}
Send(
new ConfirmDialogGump(User, Refresh())
{
Title = "Delete Site?",
Html = "All data associated with this site will be deleted.\n" +
"This action can not be reversed!\nDo you want to continue?",
AcceptHandler = OnDeleteSiteConfirm
});
}
private void OnDeleteSiteConfirm(GumpButton button)
{
if (Selected != null)
{
Selected.Delete();
}
Refresh();
}
private void AddSite(GumpButton btn)
{
var opts = new MenuGumpOptions();
Voting.SiteTypes.ForEach(t => opts.AppendEntry(new ListGumpEntry(t.Name, b => OnAddSite(t))));
Refresh();
Send(new MenuGump(User, btn.Parent, opts, btn));
}
private void OnAddSite(Type t)
{
var site = VitaNexCore.TryCatchGet(() => t.CreateInstance<IVoteSite>());
if (site != null && !Voting.VoteSites.ContainsKey(site.UID))
{
Voting.VoteSites.Add(site.UID, site);
}
Refresh(true);
}
private void OpenConfig(GumpButton btn)
{
Minimize();
var p = new PropertiesGump(User, Voting.CMOptions)
{
X = X + btn.X,
Y = Y + btn.Y
};
User.SendGump(p);
}
private void ShowProfiles(GumpButton button)
{
if (User != null && !User.Deleted)
{
Send(new VoteProfilesGump(User, Hide()));
}
}
private void ShowHelp(GumpButton button)
{
if (User == null || User.Deleted)
{
return;
}
var sb = VoteGumpUtility.GetHelpText(User);
Send(
new HtmlPanelGump<StringBuilder>(User, Refresh())
{
Selected = sb,
Html = sb.ToString(),
Title = "Voting Help",
HtmlColor = Color.SkyBlue
});
}
}
}

View File

@@ -0,0 +1,266 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using System.Drawing;
using System.Linq;
using System.Text;
using Server;
using Server.Gumps;
using Server.Mobiles;
using VitaNex.SuperGumps.UI;
#endregion
namespace VitaNex.Modules.Voting
{
public sealed class VoteProfileHistoryGump : HtmlPanelGump<VoteProfile>
{
public DateTime? HistoryDate { get; set; }
public bool UseConfirmDialog { get; set; }
public bool TechnicalView { get; set; }
public VoteProfileHistoryGump(
Mobile user,
VoteProfile profile,
Gump parent = null,
bool useConfirm = true,
DateTime? when = null)
: base(user, parent, emptyText: "No profile selected.", title: "Vote Profile History", selected: profile)
{
HtmlColor = Color.SkyBlue;
UseConfirmDialog = useConfirm;
HistoryDate = when;
}
protected override void Compile()
{
base.Compile();
if (Selected == null)
{
return;
}
Html = String.Format("<basefont color=#{0:X6}>", HtmlColor.ToRgb());
if (HistoryDate != null && HistoryDate.Value <= DateTime.UtcNow)
{
Html += String.Format(
"Viewing History for {0} on {1}\n\n",
Selected.Owner.RawName,
HistoryDate.Value.ToSimpleString(Voting.CMOptions.DateFormat));
Html += "<big>Showing up to 500 entries...</big>\n\n";
Html += String.Join("\n", Selected.GetHistory(HistoryDate.Value, 500).Select(e => e.ToHtmlString(TechnicalView)));
}
else
{
Html += String.Format("Viewing Recent History for {0}\n\n", Selected.Owner.RawName);
Html += "<big>Showing up to 500 entries...</big>\n\n";
Html += String.Join("\n", Selected.GetHistory(500).Select(e => e.ToHtmlString(TechnicalView)));
}
}
protected override void CompileMenuOptions(MenuGumpOptions list)
{
if (Selected == null)
{
return;
}
if (User.AccessLevel >= Voting.Access)
{
list.AppendEntry(new ListGumpEntry("Clear History", ClearHistory, HighlightHue));
list.AppendEntry(new ListGumpEntry("Delete Profile", DeleteProfile, HighlightHue));
if (TechnicalView)
{
list.Replace(
"Technical View",
new ListGumpEntry(
"Standard View",
b =>
{
TechnicalView = false;
Refresh(true);
},
HighlightHue));
}
else
{
list.Replace(
"Standard View",
new ListGumpEntry(
"Technical View",
b =>
{
TechnicalView = true;
Refresh(true);
},
HighlightHue));
}
}
list.AppendEntry(
new ListGumpEntry(
"Show Recent",
b =>
{
HistoryDate = null;
Refresh(true);
}));
list.AppendEntry(
new ListGumpEntry(
"Show Today",
b =>
{
HistoryDate = DateTime.UtcNow;
Refresh(true);
}));
list.AppendEntry(
new ListGumpEntry(
"Select Date",
b => Send(
new InputDateDialogGump(User, Refresh())
{
Title = "Select Date",
Html = "Type the date you wish to view history for.",
InputDate = HistoryDate,
MaxDate = DateTime.UtcNow,
CallbackDate = (b1, d) =>
{
if (d.HasValue)
{
HistoryDate = d.Value;
}
else
{
User.SendMessage(0x22, "No valid date was given.");
}
Refresh(true);
}
})));
list.AppendEntry(new ListGumpEntry("Help", ShowHelp));
base.CompileMenuOptions(list);
}
private void ClearHistory(GumpButton button)
{
if (Selected == null || Selected.Deleted)
{
Selected = Voting.EnsureProfile(User as PlayerMobile);
}
if (Selected == null)
{
Refresh(true);
return;
}
if (UseConfirmDialog)
{
Send(
new ConfirmDialogGump(User, Refresh())
{
Title = "Clear Profile History?",
Html = "All data associated with the profile history will be lost.\n" +
"This action can not be reversed!\nDo you want to continue?",
AcceptHandler = ConfirmClearHistory
});
}
else
{
Selected.ClearHistory();
Refresh(true);
}
}
private void DeleteProfile(GumpButton button)
{
if (Selected == null || Selected.Deleted)
{
Selected = Voting.EnsureProfile(User as PlayerMobile);
}
if (Selected == null)
{
Refresh(true);
return;
}
if (UseConfirmDialog)
{
Send(
new ConfirmDialogGump(User, Refresh())
{
Title = "Delete Profile?",
Html = "All data associated with this profile will be deleted.\n" +
"This action can not be reversed!\nDo you want to continue?",
AcceptHandler = ConfirmDeleteProfile
});
}
else
{
Selected.Delete();
Close();
}
}
private void ConfirmClearHistory(GumpButton button)
{
if (Selected != null && !Selected.Deleted)
{
Selected.ClearHistory();
}
Refresh(true);
}
private void ConfirmDeleteProfile(GumpButton button)
{
if (Selected != null && !Selected.Deleted)
{
Selected.Delete();
}
Close();
}
private void ShowHelp(GumpButton button)
{
if (User == null || User.Deleted)
{
return;
}
var sb = VoteGumpUtility.GetHelpText(User);
Send(
new HtmlPanelGump<StringBuilder>(User, Hide(true))
{
Selected = sb,
Html = sb.ToString(),
Title = "Voting Help",
HtmlColor = Color.SkyBlue
});
}
}
}

View File

@@ -0,0 +1,196 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using System.Drawing;
using System.Text;
using Server;
using Server.Gumps;
using Server.Mobiles;
using VitaNex.SuperGumps.UI;
#endregion
namespace VitaNex.Modules.Voting
{
public class VoteProfileGump : HtmlPanelGump<VoteProfile>
{
public VoteProfileGump(Mobile user, VoteProfile profile, Gump parent = null, bool useConfirm = true)
: base(user, parent, emptyText: "No profile selected.", title: "Vote Profile", selected: profile)
{
UseConfirmDialog = useConfirm;
HtmlColor = Color.SkyBlue;
}
public bool UseConfirmDialog { get; set; }
protected override void Compile()
{
base.Compile();
if (Selected == null || Selected.Deleted)
{
Selected = Voting.EnsureProfile(User as PlayerMobile, true);
}
Html = String.Format("<basefont color=#{0:X6}>", HtmlColor.ToRgb());
if (Selected != null)
{
Html += Selected.ToHtmlString(User);
}
}
protected override void CompileMenuOptions(MenuGumpOptions list)
{
if (Selected == null || Selected.Deleted)
{
Selected = Voting.EnsureProfile(User as PlayerMobile, true);
}
if (Selected == null)
{
base.CompileMenuOptions(list);
return;
}
if (User.AccessLevel >= Voting.Access)
{
list.AppendEntry(new ListGumpEntry("Clear History", OnClearHistory, HighlightHue));
list.AppendEntry(new ListGumpEntry("Delete Profile", OnDeleteProfile, HighlightHue));
}
list.AppendEntry(new ListGumpEntry("View History", OnViewHistory, HighlightHue));
list.AppendEntry(new ListGumpEntry("Help", ShowHelp));
base.CompileMenuOptions(list);
}
private void OnViewHistory(GumpButton button)
{
if (Selected == null || Selected.Deleted)
{
Selected = Voting.EnsureProfile(User as PlayerMobile);
}
if (Selected == null)
{
Refresh(true);
return;
}
Send(new VoteProfileHistoryGump(User, Selected, Hide(true), UseConfirmDialog, DateTime.UtcNow));
}
protected virtual void OnClearHistory(GumpButton button)
{
if (Selected == null || Selected.Deleted)
{
Selected = Voting.EnsureProfile(User as PlayerMobile);
}
if (Selected == null)
{
Refresh(true);
return;
}
if (UseConfirmDialog)
{
Send(
new ConfirmDialogGump(User, Refresh())
{
Title = "Clear Profile History?",
Html =
"All data associated with the profile history will be lost.\nThis action can not be reversed!\nDo you want to continue?",
AcceptHandler = OnConfirmClearHistory
});
}
else
{
Selected.ClearHistory();
Refresh(true);
}
}
protected virtual void OnDeleteProfile(GumpButton button)
{
if (Selected == null || Selected.Deleted)
{
Selected = Voting.EnsureProfile(User as PlayerMobile);
}
if (Selected == null)
{
Refresh(true);
return;
}
if (UseConfirmDialog)
{
Send(
new ConfirmDialogGump(User, Refresh())
{
Title = "Delete Profile?",
Html =
"All data associated with this profile will be deleted.\nThis action can not be reversed!\nDo you want to continue?",
AcceptHandler = ConfirmDeleteProfile
});
}
else
{
Selected.Delete();
Close();
}
}
protected virtual void OnConfirmClearHistory(GumpButton button)
{
if (Selected != null && !Selected.Deleted)
{
Selected.ClearHistory();
}
Refresh(true);
}
protected virtual void ConfirmDeleteProfile(GumpButton button)
{
if (Selected != null && !Selected.Deleted)
{
Selected.Delete();
}
Close();
}
private void ShowHelp(GumpButton button)
{
if (User == null || User.Deleted)
{
return;
}
var sb = VoteGumpUtility.GetHelpText(User);
Send(
new HtmlPanelGump<StringBuilder>(User, Hide(true))
{
Selected = sb,
Html = sb.ToString(),
Title = "Voting Help",
HtmlColor = Color.SkyBlue
});
}
}
}

View File

@@ -0,0 +1,277 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using Server;
using Server.Gumps;
using Server.Mobiles;
using VitaNex.SuperGumps;
using VitaNex.SuperGumps.UI;
#endregion
namespace VitaNex.Modules.Voting
{
public class VoteProfilesGump : ListGump<VoteProfile>
{
public bool SortByToday { get; set; }
public bool UseConfirmDialog { get; set; }
public VoteProfilesGump(Mobile user, Gump parent = null, bool useConfirm = true, bool sortByToday = false)
: base(user, parent, emptyText: "There are no profiles to display.", title: "Vote Profiles")
{
UseConfirmDialog = useConfirm;
SortByToday = sortByToday;
ForceRecompile = true;
CanMove = false;
CanResize = false;
}
protected override void Compile()
{
base.Compile();
Title = String.Format("Vote Profiles ({0:#,0})", List.Count);
}
protected override void CompileMenuOptions(MenuGumpOptions list)
{
list.Clear();
if (User.AccessLevel >= Voting.Access)
{
list.AppendEntry(
new ListGumpEntry(
"Delete All",
button => Send(
new ConfirmDialogGump(User, this)
{
Title = "Delete All Profiles?",
Html = "All profiles in the database will be deleted, erasing all data associated with them.\n" +
"This action can not be reversed.\n\nDo you want to continue?",
AcceptHandler = subButton =>
{
while (Voting.Profiles.Count > 0)
{
var p = Voting.Profiles.Pop();
if (p.Value != null && !p.Value.Deleted)
{
p.Value.Delete();
}
else
{
Voting.Profiles.Remove(p.Key);
}
}
Refresh(true);
}
}),
ErrorHue));
}
list.AppendEntry(new ListGumpEntry("My Profile", OnMyProfile, HighlightHue));
list.AppendEntry(
new ListGumpEntry(
SortByToday ? "Sort by Grand Total" : "Sort by Today's Total",
b =>
{
SortByToday = !SortByToday;
Refresh(true);
}));
list.AppendEntry(new ListGumpEntry("Help", ShowHelp));
base.CompileMenuOptions(list);
}
protected override void CompileList(List<VoteProfile> list)
{
list.Clear();
list.AddRange(Voting.Profiles.Values);
base.CompileList(list);
}
public override string GetSearchKeyFor(VoteProfile key)
{
return key != null && !key.Deleted ? key.Owner.RawName : base.GetSearchKeyFor(key);
}
public override int SortCompare(VoteProfile a, VoteProfile b)
{
if (a == b)
{
return 0;
}
if (a == null)
{
return 1;
}
if (b == null)
{
return -1;
}
if (a.Deleted && b.Deleted)
{
return 0;
}
if (a.Deleted)
{
return 1;
}
if (b.Deleted)
{
return -1;
}
int aTotal;
int bTotal;
if (SortByToday)
{
var when = DateTime.UtcNow;
aTotal = a.GetTokenTotal(when);
bTotal = b.GetTokenTotal(when);
}
else
{
aTotal = a.GetTokenTotal();
bTotal = b.GetTokenTotal();
}
if (aTotal > bTotal)
{
return -1;
}
if (aTotal < bTotal)
{
return 1;
}
return 0;
}
protected override void CompileLayout(SuperGumpLayout layout)
{
base.CompileLayout(layout);
layout.Replace(
"label/header/title",
() => AddLabelCropped(160, 15, 215, 20, GetTitleHue(), String.IsNullOrEmpty(Title) ? DefaultTitle : Title));
}
protected override void CompileEntryLayout(
SuperGumpLayout layout,
int length,
int index,
int pIndex,
int yOffset,
VoteProfile entry)
{
base.CompileEntryLayout(layout, length, index, pIndex, yOffset, entry);
layout.Replace(
"label/list/entry/" + index,
() =>
{
AddLabelCropped(65, 2 + yOffset, 160, 20, GetLabelHue(index, pIndex, entry), GetLabelText(index, pIndex, entry));
AddLabelCropped(
225,
2 + yOffset,
150,
20,
GetSortLabelHue(index, pIndex, entry),
GetSortLabelText(index, pIndex, entry));
});
}
protected override int GetLabelHue(int index, int pageIndex, VoteProfile entry)
{
return index < 3
? HighlightHue
: (entry != null
? Notoriety.GetHue(Notoriety.Compute(User, entry.Owner))
: base.GetLabelHue(index, pageIndex, null));
}
protected override string GetLabelText(int index, int pageIndex, VoteProfile entry)
{
return entry != null && entry.Owner != null
? String.Format("{0}: {1}", (index + 1).ToString("#,#"), entry.Owner.RawName)
: base.GetLabelText(index, pageIndex, entry);
}
protected virtual string GetSortLabelText(int index, int pageIndex, VoteProfile entry)
{
if (entry != null)
{
var val = SortByToday ? entry.GetTokenTotal(DateTime.UtcNow) : entry.GetTokenTotal();
return String.Format("Tokens: {0}", (val > 0) ? val.ToString("#,#") : "0");
}
return String.Empty;
}
protected virtual int GetSortLabelHue(int index, int pageIndex, VoteProfile entry)
{
return entry != null ? ((index < 3) ? HighlightHue : TextHue) : ErrorHue;
}
protected override void SelectEntry(GumpButton button, VoteProfile entry)
{
base.SelectEntry(button, entry);
if (button != null && entry != null && !entry.Deleted)
{
Send(new VoteProfileGump(User, entry, Hide(true), UseConfirmDialog));
}
}
private void OnMyProfile(GumpButton button)
{
Send(new VoteProfileGump(User, Voting.EnsureProfile(User as PlayerMobile), Hide(true), UseConfirmDialog));
}
private void ShowHelp(GumpButton button)
{
if (User == null || User.Deleted)
{
return;
}
var sb = VoteGumpUtility.GetHelpText(User);
Send(
new HtmlPanelGump<StringBuilder>(User, Hide(true))
{
Selected = sb,
Html = sb.ToString(),
Title = "Voting Help",
HtmlColor = Color.SkyBlue
});
}
}
}

View File

@@ -0,0 +1,82 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using System.Drawing;
using System.Text;
using Server;
using Server.Commands;
using Server.Misc;
#endregion
namespace VitaNex.Modules.Voting
{
public static class VoteGumpUtility
{
public static StringBuilder GetHelpText(Mobile m)
{
var help = new StringBuilder();
help.AppendFormat("<basefont color=#{0:X6}>", Color.SkyBlue.ToRgb());
help.AppendLine(
"The Voting service allows you to vote for " + ServerList.ServerName + " and receive rewards (usually tokens).");
if (Voting.CMOptions.DailyLimit > 0)
{
help.AppendLine();
help.AppendFormat("<basefont color=#{0:X6}>", Color.Orange.ToRgb());
help.AppendLine(
String.Format(
"There is a daily limit of {0:#,0} tokens, when you reach this limit you can still vote, but will not receive any tokens.",
Voting.CMOptions.DailyLimit));
}
help.AppendLine();
help.AppendFormat("<basefont color=#{0:X6}>", Color.Yellow.ToRgb());
help.AppendLine("All successful votes will be logged to your personal vote profile.");
help.AppendLine("These logs are separated by day and can be viewed at any time.");
if (!String.IsNullOrWhiteSpace(Voting.CMOptions.ProfilesCommand))
{
help.AppendLine();
help.AppendFormat("<basefont color=#{0:X6}>", Color.YellowGreen.ToRgb());
help.AppendLine(
String.Format(
"To view vote profiles, use the <big>{0}{1}</big> command.",
CommandSystem.Prefix,
Voting.CMOptions.ProfilesCommand));
if (m.AccessLevel >= Voting.Access)
{
help.AppendLine("You have access to administrate the voting system, you can also manage profiles.");
}
}
if (m.AccessLevel >= Voting.Access)
{
if (!String.IsNullOrWhiteSpace(Voting.CMOptions.AdminCommand))
{
help.AppendLine();
help.AppendFormat("<basefont color=#{0:X6}>", Color.LimeGreen.ToRgb());
help.AppendLine(
String.Format(
"To administrate the voting system, use the <big>{0}{1}</big> command.",
CommandSystem.Prefix,
Voting.CMOptions.AdminCommand));
}
}
return help;
}
}
}

View File

@@ -0,0 +1,185 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using Server.Gumps;
using Server.Mobiles;
using VitaNex.SuperGumps;
using VitaNex.SuperGumps.UI;
#endregion
namespace VitaNex.Modules.Voting
{
public sealed class VoteGump : ListGump<IVoteSite>
{
public VoteGump(PlayerMobile user, Gump parent = null)
: base(user, parent, emptyText: "There are no sites to display.", title: "Vote Site Listing")
{
ForceRecompile = true;
}
public override string GetSearchKeyFor(IVoteSite key)
{
return key != null ? key.Name : base.GetSearchKeyFor(null);
}
protected override int GetLabelHue(int index, int pageIndex, IVoteSite entry)
{
return entry != null
? (entry.CanVote(User as PlayerMobile, false) ? HighlightHue : ErrorHue)
: base.GetLabelHue(index, pageIndex, null);
}
protected override string GetLabelText(int index, int pageIndex, IVoteSite entry)
{
return entry != null ? String.Format("{0}", entry.Name) : base.GetLabelText(index, pageIndex, null);
}
protected override void CompileList(List<IVoteSite> list)
{
list.Clear();
list.AddRange(Voting.VoteSites.Values.Where(s => s != null && !s.Deleted && s.Enabled && s.Valid));
base.CompileList(list);
}
protected override void CompileMenuOptions(MenuGumpOptions list)
{
list.AppendEntry(new ListGumpEntry("View Profiles", ShowProfiles));
list.AppendEntry(new ListGumpEntry("Help", ShowHelp));
base.CompileMenuOptions(list);
}
protected override void CompileEntryLayout(
SuperGumpLayout layout,
int length,
int index,
int pIndex,
int yOffset,
IVoteSite entry)
{
base.CompileEntryLayout(layout, length, index, pIndex, yOffset, entry);
layout.Replace(
"label/list/entry/" + index,
() =>
{
var text = GetLabelText(index, pIndex, entry);
if (entry.Valid)
{
text = text.WrapUOHtmlUrl(entry.Link);
AddHtml(65, 2 + yOffset, 325, 40, text, false, false);
}
else
{
AddLabelCropped(65, 2 + yOffset, 325, 20, GetLabelHue(index, pIndex, entry), text);
}
});
}
protected override void SelectEntry(GumpButton button, IVoteSite entry)
{
base.SelectEntry(button, entry);
CastVote();
}
public override int SortCompare(IVoteSite a, IVoteSite b)
{
if (a == b)
{
return 0;
}
if (a == null)
{
return 1;
}
if (b == null)
{
return -1;
}
if (!a.Valid && !b.Valid)
{
return 0;
}
if (!a.Valid)
{
return 1;
}
if (!b.Valid)
{
return -1;
}
if (a.Interval > b.Interval)
{
return 1;
}
if (a.Interval < b.Interval)
{
return -1;
}
return 0;
}
private void CastVote()
{
if (Selected != null)
{
Selected.Vote(User as PlayerMobile);
}
Refresh(true);
}
private void ShowProfiles(GumpButton button)
{
if (User != null && !User.Deleted)
{
Send(new VoteProfilesGump(User, Hide()));
}
}
private void ShowHelp(GumpButton button)
{
if (User == null || User.Deleted)
{
return;
}
var sb = VoteGumpUtility.GetHelpText(User);
var g = new HtmlPanelGump<StringBuilder>(User, Refresh())
{
Selected = sb,
Title = "Voting Help",
Html = sb.ToString(),
HtmlColor = Color.SkyBlue
};
g.Send();
}
}
}

View File

@@ -0,0 +1,99 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using System.Linq;
using Server;
using Server.Mobiles;
using VitaNex.IO;
#endregion
namespace VitaNex.Modules.Voting
{
public static partial class Voting
{
public const AccessLevel Access = AccessLevel.Administrator;
public static Type[] SiteTypes { get; private set; }
public static VotingOptions CMOptions { get; private set; }
public static BinaryDataStore<int, IVoteSite> VoteSites { get; private set; }
public static BinaryDataStore<PlayerMobile, VoteProfile> Profiles { get; private set; }
public static event Action<VoteRequestEventArgs> OnVoteRequest;
public static void Invoke(this VoteRequestEventArgs e)
{
if (OnVoteRequest != null && e != null)
{
OnVoteRequest(e);
}
}
public static IVoteSite FindSite(int uid)
{
VoteSites.TryGetValue(uid, out var site);
return site;
}
public static void Remove(this IVoteSite site)
{
VoteSites.Remove(site.UID);
foreach (var h in Profiles.Values.SelectMany(p => p.History.Values))
{
h.RemoveAll(
e =>
{
if (e.VoteSite != site)
{
return false;
}
e.VoteSite = null;
return true;
});
}
site.Delete();
}
public static VoteProfile EnsureProfile(PlayerMobile m, bool replace = false)
{
if (!Profiles.ContainsKey(m))
{
Profiles.Add(m, new VoteProfile(m));
}
else if (replace || Profiles[m] == null || Profiles[m].Deleted)
{
Profiles[m] = new VoteProfile(m);
}
return Profiles[m];
}
public static void Remove(this VoteProfile profile)
{
Profiles.Remove(profile.Owner);
}
public static void Prune()
{
Profiles.Values.Where(p => p.Owner == null || p.Owner.Deleted || p.History == null || p.History.Count == 0)
.ForEach(p => p.Delete());
}
}
}

View File

@@ -0,0 +1,207 @@
#region Header
// _,-'/-'/
// . __,-; ,'( '/
// \. `-.__`-._`:_,-._ _ , . ``
// `:-._,------' ` _,`--` -: `_ , ` ,' :
// `---..__,,--' (C) 2023 ` -'. -'
// # Vita-Nex [http://core.vita-nex.com] #
// {o)xxx|===============- # -===============|xxx(o}
// # #
#endregion
#region References
using System;
using System.Collections.Generic;
using Server;
using Server.Mobiles;
using VitaNex.IO;
#endregion
namespace VitaNex.Modules.Voting
{
[CoreModule("Voting", "2.0.0.0")]
public static partial class Voting
{
static Voting()
{
SiteTypes = typeof(IVoteSite).GetConstructableChildren();
CMOptions = new VotingOptions();
VoteSites = new BinaryDataStore<int, IVoteSite>(VitaNexCore.SavesDirectory + "/Voting", "Sites")
{
Async = true,
OnSerialize = SerializeVoteSites,
OnDeserialize = DeserializeVoteSites
};
Profiles = new BinaryDataStore<PlayerMobile, VoteProfile>(VitaNexCore.SavesDirectory + "/Voting", "Profiles")
{
Async = true,
OnSerialize = SerializeProfiles,
OnDeserialize = DeserializeProfiles
};
}
private static void CMConfig()
{ }
private static void CMEnabled()
{ }
private static void CMDisabled()
{ }
private static void CMInvoke()
{
if (VoteSites.Count <= 0)
{
var sites = new List<IVoteSite>();
SiteTypes.ForEach(
type =>
{
var site = type.CreateInstanceSafe<IVoteSite>();
if (site == null)
{
return;
}
if (site.Name == "Vita-Nex")
{
site.Enabled = true;
}
sites.Add(site);
CMOptions.ToConsole(
"Created site ({0}) '{1}', '{2}'",
site.GetType().Name,
site.Name,
site.Enabled ? "Enabled" : "Disabled");
});
sites.ForEach(s => VoteSites.Update(s.UID, s));
}
Prune();
}
private static void CMSave()
{
var result = VitaNexCore.TryCatchGet(VoteSites.Export, CMOptions.ToConsole);
CMOptions.ToConsole(
"{0:#,0} site{1} saved, {2}",
VoteSites.Count,
VoteSites.Count != 1 ? "s" : String.Empty,
result);
result = VitaNexCore.TryCatchGet(Profiles.Export, CMOptions.ToConsole);
CMOptions.ToConsole(
"{0:#,0} profile{1} saved, {2}",
Profiles.Count,
Profiles.Count != 1 ? "s" : String.Empty,
result);
}
private static void CMLoad()
{
var result = VitaNexCore.TryCatchGet(VoteSites.Import, CMOptions.ToConsole);
CMOptions.ToConsole(
"{0:#,0} site{1} loaded, {2}.",
VoteSites.Count,
VoteSites.Count != 1 ? "s" : String.Empty,
result);
result = VitaNexCore.TryCatchGet(Profiles.Import, CMOptions.ToConsole);
CMOptions.ToConsole(
"{0:#,0} profile{1} loaded, {2}.",
Profiles.Count,
Profiles.Count != 1 ? "s" : String.Empty,
result);
}
private static bool SerializeVoteSites(GenericWriter writer)
{
var version = writer.SetVersion(0);
switch (version)
{
case 0:
writer.WriteBlockDictionary(VoteSites, (w, k, v) => w.WriteType(v, t => v.Serialize(w)));
break;
}
return true;
}
private static bool DeserializeVoteSites(GenericReader reader)
{
var version = reader.GetVersion();
switch (version)
{
case 0:
{
reader.ReadBlockDictionary(
r =>
{
var v = r.ReadTypeCreate<IVoteSite>(r);
return new KeyValuePair<int, IVoteSite>(v.UID, v);
},
VoteSites);
}
break;
}
return true;
}
private static bool SerializeProfiles(GenericWriter writer)
{
var version = writer.SetVersion(0);
switch (version)
{
case 0:
{
writer.WriteBlockDictionary(
Profiles,
(w, k, v) =>
{
w.Write(k);
v.Serialize(w);
});
}
break;
}
return true;
}
private static bool DeserializeProfiles(GenericReader reader)
{
var version = reader.GetVersion();
switch (version)
{
case 0:
{
reader.ReadBlockDictionary(
r =>
{
var k = r.ReadMobile<PlayerMobile>();
var v = new VoteProfile(r);
return new KeyValuePair<PlayerMobile, VoteProfile>(k, v);
},
Profiles);
}
break;
}
return true;
}
}
}