Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
#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;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex
|
||||
{
|
||||
public class PlayerNamesOptions : CoreServiceOptions
|
||||
{
|
||||
private bool _IgnoreCase;
|
||||
|
||||
[CommandProperty(PlayerNames.Access)]
|
||||
public virtual bool IgnoreCase
|
||||
{
|
||||
get => _IgnoreCase;
|
||||
set
|
||||
{
|
||||
if (_IgnoreCase && !value)
|
||||
{
|
||||
PlayerNames.Registry.Comparer.Impl = EqualityComparer<string>.Default;
|
||||
}
|
||||
else if (!_IgnoreCase && value)
|
||||
{
|
||||
PlayerNames.Registry.Comparer.Impl = StringComparer.OrdinalIgnoreCase;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_IgnoreCase = value;
|
||||
|
||||
if (PlayerNames.Registry.Count > 0)
|
||||
{
|
||||
PlayerNames.Clear();
|
||||
PlayerNames.Index();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(PlayerNames.Access)]
|
||||
public virtual bool IndexOnStart { get; set; }
|
||||
|
||||
[CommandProperty(PlayerNames.Access)]
|
||||
public virtual bool NameSharing { get; set; }
|
||||
|
||||
public PlayerNamesOptions()
|
||||
: base(typeof(PlayerNames))
|
||||
{
|
||||
IndexOnStart = false;
|
||||
NameSharing = true;
|
||||
IgnoreCase = false;
|
||||
}
|
||||
|
||||
public PlayerNamesOptions(GenericReader reader)
|
||||
: base(reader)
|
||||
{ }
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
base.Clear();
|
||||
|
||||
IndexOnStart = false;
|
||||
NameSharing = true;
|
||||
IgnoreCase = false;
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
|
||||
IndexOnStart = false;
|
||||
NameSharing = true;
|
||||
IgnoreCase = false;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
var version = writer.SetVersion(2);
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 2:
|
||||
writer.Write(IgnoreCase);
|
||||
goto case 1;
|
||||
case 1:
|
||||
writer.Write(NameSharing);
|
||||
goto case 0;
|
||||
case 0:
|
||||
writer.Write(IndexOnStart);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.GetVersion();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 2:
|
||||
IgnoreCase = reader.ReadBool();
|
||||
goto case 1;
|
||||
case 1:
|
||||
NameSharing = reader.ReadBool();
|
||||
goto case 0;
|
||||
case 0:
|
||||
IndexOnStart = reader.ReadBool();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
#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 Server;
|
||||
using Server.Mobiles;
|
||||
|
||||
using VitaNex.IO;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex
|
||||
{
|
||||
public static partial class PlayerNames
|
||||
{
|
||||
public const AccessLevel Access = AccessLevel.Administrator;
|
||||
|
||||
public static PlayerNamesOptions CSOptions { get; private set; }
|
||||
|
||||
public static BinaryDataStore<string, List<PlayerMobile>> Registry { get; private set; }
|
||||
|
||||
public static event Action<PlayerMobile> OnRegistered;
|
||||
|
||||
private static void InvokeRegistered(PlayerMobile pm)
|
||||
{
|
||||
if (OnRegistered != null)
|
||||
{
|
||||
OnRegistered(pm);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsRegistered(PlayerMobile pm)
|
||||
{
|
||||
return pm != null && !String.IsNullOrWhiteSpace(FindRegisteredName(pm));
|
||||
}
|
||||
|
||||
public static void Register(PlayerMobile pm)
|
||||
{
|
||||
if (pm == null || pm.Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var rName = FindRegisteredName(pm);
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(rName) && rName != pm.RawName)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(pm.RawName))
|
||||
{
|
||||
pm.RawName = rName;
|
||||
return;
|
||||
}
|
||||
|
||||
Registry[rName].Remove(pm);
|
||||
Registry[rName].TrimExcess();
|
||||
|
||||
if (Registry[rName].Count == 0)
|
||||
{
|
||||
Registry.Remove(rName);
|
||||
}
|
||||
}
|
||||
|
||||
if (!Registry.ContainsKey(pm.RawName))
|
||||
{
|
||||
Registry.Add(
|
||||
pm.RawName,
|
||||
new List<PlayerMobile>
|
||||
{
|
||||
pm
|
||||
});
|
||||
InvokeRegistered(pm);
|
||||
}
|
||||
else if (!Registry[pm.RawName].Contains(pm))
|
||||
{
|
||||
Registry[pm.RawName].Add(pm);
|
||||
InvokeRegistered(pm);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ValidateSharedName(PlayerMobile m)
|
||||
{
|
||||
if (m != null && !CSOptions.NameSharing &&
|
||||
FindPlayers(m.RawName, p => p != m && p.CreationTime < m.CreationTime).Any())
|
||||
{
|
||||
new ForcePlayerRenameDialog(m).Send();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool HasNameChanged(PlayerMobile pm)
|
||||
{
|
||||
return pm != null && !pm.Deleted && pm.RawName != FindRegisteredName(pm);
|
||||
}
|
||||
|
||||
public static string FindRegisteredName(PlayerMobile pm)
|
||||
{
|
||||
if (pm == null || pm.Deleted)
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
var val = Registry.Values.IndexOf(list => list.Contains(pm));
|
||||
|
||||
if (Registry.InBounds(val))
|
||||
{
|
||||
return Registry.GetKeyAt(val);
|
||||
}
|
||||
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
public static IEnumerable<PlayerMobile> FindPlayers(string name)
|
||||
{
|
||||
return FindPlayers(name, null);
|
||||
}
|
||||
|
||||
public static IEnumerable<PlayerMobile> FindPlayers(string name, Func<PlayerMobile, bool> match)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
var players = Registry.GetValue(name);
|
||||
|
||||
if (players == null || players.Count == 0)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
foreach (var m in (match == null ? players : players.Where(match)))
|
||||
{
|
||||
yield return m;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
#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 Server;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
|
||||
using VitaNex.IO;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex
|
||||
{
|
||||
[CoreService("Player Name Register", "1.0.0.0", TaskPriority.Low)]
|
||||
public static partial class PlayerNames
|
||||
{
|
||||
static PlayerNames()
|
||||
{
|
||||
CSOptions = new PlayerNamesOptions();
|
||||
|
||||
Registry = new BinaryDataStore<string, List<PlayerMobile>>(VitaNexCore.SavesDirectory + "/PlayerNames", "Registry")
|
||||
{
|
||||
OnSerialize = Serialize,
|
||||
OnDeserialize = Deserialize,
|
||||
Async = true
|
||||
};
|
||||
}
|
||||
|
||||
private static void CSConfig()
|
||||
{
|
||||
EventSink.CharacterCreated += e => Register(e.Mobile as PlayerMobile);
|
||||
|
||||
EventSink.Login += e =>
|
||||
{
|
||||
Register(e.Mobile as PlayerMobile);
|
||||
ValidateSharedName(e.Mobile as PlayerMobile);
|
||||
};
|
||||
|
||||
EventSink.Logout += e => Register(e.Mobile as PlayerMobile);
|
||||
EventSink.PlayerDeath += e => Register(e.Mobile as PlayerMobile);
|
||||
|
||||
CommandUtility.Register(
|
||||
"PlayerNames",
|
||||
Access,
|
||||
e =>
|
||||
{
|
||||
if (e.Arguments != null && e.Arguments.Length > 0 && Insensitive.Equals(e.Arguments[0], "index"))
|
||||
{
|
||||
e.Mobile.SendMessage("Indexing player names, please wait...");
|
||||
|
||||
Index();
|
||||
|
||||
e.Mobile.SendMessage(
|
||||
"Player name indexing complete, there are {0:#,0} registered names by {1:#,0} players.",
|
||||
Registry.Count,
|
||||
Registry.Values.Aggregate(0, (c, list) => c + list.Count));
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Mobile.SendGump(new PropertiesGump(e.Mobile, CSOptions));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void Clear()
|
||||
{
|
||||
Registry.Clear();
|
||||
}
|
||||
|
||||
public static void Index()
|
||||
{
|
||||
CSOptions.ToConsole("Indexing...");
|
||||
World.Broadcast(0x55, true, "Indexing player names...");
|
||||
|
||||
World.Mobiles.Values.AsParallel().OfType<PlayerMobile>().ForEach(Register);
|
||||
|
||||
World.Broadcast(0x55, true, "Indexing complete.");
|
||||
CSOptions.ToConsole("Indexing complete.");
|
||||
|
||||
CSOptions.ToConsole(
|
||||
"{0:#,0} registered names by {1:#,0} players.",
|
||||
Registry.Count,
|
||||
Registry.Values.Aggregate(0, (c, list) => c + list.Count));
|
||||
}
|
||||
|
||||
private static void CSInvoke()
|
||||
{
|
||||
if (CSOptions.IndexOnStart)
|
||||
{
|
||||
Index();
|
||||
}
|
||||
}
|
||||
|
||||
private static void CSSave()
|
||||
{
|
||||
Registry.Export();
|
||||
}
|
||||
|
||||
private static void CSLoad()
|
||||
{
|
||||
Registry.Import();
|
||||
}
|
||||
|
||||
private static bool Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteBlockDictionary(
|
||||
Registry,
|
||||
(w, name, players) =>
|
||||
{
|
||||
w.Write(name);
|
||||
w.WriteMobileList(players, true);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool Deserialize(GenericReader reader)
|
||||
{
|
||||
reader.ReadBlockDictionary(
|
||||
r =>
|
||||
{
|
||||
var name = r.ReadString();
|
||||
var players = r.ReadStrongMobileList<PlayerMobile>();
|
||||
return new KeyValuePair<string, List<PlayerMobile>>(name, players);
|
||||
},
|
||||
Registry);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
#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 Server;
|
||||
using Server.Gumps;
|
||||
using Server.Misc;
|
||||
using Server.Mobiles;
|
||||
|
||||
using VitaNex.SuperGumps;
|
||||
using VitaNex.SuperGumps.UI;
|
||||
#endregion
|
||||
|
||||
namespace VitaNex
|
||||
{
|
||||
public class ForcePlayerRenameDialog : InputDialogGump
|
||||
{
|
||||
public ForcePlayerRenameDialog(Mobile user, string input = null)
|
||||
: base(user, input: input, limit: 16)
|
||||
{
|
||||
CanClose = false;
|
||||
CanDispose = false;
|
||||
|
||||
BlockMovement = true;
|
||||
BlockSpeech = true;
|
||||
|
||||
Html = "It appears that another character is already using the name \"" + //
|
||||
InputText.WrapUOHtmlColor(Color.LawnGreen, HtmlColor) + "\"!\n\n" + //
|
||||
"Please enter a new name for your character...";
|
||||
}
|
||||
|
||||
protected override void CompileLayout(SuperGumpLayout layout)
|
||||
{
|
||||
base.CompileLayout(layout);
|
||||
|
||||
layout.Remove("button/body/cancel");
|
||||
}
|
||||
|
||||
protected override void OnAccept(GumpButton button)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(InputText) || !NameVerification.Validate(
|
||||
InputText,
|
||||
2,
|
||||
20,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
1,
|
||||
NameVerification.SpaceDashPeriodQuote))
|
||||
{
|
||||
Html = ("The name \"" + InputText + "\" is invalid.\n\n").WrapUOHtmlColor(Color.OrangeRed, HtmlColor) +
|
||||
"It appears that another character is already using the name \"" + //
|
||||
User.RawName.WrapUOHtmlColor(Color.LawnGreen, HtmlColor) + "\"!\n\n" + //
|
||||
"Please enter a new name for your character...";
|
||||
|
||||
InputText = NameList.RandomName(User.Female ? "female" : "male");
|
||||
|
||||
Refresh(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (InputText == User.RawName || PlayerNames.FindPlayers(
|
||||
InputText,
|
||||
p => p != User && p.GameTime > ((PlayerMobile)User).GameTime)
|
||||
.Any())
|
||||
{
|
||||
Html = "It appears that another character is already using the name \"" + //
|
||||
InputText.WrapUOHtmlColor(Color.LawnGreen, HtmlColor) + "\"!\n\n" + //
|
||||
"Please enter a new name for your character...";
|
||||
|
||||
InputText = NameList.RandomName(User.Female ? "female" : "male");
|
||||
|
||||
Refresh(true);
|
||||
return;
|
||||
}
|
||||
|
||||
User.RawName = InputText;
|
||||
|
||||
PlayerNames.Register((PlayerMobile)User);
|
||||
|
||||
base.OnAccept(button);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user