Updates Packets & Randomizer (#43)
* Fixes a bug with the main loop. Removes unnecessary optimizations for RDRand. * WIP - Rewriting packets. * Cleanup and updates README * Converts more packets * Fixes header * Converts Effects packets. * Forgot the send command * Adds the start of containers packets. * Adds message packets with caching * Extends the send methods * Starts to add Acquire methods * Converted the packets * Cleanup * Cleanup * Adds more packets * Adds more packets * Fixes clearing arrays from pool. Adds Mobile Incoming * Converts more packets. * Moves more packets * Moves more packets * Test compression * Merges * Migrating to an idiomatic syntax that also supports compression, and proxying. * Optimize the stack alloc. Changes attributes * Converted container packets * Visual Studio doesn't auto save files. I am still getting used to subpar IDEs. * Adds static packet caching. Will profile later. Converts more packets * Fixes packets and changes how compression is configured * WIP - Adds basics for Gumps. Not finished though. * Fix file * Fixes formatting * Changed SpanWriter to be more idiomatic. * Fixes Span vs RawSpan and missing stackallocs * Converts over some more gumps * WIP - Deletes 32bit support. * Drops RDRand32 support. * Fixes gump compilation * Converting gump components * Removes old huffman compression function * Revert signature for backwards compatibility * WIP - Converting more gump components * Creates ArraySet for the strings. Updates AppendTo to reference that. * Converts the maining gump components * Cleans up gump components * Cleans up directives * Cleans up ArraySet and moves it. Adds null-coalescing-assignment * Cleanup, Target Packets, and C# 8 changes. * Removed OPL Packet * World packets * Fixing packet uses * Cleans up code. Fixes packet uses in various places. * More cleanup for packets * Code cleanup * Converts more packet uses and cleans up more code * More code cleanup * Finishes fixing the packets in Item * Updates secure trade packets * Updates core and gets it to compile. * Moved packets to scripts. Fixed account handler use of packets * Code cleanup * Updates chat packets * Code cleanuo * Adds party packets, but need to implement them. * Party packets WIP * Finishes party packets * Rearrange movement namespaces and classes * Finishes plant packets * Code Formatting * Fixes moving effects * Code cleanup, eliminates equipinfo * Adds more packets. Fixes bugs with various packets. * Finishes mahjon packets * Fixes mahjong packet * Code cleanup * Finishes mahjong packets * Adds Map packets * Add multifacet maps and charts * Cleans up some packets with UTF8 * Optimizes packets * Cleans up more packets. Moves the MessageHelper * Removes assistant support. Removes extended protocol. Incorporates MapUO packets as normal packets. * Updates protocol extensions packet receiver * Fixes a few bugs. Fixes a few more packets. * Code cleanup and fixing more packets * Fixes packet effects * Cleaned up more code * Buff Icon cleanup * Removed unused constructors * Code Cleanup. Adds BoatHS Packets * Moves house files. Updates house foundation packets. * Deployment cleanup * Fixes: * Code cleanup * More code cleanup * More code cleanup * Cleaned up BaseHouse * Enforces styling * Converts foreach to linq where possible. * Dont need that * Goals/Readme updates * Removes 32bit support at the highest level. Turns on HRT by default. * Code cleanup. Fixes extended features packet. * Fixes various bugs * Code cleanup * Code cleanup * Code cleanup. Fixes gump X/Y assignment. * Code cleanup using |= operator * More code cleanup * Cleanup * Fixes spacing issues. Thanks Visual Studio. You suck. * Compiler error * Fixes NPE from RunUO 2.7 * Renames ScriptCompiler to AssemblyHandler. Fixes packets. Updates README * Fixes more packets. Stupid trailing nulls. * Fixes various bugs. * Fixes for gumps * Fixes more gump stuff. Going to split it out later since it is getting insane * Recoded the gump writing * WIP * *Added output path of scripts project to dev branch *Activated debugging in code
This commit is contained in:
parent
7aa8fd3df1
commit
179cb50557
588 changed files with 10843 additions and 16177 deletions
|
|
@ -9,7 +9,7 @@ using Server.Spells.Seventh;
|
|||
|
||||
namespace Server
|
||||
{
|
||||
public class AOS
|
||||
public static class AOS
|
||||
{
|
||||
public static void DisableStatInfluences()
|
||||
{
|
||||
|
|
@ -1019,8 +1019,7 @@ namespace Server
|
|||
if (!GetValues(i, out SkillName skill, out double bonus))
|
||||
continue;
|
||||
|
||||
if (m_Mods == null)
|
||||
m_Mods = new List<SkillMod>();
|
||||
m_Mods ??= new List<SkillMod>();
|
||||
|
||||
SkillMod sk = new DefaultSkillMod(skill, true, bonus);
|
||||
sk.ObeyCap = true;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ using Server.Accounting;
|
|||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class AccountPrompt
|
||||
public static class AccountPrompt
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
|
|
@ -22,8 +22,7 @@ namespace Server.Misc
|
|||
Console.Write("Password: ");
|
||||
string password = Console.ReadLine();
|
||||
|
||||
Account a = new Account(username, password);
|
||||
a.AccessLevel = AccessLevel.Owner;
|
||||
Account a = new Account(username, password) {AccessLevel = AccessLevel.Owner};
|
||||
|
||||
Console.WriteLine("Account created.");
|
||||
}
|
||||
|
|
@ -36,4 +35,4 @@ namespace Server.Misc
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
namespace Server.Misc
|
||||
{
|
||||
public class Animations
|
||||
public static class Animations
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
|
|
@ -28,4 +28,4 @@ namespace Server.Misc
|
|||
from.Animate(action, 5, 1, true, false, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ using Server.Network;
|
|||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class AttackMessage
|
||||
public static class AttackMessage
|
||||
{
|
||||
private const string AggressorFormat = "You are attacking {0}!";
|
||||
private const string AggressedFormat = "{0} is attacking you!";
|
||||
|
|
@ -59,4 +59,4 @@ namespace Server.Misc
|
|||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ namespace Server.Misc
|
|||
string saves = Path.Combine(Core.BaseDirectory, "Saves");
|
||||
|
||||
if (Directory.Exists(saves))
|
||||
Directory.Move(saves, FormatDirectory(root, m_Backups[m_Backups.Length - 1], GetTimeStamp()));
|
||||
Directory.Move(saves, FormatDirectory(root, m_Backups[^1], GetTimeStamp()));
|
||||
}
|
||||
|
||||
private static DirectoryInfo Match(string[] paths, string match)
|
||||
|
|
@ -181,4 +181,4 @@ namespace Server.Misc
|
|||
return $"{now.Day}-{now.Month}-{now.Year} {now.Hour}-{now.Minute:D2}-{now.Second:D2}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
namespace Server.Misc
|
||||
{
|
||||
public class Broadcasts
|
||||
public static class Broadcasts
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using Server.Buffers;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
|
|
@ -18,13 +19,11 @@ namespace Server
|
|||
};
|
||||
}
|
||||
|
||||
#region Properties
|
||||
|
||||
public BuffIcon ID{ get; }
|
||||
|
||||
public int TitleCliloc{ get; }
|
||||
public int Title{ get; }
|
||||
|
||||
public int SecondaryCliloc{ get; }
|
||||
public TextDefinition Description{ get; }
|
||||
|
||||
public TimeSpan TimeLength{ get; }
|
||||
|
||||
|
|
@ -32,50 +31,30 @@ namespace Server
|
|||
|
||||
public Timer Timer{ get; }
|
||||
|
||||
public bool RetainThroughDeath{ get; }
|
||||
public bool RetainThroughDeath { get; }
|
||||
|
||||
public TextDefinition Args{ get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
public BuffInfo(BuffIcon iconID, int titleCliloc)
|
||||
: this(iconID, titleCliloc, titleCliloc + 1)
|
||||
public BuffInfo(BuffIcon iconId, int title, TimeSpan time = default, Mobile m = null) :
|
||||
this(iconId, title, title + 1, time, m)
|
||||
{
|
||||
}
|
||||
|
||||
public BuffInfo(BuffIcon iconID, int titleCliloc, int secondaryCliloc)
|
||||
{
|
||||
ID = iconID;
|
||||
TitleCliloc = titleCliloc;
|
||||
SecondaryCliloc = secondaryCliloc;
|
||||
}
|
||||
|
||||
public BuffInfo(BuffIcon iconID, int titleCliloc, TimeSpan length, Mobile m)
|
||||
: this(iconID, titleCliloc, titleCliloc + 1, length, m)
|
||||
public BuffInfo(BuffIcon iconId, int title, string args, TimeSpan time = default, Mobile m = null) :
|
||||
this(iconId, title, title + 1, args, time, m)
|
||||
{
|
||||
}
|
||||
|
||||
//Only the timed one needs to Mobile to know when to automagically remove it.
|
||||
public BuffInfo(BuffIcon iconID, int titleCliloc, int secondaryCliloc, TimeSpan length, Mobile m)
|
||||
: this(iconID, titleCliloc, secondaryCliloc)
|
||||
public BuffInfo(BuffIcon iconId, int title, int desc, TimeSpan time = default, Mobile m = null) :
|
||||
this(iconId, title, desc, null, time, m)
|
||||
{
|
||||
TimeLength = length;
|
||||
TimeStart = DateTime.UtcNow;
|
||||
|
||||
Timer = Timer.DelayCall(length, delegate
|
||||
{
|
||||
if (!(m is PlayerMobile pm))
|
||||
return;
|
||||
|
||||
pm.RemoveBuff(this);
|
||||
});
|
||||
}
|
||||
|
||||
public BuffInfo(BuffIcon iconId, int title, string args, bool retain, Mobile m = null) :
|
||||
this(iconId, title, title + 1, args, DateTime.UtcNow, default, retain, m)
|
||||
{
|
||||
}
|
||||
|
||||
public BuffInfo(BuffIcon iconID, int titleCliloc, TextDefinition args)
|
||||
: this(iconID, titleCliloc, titleCliloc + 1, args)
|
||||
public BuffInfo(BuffIcon iconId, int title, int desc, string args, TimeSpan time, Mobile m = null) :
|
||||
this(iconId, title, new TextDefinition(desc, args), DateTime.UtcNow, time, false, m)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -83,8 +62,8 @@ namespace Server
|
|||
: this(iconID, titleCliloc, secondaryCliloc) =>
|
||||
Args = args;
|
||||
|
||||
public BuffInfo(BuffIcon iconID, int titleCliloc, bool retainThroughDeath)
|
||||
: this(iconID, titleCliloc, titleCliloc + 1, retainThroughDeath)
|
||||
public BuffInfo(BuffIcon iconId, int title, int desc, string args, TimeSpan time = default, bool retain = false,
|
||||
Mobile m = null) : this(iconId, title, new TextDefinition(desc, args), DateTime.UtcNow, time, retain, m)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -92,9 +71,17 @@ namespace Server
|
|||
: this(iconID, titleCliloc, secondaryCliloc) =>
|
||||
RetainThroughDeath = retainThroughDeath;
|
||||
|
||||
public BuffInfo(BuffIcon iconID, int titleCliloc, TextDefinition args, bool retainThroughDeath)
|
||||
: this(iconID, titleCliloc, titleCliloc + 1, args, retainThroughDeath)
|
||||
public BuffInfo(BuffIcon iconId, int title, TextDefinition desc, DateTime start = default, TimeSpan time = default, bool retain = false,
|
||||
Mobile m = null)
|
||||
{
|
||||
ID = iconId;
|
||||
Title = title;
|
||||
Description = desc;
|
||||
TimeLength = time;
|
||||
TimeStart = start;
|
||||
RetainThroughDeath = retain;
|
||||
if (m is PlayerMobile pm)
|
||||
Timer = Timer.DelayCall(time, playermobile => playermobile.RemoveBuff(this), pm);
|
||||
}
|
||||
|
||||
public BuffInfo(BuffIcon iconID, int titleCliloc, int secondaryCliloc, TextDefinition args, bool retainThroughDeath)
|
||||
|
|
@ -131,20 +118,17 @@ namespace Server
|
|||
|
||||
public static void AddBuff(Mobile m, BuffInfo b)
|
||||
{
|
||||
if (m is PlayerMobile pm)
|
||||
pm.AddBuff(b);
|
||||
(m as PlayerMobile)?.AddBuff(b);
|
||||
}
|
||||
|
||||
public static void RemoveBuff(Mobile m, BuffInfo b)
|
||||
{
|
||||
if (m is PlayerMobile pm)
|
||||
pm.RemoveBuff(b);
|
||||
(m as PlayerMobile)?.RemoveBuff(b);
|
||||
}
|
||||
|
||||
public static void RemoveBuff(Mobile m, BuffIcon b)
|
||||
{
|
||||
if (m is PlayerMobile pm)
|
||||
pm.RemoveBuff(b);
|
||||
(m as PlayerMobile)?.RemoveBuff(b);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -208,80 +192,68 @@ namespace Server
|
|||
Fly
|
||||
}
|
||||
|
||||
public sealed class AddBuffPacket : Packet
|
||||
public static class BuffPackets
|
||||
{
|
||||
public AddBuffPacket(Mobile m, BuffInfo info)
|
||||
: this(m, info.ID, info.TitleCliloc, info.SecondaryCliloc, info.Args,
|
||||
info.TimeStart != DateTime.MinValue ? info.TimeStart + info.TimeLength - DateTime.UtcNow : TimeSpan.Zero)
|
||||
public static void SendAddBuff(Mobile m, BuffInfo info)
|
||||
{
|
||||
SendAddBuff(m.NetState, m.Serial, info.ID, info.Title, info.Description,
|
||||
info.TimeStart != DateTime.MinValue ? info.TimeStart + info.TimeLength - DateTime.UtcNow : TimeSpan.Zero);
|
||||
}
|
||||
public static void SendAddBuff(NetState ns, Serial m, BuffIcon iconID, int title, TextDefinition desc, TimeSpan time)
|
||||
{
|
||||
if (ns == null)
|
||||
return;
|
||||
|
||||
string args = desc?.String ?? "";
|
||||
|
||||
int length = 44 + args.Length * 2;
|
||||
|
||||
SpanWriter writer = new SpanWriter(stackalloc byte[length]);
|
||||
writer.Write((byte)0xDF); // Packet ID
|
||||
writer.Write((ushort)length); // Dynamic Length
|
||||
|
||||
writer.Write(m);
|
||||
|
||||
writer.Write((short)iconID); //ID
|
||||
writer.Write((short)0x1); //Type 0 for removal. 1 for add 2 for Data
|
||||
|
||||
writer.Position += 4;
|
||||
|
||||
writer.Write((short)iconID); //ID
|
||||
writer.Write((short)0x01); //Type 0 for removal. 1 for add 2 for Data
|
||||
|
||||
writer.Position += 4;
|
||||
|
||||
writer.Write((short)Math.Max(time.TotalSeconds, 0)); //Time in seconds
|
||||
|
||||
writer.Position += 3;
|
||||
|
||||
writer.Write(title);
|
||||
writer.Write(desc?.Number ?? 0);
|
||||
|
||||
writer.Position += 5;
|
||||
writer.Write((byte)0x1); // Start indicator?
|
||||
writer.Position += 2;
|
||||
|
||||
writer.WriteLittleUniNull(args);
|
||||
|
||||
ns.Send(writer.Span);
|
||||
}
|
||||
|
||||
public AddBuffPacket(Mobile mob, BuffIcon iconID, int titleCliloc, int secondaryCliloc, TextDefinition args,
|
||||
TimeSpan length)
|
||||
: base(0xDF)
|
||||
public static void SendRemoveBuffPacket(NetState ns, Serial m, int icon)
|
||||
{
|
||||
bool hasArgs = args != null;
|
||||
SpanWriter writer = new SpanWriter(stackalloc byte[13]);
|
||||
writer.Write((byte)0xDF); // Packet ID
|
||||
writer.Write((ushort)13); // Dynamic Length
|
||||
|
||||
EnsureCapacity(hasArgs ? 48 + args.ToString().Length * 2 : 44);
|
||||
m_Stream.Write(mob.Serial);
|
||||
writer.Write(m);
|
||||
|
||||
writer.Write((short)icon); //ID
|
||||
writer.Write((short)0x0); //Type 0 for removal. 1 for add 2 for Data
|
||||
|
||||
m_Stream.Write((short)iconID); //ID
|
||||
m_Stream.Write((short)0x1); //Type 0 for removal. 1 for add 2 for Data
|
||||
writer.Position += 4;
|
||||
|
||||
m_Stream.Fill(4);
|
||||
|
||||
m_Stream.Write((short)iconID); //ID
|
||||
m_Stream.Write((short)0x01); //Type 0 for removal. 1 for add 2 for Data
|
||||
|
||||
m_Stream.Fill(4);
|
||||
|
||||
if (length < TimeSpan.Zero)
|
||||
length = TimeSpan.Zero;
|
||||
|
||||
m_Stream.Write((short)length.TotalSeconds); //Time in seconds
|
||||
|
||||
m_Stream.Fill(3);
|
||||
m_Stream.Write(titleCliloc);
|
||||
m_Stream.Write(secondaryCliloc);
|
||||
|
||||
if (!hasArgs)
|
||||
{
|
||||
//m_Stream.Fill( 2 );
|
||||
m_Stream.Fill(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Stream.Fill(4);
|
||||
m_Stream.Write((short)0x1); //Unknown -> Possibly something saying 'hey, I have more data!'?
|
||||
m_Stream.Fill(2);
|
||||
|
||||
//m_Stream.WriteLittleUniNull( "\t#1018280" );
|
||||
m_Stream.WriteLittleUniNull($"\t{args}");
|
||||
|
||||
m_Stream.Write((short)0x1); //Even more Unknown -> Possibly something saying 'hey, I have more data!'?
|
||||
m_Stream.Fill(2);
|
||||
}
|
||||
ns.Send(writer.Span);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class RemoveBuffPacket : Packet
|
||||
{
|
||||
public RemoveBuffPacket(Mobile mob, BuffInfo info)
|
||||
: this(mob, info.ID)
|
||||
{
|
||||
}
|
||||
|
||||
public RemoveBuffPacket(Mobile mob, BuffIcon iconID)
|
||||
: base(0xDF)
|
||||
{
|
||||
EnsureCapacity(13);
|
||||
m_Stream.Write(mob.Serial);
|
||||
|
||||
m_Stream.Write((short)iconID); //ID
|
||||
m_Stream.Write((short)0x0); //Type 0 for removal. 1 for add 2 for Data
|
||||
|
||||
m_Stream.Fill(4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ using Server.Network;
|
|||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class CharacterCreation
|
||||
public static class CharacterCreation
|
||||
{
|
||||
private static readonly CityInfo m_NewHavenInfo =
|
||||
new CityInfo("New Haven", "The Bountiful Harvest Inn", 3503, 2574, 14, Map.Trammel);
|
||||
|
|
@ -22,15 +22,8 @@ namespace Server.Misc
|
|||
|
||||
private static void AddBackpack(Mobile m)
|
||||
{
|
||||
Container pack = m.Backpack;
|
||||
|
||||
if (pack == null)
|
||||
{
|
||||
pack = new Backpack();
|
||||
pack.Movable = false;
|
||||
|
||||
m.AddItem(pack);
|
||||
}
|
||||
if (m.Backpack == null)
|
||||
m.AddItem(new Backpack {Movable = false});
|
||||
|
||||
PackItem(new RedBook("a book", m.Name, 20, true));
|
||||
PackItem(new Gold(1000)); // Starting gold can be customized here
|
||||
|
|
@ -52,16 +45,8 @@ namespace Server.Misc
|
|||
item.Location = new Point3D(x, y, 0);
|
||||
}
|
||||
|
||||
private static Item MakePotionKeg(PotionEffect type, int hue)
|
||||
{
|
||||
PotionKeg keg = new PotionKeg();
|
||||
|
||||
keg.Held = 100;
|
||||
keg.Type = type;
|
||||
keg.Hue = hue;
|
||||
|
||||
return MakeNewbie(keg);
|
||||
}
|
||||
private static Item MakePotionKeg(PotionEffect type, int hue) =>
|
||||
MakeNewbie(new PotionKeg {Held = 100, Type = type, Hue = hue});
|
||||
|
||||
private static void FillBankAOS(Mobile m)
|
||||
{
|
||||
|
|
@ -75,11 +60,8 @@ namespace Server.Misc
|
|||
m.StatCap = 250;
|
||||
|
||||
|
||||
Container cont;
|
||||
|
||||
|
||||
// Begin box of money
|
||||
cont = new WoodenBox();
|
||||
Container cont = new WoodenBox();
|
||||
cont.ItemID = 0xE7D;
|
||||
cont.Hue = 0x489;
|
||||
|
||||
|
|
@ -97,8 +79,7 @@ namespace Server.Misc
|
|||
|
||||
|
||||
// Begin bag of potion kegs
|
||||
cont = new Backpack();
|
||||
cont.Name = "Various Potion Kegs";
|
||||
cont = new Backpack {Name = "Various Potion Kegs"};
|
||||
|
||||
PlaceItemIn(cont, 45, 149, MakePotionKeg(PotionEffect.CureGreater, 0x2D));
|
||||
PlaceItemIn(cont, 69, 149, MakePotionKeg(PotionEffect.HealGreater, 0x499));
|
||||
|
|
@ -113,8 +94,7 @@ namespace Server.Misc
|
|||
|
||||
|
||||
// Begin bag of tools
|
||||
cont = new Bag();
|
||||
cont.Name = "Tool Bag";
|
||||
cont = new Bag {Name = "Tool Bag"};
|
||||
|
||||
PlaceItemIn(cont, 30, 35, new TinkerTools(1000));
|
||||
PlaceItemIn(cont, 60, 35, new HousePlacementTool());
|
||||
|
|
@ -145,8 +125,7 @@ namespace Server.Misc
|
|||
|
||||
|
||||
// Begin bag of archery ammo
|
||||
cont = new Bag();
|
||||
cont.Name = "Bag Of Archery Ammo";
|
||||
cont = new Bag {Name = "Bag Of Archery Ammo"};
|
||||
|
||||
PlaceItemIn(cont, 48, 76, new Arrow(5000));
|
||||
PlaceItemIn(cont, 72, 76, new Bolt(5000));
|
||||
|
|
@ -156,8 +135,7 @@ namespace Server.Misc
|
|||
|
||||
|
||||
// Begin bag of treasure maps
|
||||
cont = new Bag();
|
||||
cont.Name = "Bag Of Treasure Maps";
|
||||
cont = new Bag {Name = "Bag Of Treasure Maps"};
|
||||
|
||||
PlaceItemIn(cont, 30, 35, new TreasureMap(1, Map.Trammel));
|
||||
PlaceItemIn(cont, 45, 35, new TreasureMap(2, Map.Trammel));
|
||||
|
|
@ -181,9 +159,7 @@ namespace Server.Misc
|
|||
|
||||
|
||||
// Begin bag of raw materials
|
||||
cont = new Bag();
|
||||
cont.Hue = 0x835;
|
||||
cont.Name = "Raw Materials Bag";
|
||||
cont = new Bag {Hue = 0x835, Name = "Raw Materials Bag"};
|
||||
|
||||
PlaceItemIn(cont, 92, 60, new BarbedLeather(5000));
|
||||
PlaceItemIn(cont, 92, 68, new HornedLeather(5000));
|
||||
|
|
@ -216,9 +192,7 @@ namespace Server.Misc
|
|||
|
||||
|
||||
// Begin bag of spell casting stuff
|
||||
cont = new Backpack();
|
||||
cont.Hue = 0x480;
|
||||
cont.Name = "Spell Casting Stuff";
|
||||
cont = new Backpack {Hue = 0x480, Name = "Spell Casting Stuff"};
|
||||
|
||||
PlaceItemIn(cont, 45, 105, new Spellbook(ulong.MaxValue));
|
||||
PlaceItemIn(cont, 65, 105, new NecromancerSpellbook((ulong)0xFFFF));
|
||||
|
|
@ -234,8 +208,7 @@ namespace Server.Misc
|
|||
toHue.Hue = 0x2D;
|
||||
PlaceItemIn(cont, 45, 150, toHue);
|
||||
|
||||
toHue = new BagOfNecroReagents(150);
|
||||
toHue.Hue = 0x488;
|
||||
toHue = new BagOfNecroReagents(150) {Hue = 0x488};
|
||||
PlaceItemIn(cont, 65, 150, toHue);
|
||||
|
||||
PlaceItemIn(cont, 140, 150, new BagOfAllReagents(500));
|
||||
|
|
@ -250,9 +223,7 @@ namespace Server.Misc
|
|||
|
||||
|
||||
// Begin bag of ethereals
|
||||
cont = new Backpack();
|
||||
cont.Hue = 0x490;
|
||||
cont.Name = "Bag Of Ethy's!";
|
||||
cont = new Backpack {Hue = 0x490, Name = "Bag Of Ethy's!"};
|
||||
|
||||
PlaceItemIn(cont, 45, 66, new EtherealHorse());
|
||||
PlaceItemIn(cont, 69, 82, new EtherealOstard());
|
||||
|
|
@ -268,9 +239,7 @@ namespace Server.Misc
|
|||
|
||||
|
||||
// Begin first bag of artifacts
|
||||
cont = new Backpack();
|
||||
cont.Hue = 0x48F;
|
||||
cont.Name = "Bag of Artifacts";
|
||||
cont = new Backpack {Hue = 0x48F, Name = "Bag of Artifacts"};
|
||||
|
||||
PlaceItemIn(cont, 45, 66, new TitansHammer());
|
||||
PlaceItemIn(cont, 69, 82, new InquisitorsResolution());
|
||||
|
|
@ -282,9 +251,7 @@ namespace Server.Misc
|
|||
|
||||
|
||||
// Begin second bag of artifacts
|
||||
cont = new Backpack();
|
||||
cont.Hue = 0x48F;
|
||||
cont.Name = "Bag of Artifacts";
|
||||
cont = new Backpack {Hue = 0x48F, Name = "Bag of Artifacts"};
|
||||
|
||||
PlaceItemIn(cont, 45, 66, new GauntletsOfNobility());
|
||||
PlaceItemIn(cont, 69, 82, new MidnightBracers());
|
||||
|
|
@ -324,10 +291,7 @@ namespace Server.Misc
|
|||
// End second bag of artifacts
|
||||
|
||||
// Begin bag of minor artifacts
|
||||
cont = new Backpack();
|
||||
cont.Hue = 0x48F;
|
||||
cont.Name = "Bag of Minor Artifacts";
|
||||
|
||||
cont = new Backpack {Hue = 0x48F, Name = "Bag of Minor Artifacts"};
|
||||
|
||||
PlaceItemIn(cont, 45, 66, new LunaLance());
|
||||
PlaceItemIn(cont, 69, 82, new VioletCourage());
|
||||
|
|
@ -368,9 +332,7 @@ namespace Server.Misc
|
|||
|
||||
if (Core.SE)
|
||||
{
|
||||
cont = new Bag();
|
||||
cont.Hue = 0x501;
|
||||
cont.Name = "Tokuno Minor Artifacts";
|
||||
cont = new Bag {Hue = 0x501, Name = "Tokuno Minor Artifacts"};
|
||||
|
||||
PlaceItemIn(cont, 42, 70, new Exiler());
|
||||
PlaceItemIn(cont, 38, 53, new HanzosBow());
|
||||
|
|
@ -398,8 +360,7 @@ namespace Server.Misc
|
|||
|
||||
if (Core.SE) //This bag came only after SE.
|
||||
{
|
||||
cont = new Bag();
|
||||
cont.Name = "Bag of Bows";
|
||||
cont = new Bag {Name = "Bag of Bows"};
|
||||
|
||||
PlaceItemIn(cont, 31, 84, new Bow());
|
||||
PlaceItemIn(cont, 78, 74, new CompositeBow());
|
||||
|
|
@ -432,11 +393,7 @@ namespace Server.Misc
|
|||
bank.DropItem(new BankCheck(1000000));
|
||||
|
||||
// Full spellbook
|
||||
Spellbook book = new Spellbook();
|
||||
|
||||
book.Content = ulong.MaxValue;
|
||||
|
||||
bank.DropItem(book);
|
||||
bank.DropItem(new Spellbook {Content = ulong.MaxValue});
|
||||
|
||||
Bag bag = new Bag();
|
||||
|
||||
|
|
@ -641,10 +598,7 @@ namespace Server.Misc
|
|||
newChar.Female = args.Female;
|
||||
//newChar.Body = newChar.Female ? 0x191 : 0x190;
|
||||
|
||||
if (Core.Expansion >= args.Race.RequiredExpansion)
|
||||
newChar.Race = args.Race; //Sets body
|
||||
else
|
||||
newChar.Race = Race.DefaultRace;
|
||||
newChar.Race = Core.Expansion >= args.Race.RequiredExpansion ? args.Race : Race.DefaultRace;
|
||||
|
||||
//newChar.Hue = Utility.ClipSkinHue( args.Hue & 0x3FFF ) | 0x8000;
|
||||
newChar.Hue = newChar.Race.ClipSkinHue(args.Hue & 0x3FFF) | 0x8000;
|
||||
|
|
@ -692,12 +646,7 @@ namespace Server.Misc
|
|||
if (TestCenter.Enabled)
|
||||
FillBankbox(newChar);
|
||||
|
||||
if (young)
|
||||
{
|
||||
NewPlayerTicket ticket = new NewPlayerTicket();
|
||||
ticket.Owner = newChar;
|
||||
newChar.BankBox.DropItem(ticket);
|
||||
}
|
||||
if (young) newChar.BankBox.DropItem(new NewPlayerTicket {Owner = newChar});
|
||||
|
||||
CityInfo city = GetStartLocation(args, young);
|
||||
|
||||
|
|
@ -710,19 +659,8 @@ namespace Server.Misc
|
|||
new WelcomeTimer(newChar).Start();
|
||||
}
|
||||
|
||||
public static bool VerifyProfession(int profession)
|
||||
{
|
||||
if (profession < 0)
|
||||
return false;
|
||||
if (profession < 4)
|
||||
return true;
|
||||
if (Core.AOS && profession < 6)
|
||||
return true;
|
||||
if (Core.SE && profession < 8)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
public static bool VerifyProfession(int profession) =>
|
||||
profession >= 0 && (profession < 4 || Core.AOS && profession < 6 || Core.SE && profession < 8);
|
||||
|
||||
private static CityInfo GetStartLocation(CharacterCreatedEventArgs args, bool isYoung)
|
||||
{
|
||||
|
|
@ -754,9 +692,7 @@ namespace Server.Misc
|
|||
break;
|
||||
}
|
||||
case 5: //Paladin
|
||||
{
|
||||
return m_NewHavenInfo;
|
||||
}
|
||||
case 6: //Samurai
|
||||
{
|
||||
if ((flags & ClientFlags.Tokuno) != 0)
|
||||
|
|
@ -795,10 +731,7 @@ namespace Server.Misc
|
|||
}
|
||||
}
|
||||
|
||||
if (useHaven)
|
||||
return m_NewHavenInfo;
|
||||
|
||||
return args.City;
|
||||
return useHaven ? m_NewHavenInfo : args.City;
|
||||
}
|
||||
|
||||
private static void FixStats(ref int str, ref int dex, ref int intel, int max)
|
||||
|
|
@ -1164,7 +1097,7 @@ namespace Server.Misc
|
|||
if (m_Mobile?.EquipItem(item) == true)
|
||||
return;
|
||||
|
||||
Container pack = m_Mobile.Backpack;
|
||||
Container pack = m_Mobile?.Backpack;
|
||||
|
||||
if (!mustEquip && pack != null)
|
||||
pack.DropItem(item);
|
||||
|
|
@ -1177,7 +1110,7 @@ namespace Server.Misc
|
|||
if (!Core.AOS)
|
||||
item.LootType = LootType.Newbied;
|
||||
|
||||
Container pack = m_Mobile.Backpack;
|
||||
Container pack = m_Mobile?.Backpack;
|
||||
|
||||
if (pack != null)
|
||||
pack.DropItem(item);
|
||||
|
|
@ -1733,18 +1666,18 @@ namespace Server.Misc
|
|||
private class BadStartMessage : Timer
|
||||
{
|
||||
private int m_Message;
|
||||
private Mobile m_Mobile;
|
||||
private Mobile m_From;
|
||||
|
||||
public BadStartMessage(Mobile m, int message) : base(TimeSpan.FromSeconds(3.5))
|
||||
{
|
||||
m_Mobile = m;
|
||||
m_From = m;
|
||||
m_Message = message;
|
||||
Start();
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(m_Message);
|
||||
m_From.SendLocalizedMessage(m_Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Multis;
|
||||
|
||||
namespace Server.Misc
|
||||
|
|
@ -43,9 +43,7 @@ namespace Server.Misc
|
|||
if (relEntity.Entity is Item item1)
|
||||
validItems.Add(item1);
|
||||
|
||||
foreach (VendorInventory inventory in house.VendorInventories)
|
||||
foreach (Item subItem in inventory.Items)
|
||||
validItems.Add(subItem);
|
||||
validItems.AddRange(house.VendorInventories.SelectMany(inventory => inventory.Items));
|
||||
}
|
||||
else if (item is BankBox box)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using Server.Accounting;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server
|
||||
|
|
@ -37,4 +37,4 @@ namespace Server
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -390,7 +390,7 @@ namespace Server
|
|||
|
||||
public static bool IsFrame(int id, int[] list)
|
||||
{
|
||||
if (id > list[list.Length - 1])
|
||||
if (id > list[^1])
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < list.Length; ++i)
|
||||
|
|
|
|||
|
|
@ -6,17 +6,17 @@ using System.Threading;
|
|||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class Email
|
||||
public static class Email
|
||||
{
|
||||
/* In order to support emailing, fill in EmailServer and FromAddress:
|
||||
* Example:
|
||||
* public static readonly string EmailServer = "mail.domain.com";
|
||||
* public static readonly string FromAddress = "runuo@domain.com";
|
||||
*
|
||||
*
|
||||
* If you want to add crash reporting emailing, fill in CrashAddresses:
|
||||
* Example:
|
||||
* public static readonly string CrashAddresses = "first@email.here,second@email.here,third@email.here";
|
||||
*
|
||||
*
|
||||
* If you want to add speech log page emailing, fill in SpeechLogPageAddresses:
|
||||
* Example:
|
||||
* public static readonly string SpeechLogPageAddresses = "first@email.here,second@email.here,third@email.here";
|
||||
|
|
@ -62,7 +62,7 @@ namespace Server.Misc
|
|||
// .NET relies on the MTA to generate Message-ID header. Not all MTAs will add this header.
|
||||
|
||||
DateTime now = DateTime.UtcNow;
|
||||
string messageID = $"<{now.ToString("yyyyMMdd")}.{now.ToString("HHmmssff")}@{EmailServer}>";
|
||||
string messageID = $"<{now:yyyyMMdd}.{now:HHmmssff}@{EmailServer}>";
|
||||
message.Headers.Add("Message-ID", messageID);
|
||||
|
||||
message.Headers.Add("X-Mailer", "RunUO");
|
||||
|
|
@ -89,10 +89,8 @@ namespace Server.Misc
|
|||
{
|
||||
MailMessage message = (MailMessage)state;
|
||||
|
||||
if (Send(message))
|
||||
Console.WriteLine("Sent e-mail '{0}' to '{1}'.", message.Subject, message.To);
|
||||
else
|
||||
Console.WriteLine("Failure sending e-mail '{0}' to '{1}'.", message.Subject, message.To);
|
||||
Console.WriteLine(Send(message) ? "Sent e-mail '{0}' to '{1}'." : "Failure sending e-mail '{0}' to '{1}'.",
|
||||
message.Subject, message.To);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ namespace Server.Misc
|
|||
{
|
||||
// This fastwalk detection is no longer required
|
||||
// As of B36 PlayerMobile implements movement packet throttling which more reliably controls movement speeds
|
||||
public class Fastwalk
|
||||
public static class Fastwalk
|
||||
{
|
||||
private static int MaxSteps = 4; // Maximum number of queued steps until fastwalk is detected
|
||||
private static bool Enabled = false; // Is fastwalk detection enabled?
|
||||
|
|
@ -30,4 +30,4 @@ namespace Server.Misc
|
|||
Console.WriteLine("Client: {0}: Fast movement detected (name={1})", e.NetState, e.NetState.Mobile.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,26 +19,19 @@ namespace Server.Misc
|
|||
|
||||
public static Point2D ArcPoint(Point3D loc, int radius, int angle)
|
||||
{
|
||||
int sideA, sideB;
|
||||
|
||||
if (angle < 0)
|
||||
angle = 0;
|
||||
|
||||
if (angle > 90)
|
||||
angle = 90;
|
||||
|
||||
sideA = (int)Math.Round(radius * Math.Sin(DegreesToRadians(angle)));
|
||||
sideB = (int)Math.Round(radius * Math.Cos(DegreesToRadians(angle)));
|
||||
int sideA = (int)Math.Round(radius * Math.Sin(DegreesToRadians(angle)));
|
||||
int sideB = (int)Math.Round(radius * Math.Cos(DegreesToRadians(angle)));
|
||||
|
||||
return new Point2D(loc.X - sideB, loc.Y - sideA);
|
||||
}
|
||||
|
||||
public static void Circle2D(Point3D loc, Map map, int radius, DoEffect_Callback effect)
|
||||
{
|
||||
Circle2D(loc, map, radius, effect, 0, 360);
|
||||
}
|
||||
|
||||
public static void Circle2D(Point3D loc, Map map, int radius, DoEffect_Callback effect, int angleStart, int angleEnd)
|
||||
public static void Circle2D(Point3D loc, Map map, int radius, DoEffect_Callback effect, int angleStart = 0, int angleEnd = 360)
|
||||
{
|
||||
if (angleStart < 0 || angleStart > 360)
|
||||
angleStart = 0;
|
||||
|
|
@ -147,13 +140,9 @@ namespace Server.Misc
|
|||
withinBounds = false;
|
||||
}
|
||||
else if (pointQuadrant == start.Quadrant && (x < startX || y > startY))
|
||||
{
|
||||
withinBounds = false;
|
||||
}
|
||||
else if (pointQuadrant == end.Quadrant && (x > endX || y < endY))
|
||||
{
|
||||
withinBounds = false;
|
||||
}
|
||||
|
||||
return opposite ? !withinBounds : withinBounds;
|
||||
}
|
||||
|
|
@ -218,4 +207,4 @@ namespace Server.Misc
|
|||
public int Quadrant{ get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,9 +129,7 @@ namespace Server.Items
|
|||
Effects.SendMovingEffect(from, targ, 0x36E4, 7, 0, false, true, 0x47F);
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1005574); // The snow is not ready to be packed yet. Keep trying.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -140,11 +138,9 @@ namespace Server.Items
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(
|
||||
1005577); // You can only throw a snowball at something that can throw one back.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ namespace Server.Guilds
|
|||
|
||||
public class RankDefinition
|
||||
{
|
||||
public static RankDefinition[] Ranks =
|
||||
public static readonly RankDefinition[] Ranks =
|
||||
{
|
||||
new RankDefinition(1062963, 0, RankFlags.None), //Ronin
|
||||
new RankDefinition(1062962, 1, RankFlags.Member), //Member
|
||||
|
|
@ -78,8 +78,8 @@ namespace Server.Guilds
|
|||
public class AllianceInfo
|
||||
{
|
||||
private Guild m_Leader;
|
||||
private List<Guild> m_Members;
|
||||
private List<Guild> m_PendingMembers;
|
||||
private readonly List<Guild> m_Members;
|
||||
private readonly List<Guild> m_PendingMembers;
|
||||
|
||||
public AllianceInfo(Guild leader, string name, Guild partner)
|
||||
{
|
||||
|
|
@ -154,21 +154,9 @@ namespace Server.Guilds
|
|||
}
|
||||
}
|
||||
|
||||
public bool IsPendingMember(Guild g)
|
||||
{
|
||||
if (g.Alliance != this)
|
||||
return false;
|
||||
public bool IsPendingMember(Guild g) => g.Alliance == this && m_PendingMembers.Contains(g);
|
||||
|
||||
return m_PendingMembers.Contains(g);
|
||||
}
|
||||
|
||||
public bool IsMember(Guild g)
|
||||
{
|
||||
if (g.Alliance != this)
|
||||
return false;
|
||||
|
||||
return m_Members.Contains(g);
|
||||
}
|
||||
public bool IsMember(Guild g) => g.Alliance == this && m_Members.Contains(g);
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
|
|
@ -332,29 +320,18 @@ namespace Server.Guilds
|
|||
|
||||
public void AllianceChat(Mobile from, int hue, string text)
|
||||
{
|
||||
Packet p = null;
|
||||
for (int i = 0; i < m_Members.Count; i++)
|
||||
{
|
||||
Guild g = m_Members[i];
|
||||
|
||||
for (int j = 0; j < g.Members.Count; j++)
|
||||
{
|
||||
Mobile m = g.Members[j];
|
||||
NetState ns = g.Members[j].NetState;
|
||||
|
||||
NetState state = m.NetState;
|
||||
|
||||
if (state != null)
|
||||
{
|
||||
if (p == null)
|
||||
p = Packet.Acquire(new UnicodeMessage(from.Serial, from.Body, MessageType.Alliance, hue, 3,
|
||||
from.Language, from.Name, text));
|
||||
|
||||
state.Send(p);
|
||||
}
|
||||
if (ns != null)
|
||||
Packets.SendUnicodeMessage(ns, from.Serial, from.Body, MessageType.Alliance, hue, 3, from.Language, from.Name, text);
|
||||
}
|
||||
}
|
||||
|
||||
Packet.Release(p);
|
||||
}
|
||||
|
||||
public void AllianceChat(Mobile from, string text)
|
||||
|
|
@ -683,9 +660,7 @@ namespace Server.Guilds
|
|||
Mobile from = e.Mobile;
|
||||
|
||||
if (arg.Length == 0)
|
||||
{
|
||||
e.Mobile.Target = new GuildPropsTarget();
|
||||
}
|
||||
else
|
||||
{
|
||||
Guild g = uint.TryParse(arg, out uint id)
|
||||
|
|
@ -720,7 +695,7 @@ namespace Server.Guilds
|
|||
|
||||
if (o is Guildstone stone)
|
||||
{
|
||||
if (stone?.Guild.Disbanded != false)
|
||||
if (stone.Guild.Disbanded)
|
||||
{
|
||||
from.SendMessage("The guild associated with that Guildstone no longer exists");
|
||||
return;
|
||||
|
|
@ -729,9 +704,7 @@ namespace Server.Guilds
|
|||
g = stone.Guild;
|
||||
}
|
||||
else if (o is Mobile mobile)
|
||||
{
|
||||
g = mobile.Guild as Guild;
|
||||
}
|
||||
|
||||
if (g == null)
|
||||
{
|
||||
|
|
@ -773,13 +746,7 @@ namespace Server.Guilds
|
|||
|
||||
public AllianceInfo Alliance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_AllianceInfo != null)
|
||||
return m_AllianceInfo;
|
||||
|
||||
return m_AllianceLeader?.m_AllianceInfo;
|
||||
}
|
||||
get => m_AllianceInfo ?? m_AllianceLeader?.m_AllianceInfo;
|
||||
set
|
||||
{
|
||||
AllianceInfo current = Alliance;
|
||||
|
|
@ -822,10 +789,7 @@ namespace Server.Guilds
|
|||
{
|
||||
AllianceInfo alliance = g.Alliance;
|
||||
|
||||
if (alliance?.Leader != null && alliance.IsMember(g))
|
||||
return alliance.Leader;
|
||||
|
||||
return g;
|
||||
return alliance?.Leader != null && alliance.IsMember(g) ? alliance.Leader : g;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -837,31 +801,9 @@ namespace Server.Guilds
|
|||
public List<WarDeclaration> AcceptedWars{ get; private set; }
|
||||
|
||||
|
||||
public WarDeclaration FindPendingWar(Guild g)
|
||||
{
|
||||
for (int i = 0; i < PendingWars.Count; i++)
|
||||
{
|
||||
WarDeclaration w = PendingWars[i];
|
||||
public WarDeclaration FindPendingWar(Guild g) => PendingWars.FirstOrDefault(w => w.Opponent == g);
|
||||
|
||||
if (w.Opponent == g)
|
||||
return w;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public WarDeclaration FindActiveWar(Guild g)
|
||||
{
|
||||
for (int i = 0; i < AcceptedWars.Count; i++)
|
||||
{
|
||||
WarDeclaration w = AcceptedWars[i];
|
||||
|
||||
if (w.Opponent == g)
|
||||
return w;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
public WarDeclaration FindActiveWar(Guild g) => AcceptedWars.FirstOrDefault(w => w.Opponent == g);
|
||||
|
||||
public void CheckExpiredWars()
|
||||
{
|
||||
|
|
@ -936,8 +878,7 @@ namespace Server.Guilds
|
|||
if (!NewGuildSystem)
|
||||
return;
|
||||
|
||||
if (killer == null)
|
||||
killer = victim.FindMostRecentDamager(false);
|
||||
killer ??= victim.FindMostRecentDamager(false);
|
||||
|
||||
if (killer == null || victim.Guild == null || killer.Guild == null)
|
||||
return;
|
||||
|
|
@ -1148,24 +1089,10 @@ namespace Server.Guilds
|
|||
}
|
||||
}
|
||||
|
||||
if (AllyDeclarations == null)
|
||||
AllyDeclarations = new List<Guild>();
|
||||
|
||||
if (AllyInvitations == null)
|
||||
AllyInvitations = new List<Guild>();
|
||||
|
||||
|
||||
if (AcceptedWars == null)
|
||||
AcceptedWars = new List<WarDeclaration>();
|
||||
|
||||
if (PendingWars == null)
|
||||
PendingWars = new List<WarDeclaration>();
|
||||
|
||||
|
||||
/*
|
||||
if ( ( !NewGuildSystem && m_Guildstone == null )|| m_Members.Count == 0 )
|
||||
Disband();
|
||||
*/
|
||||
AllyDeclarations ??= new List<Guild>();
|
||||
AllyInvitations ??= new List<Guild>();
|
||||
AcceptedWars ??= new List<WarDeclaration>();
|
||||
PendingWars ??= new List<WarDeclaration>();
|
||||
|
||||
Timer.DelayCall(TimeSpan.Zero, VerifyGuild_Callback);
|
||||
}
|
||||
|
|
@ -1334,24 +1261,14 @@ namespace Server.Guilds
|
|||
|
||||
public void GuildChat(Mobile from, int hue, string text)
|
||||
{
|
||||
Packet p = null;
|
||||
for (int i = 0; i < Members.Count; i++)
|
||||
{
|
||||
Mobile m = Members[i];
|
||||
NetState ns = Members[i].NetState;
|
||||
|
||||
NetState state = m.NetState;
|
||||
|
||||
if (state != null)
|
||||
{
|
||||
if (p == null)
|
||||
p = Packet.Acquire(new UnicodeMessage(from.Serial, from.Body, MessageType.Guild, hue, 3,
|
||||
from.Language, from.Name, text));
|
||||
|
||||
state.Send(p);
|
||||
}
|
||||
if (ns != null)
|
||||
Packets.SendUnicodeMessage(ns, from.Serial, from.Body, MessageType.Guild, hue, 3,
|
||||
from.Language, from.Name, text);
|
||||
}
|
||||
|
||||
Packet.Release(p);
|
||||
}
|
||||
|
||||
public void GuildChat(Mobile from, string text)
|
||||
|
|
@ -1402,17 +1319,12 @@ namespace Server.Guilds
|
|||
Mobile winner = null;
|
||||
int highVotes = 0;
|
||||
|
||||
foreach (KeyValuePair<Mobile, int> kvp in votes)
|
||||
{
|
||||
Mobile m = kvp.Key;
|
||||
int val = kvp.Value;
|
||||
|
||||
foreach ((Mobile m, int val) in votes)
|
||||
if (winner == null || val > highVotes)
|
||||
{
|
||||
winner = m;
|
||||
highVotes = val;
|
||||
}
|
||||
}
|
||||
|
||||
if (NewGuildSystem && highVotes * 100 / Math.Max(votingMembers, 1) < MajorityPercentage && !Disbanded &&
|
||||
winner != m_Leader && m_Leader.Guild == this)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ using Server.Mobiles;
|
|||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class Keywords
|
||||
public static class Keywords
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
|
|
@ -51,4 +51,4 @@ namespace Server.Misc
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ namespace Server.Misc
|
|||
* enable showing of unicode control chars
|
||||
**/
|
||||
|
||||
public class LanguageStatistics
|
||||
public static class LanguageStatistics
|
||||
{
|
||||
private static InternationalCode[] InternationalCodes =
|
||||
{
|
||||
|
|
@ -317,13 +317,10 @@ namespace Server.Misc
|
|||
|
||||
public int Compare(InternationalCodeCounter x, InternationalCodeCounter y)
|
||||
{
|
||||
string a = null, b = null;
|
||||
int ca = 0, cb = 0;
|
||||
|
||||
a = x.Code;
|
||||
ca = x.Count;
|
||||
b = y.Code;
|
||||
cb = y.Count;
|
||||
string a = x?.Code;
|
||||
int ca = x?.Count ?? 0;
|
||||
string b = y?.Code;
|
||||
int cb = y?.Count ?? 0;
|
||||
|
||||
|
||||
if (ca > cb)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ using Server.Network;
|
|||
|
||||
namespace Server
|
||||
{
|
||||
public class LightCycle
|
||||
public static class LightCycle
|
||||
{
|
||||
public const int DayLevel = 0;
|
||||
public const int NightLevel = 12;
|
||||
|
|
@ -69,12 +69,12 @@ namespace Server
|
|||
Clock.GetTime(from.Map, from.X, from.Y, out int hours, out int minutes);
|
||||
|
||||
/* OSI times:
|
||||
*
|
||||
*
|
||||
* Midnight -> 3:59 AM : Night
|
||||
* 4:00 AM -> 11:59 PM : Day
|
||||
*
|
||||
*
|
||||
* RunUO times:
|
||||
*
|
||||
*
|
||||
* 10:00 PM -> 11:59 PM : Scale to night
|
||||
* Midnight -> 3:59 AM : Night
|
||||
* 4:00 AM -> 5:59 AM : Scale to day
|
||||
|
|
@ -124,10 +124,10 @@ namespace Server
|
|||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Owner.EndAction<LightCycle>();
|
||||
m_Owner.EndAction<NightSightTimer>();
|
||||
m_Owner.LightLevel = 0;
|
||||
BuffInfo.RemoveBuff(m_Owner, BuffIcon.NightSight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ using Server.Network;
|
|||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class LoginStats
|
||||
public static class LoginStats
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
|
|
@ -27,4 +27,4 @@ namespace Server.Misc
|
|||
mobileCount, mobileCount == 1 ? "" : "s");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,16 @@
|
|||
namespace Server.Misc
|
||||
{
|
||||
public class MapDefinitions
|
||||
public static class MapDefinitions
|
||||
{
|
||||
public static void Configure()
|
||||
{
|
||||
/* Here we configure all maps. Some notes:
|
||||
*
|
||||
*
|
||||
* 1) The first 32 maps are reserved for core use.
|
||||
* 2) Map 0x7F is reserved for core use.
|
||||
* 3) Map 0xFF is reserved for core use.
|
||||
* 4) Changing or removing any predefined maps may cause server instability.
|
||||
*/
|
||||
|
||||
RegisterMap(0, 0, 0, 7168, 4096, 4, "Felucca", MapRules.FeluccaRules);
|
||||
RegisterMap(1, 1, 1, 7168, 4096, 0, "Trammel", MapRules.TrammelRules);
|
||||
RegisterMap(2, 2, 2, 2304, 1600, 1, "Ilshenar", MapRules.TrammelRules);
|
||||
|
|
@ -23,7 +22,7 @@ namespace Server.Misc
|
|||
|
||||
/* Example of registering a custom map:
|
||||
* RegisterMap( 32, 0, 0, 6144, 4096, 3, "Iceland", MapRules.FeluccaRules );
|
||||
*
|
||||
*
|
||||
* Defined:
|
||||
* RegisterMap( <index>, <mapID>, <fileIndex>, <width>, <height>, <season>, <name>, <rules> );
|
||||
* - <index> : An unreserved unique index for this map
|
||||
|
|
@ -40,7 +39,7 @@ namespace Server.Misc
|
|||
MultiComponentList.PostHSFormat = true; // OSI Client Patch 7.0.9.0
|
||||
}
|
||||
|
||||
public static void RegisterMap(int mapIndex, int mapID, int fileIndex, int width, int height, int season,
|
||||
public static void RegisterMap(int mapIndex, int mapID, int fileIndex, int width, int height, byte season,
|
||||
string name, MapRules rules)
|
||||
{
|
||||
Map newMap = new Map(mapID, mapIndex, fileIndex, width, height, season, name, rules);
|
||||
|
|
@ -49,4 +48,4 @@ namespace Server.Misc
|
|||
Map.AllMaps.Add(newMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using Server.Buffers;
|
||||
using Server.Engines.PartySystem;
|
||||
using Server.Guilds;
|
||||
using Server.Network;
|
||||
|
|
@ -18,35 +19,12 @@ namespace Server.Misc
|
|||
|
||||
private static void OnPartyTrack(NetState state, PacketReader pvSrc)
|
||||
{
|
||||
Mobile from = state.Mobile;
|
||||
Party party = Party.Get(from);
|
||||
|
||||
if (party != null)
|
||||
{
|
||||
Packets.PartyTrack packet = new Packets.PartyTrack(from, party);
|
||||
|
||||
if (packet.UnderlyingStream.Length > 8)
|
||||
state.Send(packet);
|
||||
}
|
||||
MapUOPackets.SendPartyTrack(state, Party.Get(state.Mobile));
|
||||
}
|
||||
|
||||
private static void OnGuildTrack(NetState state, PacketReader pvSrc)
|
||||
{
|
||||
Mobile from = state.Mobile;
|
||||
|
||||
if (from.Guild is Guild guild)
|
||||
{
|
||||
bool locations = pvSrc.ReadByte() != 0;
|
||||
|
||||
Packets.GuildTrack packet = new Packets.GuildTrack(from, guild, locations);
|
||||
|
||||
if (packet.UnderlyingStream.Length > (locations ? 9 : 5))
|
||||
state.Send(packet);
|
||||
}
|
||||
else
|
||||
{
|
||||
state.Send(new Packets.GuildTrack());
|
||||
}
|
||||
MapUOPackets.SendGuildTrack(state, state.Mobile.Guild as Guild, pvSrc.ReadBoolean());
|
||||
}
|
||||
|
||||
private static class Settings
|
||||
|
|
@ -56,75 +34,97 @@ namespace Server.Misc
|
|||
public const bool GuildHitsPercent = true;
|
||||
}
|
||||
|
||||
private static class Packets
|
||||
private static class MapUOPackets
|
||||
{
|
||||
public sealed class PartyTrack : ProtocolExtension
|
||||
public static void SendPartyTrack(NetState ns, Party party)
|
||||
{
|
||||
public PartyTrack(Mobile from, Party party) : base(0x01, (party.Members.Count - 1) * 9 + 4)
|
||||
Mobile from = ns.Mobile;
|
||||
int count = party?.Members.Count ?? 0;
|
||||
if (count < 2)
|
||||
return;
|
||||
|
||||
SpanWriter writer = new SpanWriter(stackalloc byte[Math.Max(count - 1, 0) * 9 + 8]);
|
||||
writer.Write((byte)0xF0); // Packet ID
|
||||
writer.Position += 2; // Dynamic Length
|
||||
|
||||
writer.Write((byte)0x01); // Command
|
||||
|
||||
count = 0;
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
for (int i = 0; i < party.Members.Count; ++i)
|
||||
{
|
||||
PartyMemberInfo pmi = party.Members[i];
|
||||
Mobile mob = party.Members[i]?.Mobile; // if count is greater than 0, then party is not null
|
||||
|
||||
if (pmi == null || pmi.Mobile == from)
|
||||
continue;
|
||||
if (mob == from || mob?.NetState == null || Utility.InUpdateRange(from, mob) && from.CanSee(mob))
|
||||
continue;
|
||||
|
||||
Mobile mob = pmi.Mobile;
|
||||
|
||||
if (Utility.InUpdateRange(from, mob) && from.CanSee(mob))
|
||||
continue;
|
||||
|
||||
m_Stream.Write(mob.Serial);
|
||||
m_Stream.Write((short)mob.X);
|
||||
m_Stream.Write((short)mob.Y);
|
||||
m_Stream.Write((byte)(mob.Map?.MapID ?? 0));
|
||||
}
|
||||
|
||||
m_Stream.Write(0);
|
||||
count++;
|
||||
writer.Write(mob.Serial);
|
||||
writer.Write((short)mob.X);
|
||||
writer.Write((short)mob.Y);
|
||||
writer.Write((byte)(mob.Map?.MapID ?? 0));
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
writer.Position += 4; // Empty Serial
|
||||
writer.Position = 1;
|
||||
writer.Write((ushort)writer.WrittenCount);
|
||||
|
||||
ns.Send(writer.Span);
|
||||
}
|
||||
|
||||
public sealed class GuildTrack : ProtocolExtension
|
||||
public static void SendGuildTrack(NetState ns, Guild guild = null, bool locations = false)
|
||||
{
|
||||
public GuildTrack() : base(0x02, 5)
|
||||
{
|
||||
m_Stream.Write((byte)0);
|
||||
m_Stream.Write(0);
|
||||
}
|
||||
Mobile from = ns.Mobile;
|
||||
|
||||
public GuildTrack(Mobile from, Guild guild, bool locations) : base(0x02,
|
||||
(guild.Members.Count - 1) * (locations ? 10 : 4) + 5)
|
||||
{
|
||||
m_Stream.Write((byte)(locations ? 1 : 0));
|
||||
int count = guild?.Members.Count ?? 0;
|
||||
|
||||
for (int i = 0; i < guild.Members.Count; ++i)
|
||||
if (count < 2)
|
||||
return;
|
||||
|
||||
SpanWriter writer = new SpanWriter(stackalloc byte[Math.Max(count - 1, 0) * (locations ? 10 : 4) + 9]);
|
||||
writer.Write((byte)0xF0); // Packet ID
|
||||
writer.Position += 2; // Dynamic Length
|
||||
|
||||
writer.Write((byte)0x02); // Command
|
||||
|
||||
writer.Write(locations);
|
||||
|
||||
count = 0;
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
Mobile mob = guild.Members[i]; // If guild count is above 0, then guild is not null.
|
||||
|
||||
if (mob == from || mob?.NetState == null || locations && Utility.InUpdateRange(from, mob) && from.CanSee(mob))
|
||||
continue;
|
||||
|
||||
count++;
|
||||
writer.Write(mob.Serial);
|
||||
|
||||
if (locations)
|
||||
{
|
||||
Mobile mob = guild.Members[i];
|
||||
writer.Write((short)mob.X);
|
||||
writer.Write((short)mob.Y);
|
||||
writer.Write((byte)(mob.Map?.MapID ?? 0));
|
||||
|
||||
if (mob == null || mob == from || mob.NetState == null)
|
||||
continue;
|
||||
|
||||
if (locations && Utility.InUpdateRange(from, mob) && from.CanSee(mob))
|
||||
continue;
|
||||
|
||||
m_Stream.Write(mob.Serial);
|
||||
|
||||
if (locations)
|
||||
{
|
||||
m_Stream.Write((short)mob.X);
|
||||
m_Stream.Write((short)mob.Y);
|
||||
m_Stream.Write((byte)(mob.Map?.MapID ?? 0));
|
||||
|
||||
if (Settings.GuildHitsPercent && mob.Alive)
|
||||
m_Stream.Write((byte)(mob.Hits / Math.Max(mob.HitsMax, 1.0) * 100));
|
||||
else
|
||||
m_Stream.Write((byte)0);
|
||||
}
|
||||
if (Settings.GuildHitsPercent && mob.Alive)
|
||||
writer.Write((byte)(mob.Hits / Math.Max(mob.HitsMax, 1.0) * 100));
|
||||
else
|
||||
writer.Position++; // writer.Write((byte)0);
|
||||
}
|
||||
|
||||
m_Stream.Write(0);
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
writer.Position += 4; // Empty Serial
|
||||
|
||||
writer.Position = 1;
|
||||
writer.Write((ushort)writer.WrittenCount);
|
||||
|
||||
ns.Send(writer.Span);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
22
Projects/Scripts/Misc/MessageHelper.cs
Normal file
22
Projects/Scripts/Misc/MessageHelper.cs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
using Server.Network;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public static class MessageHelper
|
||||
{
|
||||
public static void SendLocalizedMessageTo(Item from, Mobile to, int number, int hue)
|
||||
{
|
||||
SendLocalizedMessageTo(from, to, number, "", hue);
|
||||
}
|
||||
|
||||
public static void SendLocalizedMessageTo(Item from, Mobile to, int number, string args, int hue)
|
||||
{
|
||||
Packets.SendMessageLocalized(to.NetState, from.Serial, from.ItemID, MessageType.Regular, hue, 3, number, "", args);
|
||||
}
|
||||
|
||||
public static void SendMessageTo(Item from, Mobile to, string text, int hue)
|
||||
{
|
||||
Packets.SendUnicodeMessage(to.NetState, from.Serial, from.ItemID, MessageType.Regular, hue, 3, "ENU", "", text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
|
||||
namespace Server
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
namespace Server.Misc
|
||||
{
|
||||
public class NameVerification
|
||||
public static class NameVerification
|
||||
{
|
||||
public static readonly char[] SpaceDashPeriodQuote =
|
||||
{
|
||||
|
|
@ -148,20 +148,9 @@ namespace Server.Misc
|
|||
|
||||
exceptCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool except = false;
|
||||
|
||||
for (int j = 0; !except && j < exceptions.Length; ++j)
|
||||
if (c == exceptions[j])
|
||||
except = true;
|
||||
|
||||
if (!except || i == 0 && noExceptionsAtStart)
|
||||
return false;
|
||||
|
||||
if (exceptCount++ == maxExceptions)
|
||||
return false;
|
||||
}
|
||||
else if (exceptCount++ == maxExceptions || exceptions.All(exception => exception != c) ||
|
||||
i == 0 && noExceptionsAtStart)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < disallowed.Length; ++i)
|
||||
|
|
@ -188,11 +177,7 @@ namespace Server.Misc
|
|||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < startDisallowed.Length; ++i)
|
||||
if (name.StartsWith(startDisallowed[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
return startDisallowed.All(t => !name.StartsWith(t));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Server.Engines.ConPVP;
|
||||
using Server.Engines.PartySystem;
|
||||
using Server.Factions;
|
||||
|
|
@ -12,7 +13,7 @@ using Server.Spells.Seventh;
|
|||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class NotorietyHandlers
|
||||
public static class NotorietyHandlers
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
|
|
@ -306,7 +307,7 @@ namespace Server.Misc
|
|||
}
|
||||
|
||||
/* Must be thread-safe */
|
||||
public static int MobileNotoriety(Mobile source, Mobile target)
|
||||
public static byte MobileNotoriety(Mobile source, Mobile target)
|
||||
{
|
||||
BaseCreature bcTarg = target as BaseCreature;
|
||||
|
||||
|
|
@ -429,27 +430,12 @@ namespace Server.Misc
|
|||
|
||||
public static bool IsSummoned(BaseCreature c) => c?.Summoned == true;
|
||||
|
||||
public static bool CheckAggressor(List<AggressorInfo> list, Mobile target)
|
||||
{
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
if (list[i].Attacker == target)
|
||||
return true;
|
||||
public static bool IsSummoned(BaseCreature c) => c?.Summoned == true;
|
||||
|
||||
return false;
|
||||
}
|
||||
public static bool CheckAggressor(IEnumerable<AggressorInfo> list, Mobile target) => list.Any(t => t.Attacker == target);
|
||||
|
||||
public static bool CheckAggressed(List<AggressorInfo> list, Mobile target)
|
||||
{
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
{
|
||||
AggressorInfo info = list[i];
|
||||
|
||||
if (!info.CriminalAggression && info.Defender == target)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
public static bool CheckAggressed(IEnumerable<AggressorInfo> list, Mobile target) =>
|
||||
list.Any(info => !info.CriminalAggression && info.Defender == target);
|
||||
|
||||
private enum GuildStatus
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ using Server.Network;
|
|||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class Paperdoll
|
||||
public static class Paperdoll
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
|
|
@ -13,21 +13,22 @@ namespace Server.Misc
|
|||
public static void EventSink_PaperdollRequest(PaperdollRequestEventArgs e)
|
||||
{
|
||||
Mobile beholder = e.Beholder;
|
||||
NetState ns = beholder.NetState;
|
||||
Mobile beheld = e.Beheld;
|
||||
|
||||
beholder.Send(new DisplayPaperdoll(beheld, Titles.ComputeTitle(beholder, beheld),
|
||||
beheld.AllowEquipFrom(beholder)));
|
||||
Packets.SendDisplayPaperdoll(ns, beholder, Titles.ComputeTitle(beholder, beheld),
|
||||
beheld.AllowEquipFrom(beholder));
|
||||
|
||||
if (ObjectPropertyList.Enabled)
|
||||
{
|
||||
List<Item> items = beheld.Items;
|
||||
|
||||
for (int i = 0; i < items.Count; ++i)
|
||||
beholder.Send(items[i].OPLPacket);
|
||||
items[i].PropertyList.SendOPLInfo(ns);
|
||||
|
||||
// NOTE: OSI sends MobileUpdate when opening your own paperdoll.
|
||||
// It has a very bad rubber-banding affect. What positive affects does it have?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,10 +99,7 @@ namespace Server.Misc
|
|||
return false;
|
||||
}
|
||||
default:
|
||||
case ProfanityAction.Other: // TODO: Provide custom implementation if this is chosen
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -118,4 +115,4 @@ namespace Server.Misc
|
|||
e.Blocked = !OnProfanityDetected(from, e.Speech);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ using Server.Network;
|
|||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class Profile
|
||||
public static class Profile
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
|
|
@ -48,12 +48,9 @@ namespace Server.Misc
|
|||
if (footer.Length == 0 && beholder == beheld)
|
||||
footer = GetAccountDuration(beheld);
|
||||
|
||||
string body = beheld.Profile;
|
||||
string body = beheld.Profile ?? "";
|
||||
|
||||
if (body == null || body.Length <= 0)
|
||||
body = "";
|
||||
|
||||
beholder.Send(new DisplayProfile(beholder != beheld || !beheld.ProfileLocked, beheld, header, body, footer));
|
||||
Packets.SendDisplayProfile(beholder.NetState, beholder != beheld || !beheld.ProfileLocked ? beheld.Serial : Serial.Zero, header, body, footer);
|
||||
}
|
||||
|
||||
private static string GetAccountDuration(Mobile m)
|
||||
|
|
@ -72,10 +69,7 @@ namespace Server.Misc
|
|||
if (Format(ts.TotalMinutes, "This account is {0} minute{1} old.", out v))
|
||||
return v;
|
||||
|
||||
if (Format(ts.TotalSeconds, "This account is {0} second{1} old.", out v))
|
||||
return v;
|
||||
|
||||
return "";
|
||||
return Format(ts.TotalSeconds, "This account is {0} second{1} old.", out v) ? v : "";
|
||||
}
|
||||
|
||||
public static bool Format(double value, string format, out string op)
|
||||
|
|
@ -90,4 +84,4 @@ namespace Server.Misc
|
|||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ using Server.Network;
|
|||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class ProtocolExtensions
|
||||
public static class ProtocolExtensions
|
||||
{
|
||||
private static PacketHandler[] m_Handlers = new PacketHandler[0x100];
|
||||
private static readonly PacketHandler[] m_Handlers = new PacketHandler[0x100];
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
|
|
@ -17,48 +17,34 @@ namespace Server.Misc
|
|||
m_Handlers[packetID] = new PacketHandler(packetID, 0, ingame, onReceive);
|
||||
}
|
||||
|
||||
public static PacketHandler GetHandler(int packetID)
|
||||
{
|
||||
if (packetID >= 0 && packetID < m_Handlers.Length)
|
||||
return m_Handlers[packetID];
|
||||
|
||||
return null;
|
||||
}
|
||||
public static PacketHandler GetHandler(int packetID) => packetID >= 0 && packetID < m_Handlers.Length ? m_Handlers[packetID] : null;
|
||||
|
||||
public static void DecodeBundledPacket(NetState state, PacketReader pvSrc)
|
||||
{
|
||||
int packetID = pvSrc.ReadByte();
|
||||
|
||||
PacketHandler ph = GetHandler(packetID);
|
||||
if (ph == null)
|
||||
return;
|
||||
|
||||
if (ph != null)
|
||||
if (ph.Ingame)
|
||||
{
|
||||
if (ph.Ingame && state.Mobile == null)
|
||||
if (state.Mobile == null)
|
||||
{
|
||||
Console.WriteLine(
|
||||
"Client: {0}: Sent ingame packet (0xF0x{1:X2}) before having been attached to a mobile", state,
|
||||
packetID);
|
||||
"Client: {0}: Sent ingame packet (0xF0x{1:X2}) before having been attached to a mobile", state, packetID);
|
||||
state.Dispose();
|
||||
return;
|
||||
}
|
||||
else if (ph.Ingame && state.Mobile.Deleted)
|
||||
|
||||
if (state.Mobile.Deleted)
|
||||
{
|
||||
state.Dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
ph.OnReceive(state, pvSrc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ph.OnReceive(state, pvSrc);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class ProtocolExtension : Packet
|
||||
{
|
||||
public ProtocolExtension(int packetID, int capacity) : base(0xF0)
|
||||
{
|
||||
EnsureCapacity(4 + capacity);
|
||||
|
||||
m_Stream.Write((byte)packetID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
using System.Linq;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class RaceDefinitions
|
||||
|
|
@ -30,22 +32,9 @@ namespace Server.Misc
|
|||
{
|
||||
}
|
||||
|
||||
public override bool ValidateHair(bool female, int itemID)
|
||||
{
|
||||
if (itemID == 0)
|
||||
return true;
|
||||
|
||||
if (female && itemID == 0x2048 || !female && itemID == 0x2046)
|
||||
return false; //Buns & Receding Hair
|
||||
|
||||
if (itemID >= 0x203B && itemID <= 0x203D)
|
||||
return true;
|
||||
|
||||
if (itemID >= 0x2044 && itemID <= 0x204A)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
public override bool ValidateHair(bool female, int itemID) =>
|
||||
itemID == 0 || (!female || itemID != 0x2048) && (female || itemID != 0x2046) &&
|
||||
(itemID >= 0x203B && itemID <= 0x203D || itemID >= 0x2044 && itemID <= 0x204A);
|
||||
|
||||
public override int RandomHair(bool female) //Random hair doesn't include baldness
|
||||
{
|
||||
|
|
@ -90,32 +79,18 @@ namespace Server.Misc
|
|||
return (rand < 4 ? 0x203E : 0x2047) + rand;
|
||||
}
|
||||
|
||||
public override int ClipSkinHue(int hue)
|
||||
{
|
||||
if (hue < 1002)
|
||||
return 1002;
|
||||
if (hue > 1058)
|
||||
return 1058;
|
||||
return hue;
|
||||
}
|
||||
public override int ClipSkinHue(int hue) => hue < 1002 ? 1002 : hue > 1058 ? 1058 : hue;
|
||||
|
||||
public override int RandomSkinHue() => Utility.Random(1002, 57) | 0x8000;
|
||||
|
||||
public override int ClipHairHue(int hue)
|
||||
{
|
||||
if (hue < 1102)
|
||||
return 1102;
|
||||
if (hue > 1149)
|
||||
return 1149;
|
||||
return hue;
|
||||
}
|
||||
public override int ClipHairHue(int hue) => hue < 1102 ? 1102 : hue > 1149 ? 1149 : hue;
|
||||
|
||||
public override int RandomHairHue() => Utility.Random(1102, 48);
|
||||
}
|
||||
|
||||
private class Elf : Race
|
||||
{
|
||||
private static int[] m_SkinHues =
|
||||
private static readonly int[] m_SkinHues =
|
||||
{
|
||||
0x0BF, 0x24D, 0x24E, 0x24F, 0x353, 0x361, 0x367, 0x374,
|
||||
0x375, 0x376, 0x381, 0x382, 0x383, 0x384, 0x385, 0x389,
|
||||
|
|
@ -123,7 +98,7 @@ namespace Server.Misc
|
|||
0x51D, 0x53F, 0x579, 0x76B, 0x76C, 0x76D, 0x835, 0x903
|
||||
};
|
||||
|
||||
private static int[] m_HairHues =
|
||||
private static readonly int[] m_HairHues =
|
||||
{
|
||||
0x034, 0x035, 0x036, 0x037, 0x038, 0x039, 0x058, 0x08E,
|
||||
0x08F, 0x090, 0x091, 0x092, 0x101, 0x159, 0x15A, 0x15B,
|
||||
|
|
@ -139,10 +114,10 @@ namespace Server.Misc
|
|||
{
|
||||
}
|
||||
|
||||
public override bool ValidateHair(bool female, int itemID)
|
||||
{
|
||||
if (itemID == 0)
|
||||
return true;
|
||||
public override bool ValidateHair(bool female, int itemID) =>
|
||||
itemID == 0 || (!female || itemID != 0x2FCD && itemID != 0x2FBF) &&
|
||||
(female || itemID != 0x2FCC && itemID != 0x2FD0) &&
|
||||
(itemID >= 0x2FBF && itemID <= 0x2FC2 || itemID >= 0x2FCC && itemID <= 0x2FD1);
|
||||
|
||||
if (female && (itemID == 0x2FCD || itemID == 0x2FBF) || !female && (itemID == 0x2FCC || itemID == 0x2FD0))
|
||||
return false;
|
||||
|
|
@ -186,14 +161,9 @@ namespace Server.Misc
|
|||
|
||||
public override int RandomSkinHue() => m_SkinHues[Utility.Random(m_SkinHues.Length)] | 0x8000;
|
||||
|
||||
public override int ClipHairHue(int hue)
|
||||
{
|
||||
for (int i = 0; i < m_HairHues.Length; i++)
|
||||
if (m_HairHues[i] == hue)
|
||||
return hue;
|
||||
public override int RandomSkinHue() => m_SkinHues[Utility.Random(m_SkinHues.Length)] | 0x8000;
|
||||
|
||||
return m_HairHues[0];
|
||||
}
|
||||
public override int ClipHairHue(int hue) => m_HairHues.Any(t => t == hue) ? hue : m_HairHues[0];
|
||||
|
||||
public override int RandomHairHue() => m_HairHues[Utility.Random(m_HairHues.Length)];
|
||||
}
|
||||
|
|
@ -225,13 +195,11 @@ namespace Server.Misc
|
|||
{
|
||||
}
|
||||
|
||||
public override bool ValidateHair(bool female, int itemID)
|
||||
{
|
||||
if (female == false) return itemID >= 0x4258 && itemID <= 0x425F;
|
||||
|
||||
return itemID == 0x4261 || itemID == 0x4262 || itemID >= 0x4273 && itemID <= 0x4275 || itemID == 0x42B0 ||
|
||||
itemID == 0x42B1 || itemID == 0x42AA || itemID == 0x42AB;
|
||||
}
|
||||
public override bool ValidateHair(bool female, int itemID) =>
|
||||
female == false
|
||||
? itemID >= 0x4258 && itemID <= 0x425F
|
||||
: itemID == 0x4261 || itemID == 0x4262 || itemID >= 0x4273 && itemID <= 0x4275 || itemID == 0x42B0 ||
|
||||
itemID == 0x42B1 || itemID == 0x42AA || itemID == 0x42AB;
|
||||
|
||||
public override int RandomHair(bool female)
|
||||
{
|
||||
|
|
@ -262,14 +230,9 @@ namespace Server.Misc
|
|||
|
||||
public override int RandomSkinHue() => m_BodyHues[Utility.Random(m_BodyHues.Length)] | 0x8000;
|
||||
|
||||
public override int ClipHairHue(int hue)
|
||||
{
|
||||
for (int i = 0; i < m_HornHues.Length; i++)
|
||||
if (m_HornHues[i] == hue)
|
||||
return hue;
|
||||
public override int RandomSkinHue() => m_BodyHues[Utility.Random(m_BodyHues.Length)] | 0x8000;
|
||||
|
||||
return m_HornHues[0];
|
||||
}
|
||||
public override int ClipHairHue(int hue) => m_HornHues.Any(t => t == hue) ? hue : m_HornHues[0];
|
||||
|
||||
public override int RandomHairHue() => m_HornHues[Utility.Random(m_HornHues.Length)];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
|
|
@ -9,18 +10,18 @@ namespace Server.Misc
|
|||
{
|
||||
public class ServerList
|
||||
{
|
||||
/*
|
||||
/*
|
||||
* The default setting for Address, a value of 'null', will use your local IP address. If all of your local IP addresses
|
||||
* are private network addresses and AutoDetect is 'true' then RunUO will attempt to discover your public IP address
|
||||
* for you automatically.
|
||||
*
|
||||
* If you do not plan on allowing clients outside of your LAN to connect, you can set AutoDetect to 'false' and leave
|
||||
* Address set to 'null'.
|
||||
*
|
||||
*
|
||||
* If your public IP address cannot be determined, you must change the value of Address to your public IP address
|
||||
* manually to allow clients outside of your LAN to connect to your server. Address can be either an IP address or
|
||||
* a hostname that will be resolved when RunUO starts.
|
||||
*
|
||||
*
|
||||
* If you want players outside your LAN to be able to connect to your server and you are behind a router, you must also
|
||||
* forward TCP port 2593 to your private IP address. The procedure for doing this varies by manufacturer but generally
|
||||
* involves configuration of the router through your web browser.
|
||||
|
|
@ -32,7 +33,7 @@ namespace Server.Misc
|
|||
* properly and fully supports listening on multiple ports. If a client with a public IP address is connecting to a
|
||||
* locally private address, the server will direct the client to either the AutoDetected IP address or the manually entered
|
||||
* IP address or hostname, whichever is applicable. Loopback clients will be directed to loopback.
|
||||
*
|
||||
*
|
||||
* If you would like to listen on additional ports (i.e. 22, 23, 80, for clients behind highly restrictive egress
|
||||
* firewalls) or specific IP adddresses you can do so by modifying the file SocketOptions.cs found in this directory.
|
||||
*/
|
||||
|
|
@ -111,7 +112,7 @@ namespace Server.Misc
|
|||
IPHostEntry iphe = Dns.GetHostEntry(addr);
|
||||
|
||||
if (iphe.AddressList.Length > 0)
|
||||
outValue = iphe.AddressList[iphe.AddressList.Length - 1];
|
||||
outValue = iphe.AddressList[^1];
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
@ -119,65 +120,23 @@ namespace Server.Misc
|
|||
}
|
||||
}
|
||||
|
||||
private static bool HasPublicIPAddress()
|
||||
{
|
||||
NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
|
||||
private static bool HasPublicIPAddress() =>
|
||||
NetworkInterface.GetAllNetworkInterfaces().Select(adapter => adapter.GetIPProperties())
|
||||
.Any(properties => properties.UnicastAddresses.Select(unicast => unicast.Address)
|
||||
.Any(ip => !IPAddress.IsLoopback(ip) && ip.AddressFamily != AddressFamily.InterNetworkV6 && !IsPrivateNetwork(ip)));
|
||||
|
||||
foreach (NetworkInterface adapter in adapters)
|
||||
{
|
||||
IPInterfaceProperties properties = adapter.GetIPProperties();
|
||||
|
||||
foreach (IPAddressInformation unicast in properties.UnicastAddresses)
|
||||
{
|
||||
IPAddress ip = unicast.Address;
|
||||
|
||||
if (!IPAddress.IsLoopback(ip) && ip.AddressFamily != AddressFamily.InterNetworkV6 &&
|
||||
!IsPrivateNetwork(ip))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
|
||||
/*
|
||||
IPHostEntry iphe = Dns.GetHostEntry( Dns.GetHostName() );
|
||||
|
||||
IPAddress[] ips = iphe.AddressList;
|
||||
|
||||
for ( int i = 0; i < ips.Length; ++i )
|
||||
{
|
||||
if ( ips[i].AddressFamily != AddressFamily.InterNetworkV6 && !IsPrivateNetwork( ips[i] ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
*/
|
||||
}
|
||||
|
||||
private static bool IsPrivateNetwork(IPAddress ip)
|
||||
{
|
||||
// 10.0.0.0/8
|
||||
// 172.16.0.0/12
|
||||
// 192.168.0.0/16
|
||||
// 169.254.0.0/16
|
||||
// 100.64.0.0/10 RFC 6598
|
||||
|
||||
if (ip.AddressFamily == AddressFamily.InterNetworkV6)
|
||||
return false;
|
||||
|
||||
if (Utility.IPMatch("192.168.*", ip))
|
||||
return true;
|
||||
if (Utility.IPMatch("10.*", ip))
|
||||
return true;
|
||||
if (Utility.IPMatch("172.16-31.*", ip))
|
||||
return true;
|
||||
if (Utility.IPMatch("169.254.*", ip))
|
||||
return true;
|
||||
if (Utility.IPMatch("100.64-127.*", ip))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
// 10.0.0.0/8
|
||||
// 172.16.0.0/12
|
||||
// 192.168.0.0/16
|
||||
// 169.254.0.0/16
|
||||
// 100.64.0.0/10 RFC 6598
|
||||
private static bool IsPrivateNetwork(IPAddress ip) =>
|
||||
ip.AddressFamily != AddressFamily.InterNetworkV6 &&
|
||||
(Utility.IPMatch("192.168.*", ip) ||
|
||||
Utility.IPMatch("10.*", ip) ||
|
||||
Utility.IPMatch("172.16-31.*", ip) ||
|
||||
Utility.IPMatch("169.254.*", ip) ||
|
||||
Utility.IPMatch("100.64-127.*", ip));
|
||||
|
||||
private static IPAddress FindPublicAddress()
|
||||
{
|
||||
|
|
@ -193,7 +152,7 @@ namespace Server.Misc
|
|||
|
||||
StreamReader sr = new StreamReader(s);
|
||||
|
||||
IPAddress ip = IPAddress.Parse(sr.ReadLine());
|
||||
IPAddress ip = IPAddress.Parse(sr.ReadLine() ?? "");
|
||||
|
||||
sr.Close();
|
||||
s.Close();
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ using System.Net;
|
|||
using System.Text.RegularExpressions;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
using Server.Prompts;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
|
|
@ -465,9 +464,7 @@ namespace Server.Misc
|
|||
|
||||
public void QueuePoll(ShardPoller poller)
|
||||
{
|
||||
if (m_Polls == null)
|
||||
m_Polls = new Queue<ShardPoller>(4);
|
||||
|
||||
m_Polls ??= new Queue<ShardPoller>(4);
|
||||
m_Polls.Enqueue(poller);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ namespace Server.Misc
|
|||
|
||||
Skills skills = from.Skills;
|
||||
|
||||
if (from.Player && skills.Total / skills.Cap >= Utility.RandomDouble()) //( skills.Total >= skills.Cap )
|
||||
if (from.Player && skills.Total / (double)skills.Cap >= Utility.RandomDouble()) //( skills.Total >= skills.Cap )
|
||||
for (int i = 0; i < skills.Length; ++i)
|
||||
{
|
||||
Skill toLower = skills[i];
|
||||
|
|
|
|||
|
|
@ -373,8 +373,7 @@ namespace Server.Misc
|
|||
{
|
||||
int fp = Math.Min(skill.BaseFixedPoint, 1200);
|
||||
|
||||
return (fp - 300) / 100;
|
||||
}
|
||||
private static int GetTableIndex(Skill skill) => (Math.Min(skill.BaseFixedPoint, 1200) - 300) / 100;
|
||||
}
|
||||
|
||||
public class FameEntry
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Server
|
|||
public static void Initialize()
|
||||
{
|
||||
string filePath = Path.Combine(Core.BaseDirectory, "Data/treasure.cfg");
|
||||
int i = 0, x = 0, y = 0;
|
||||
int i = 0;
|
||||
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
|
|
@ -69,4 +69,4 @@ namespace Server
|
|||
m.SendMessage("You have left a protected treasure map area.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -347,8 +347,6 @@ namespace Server
|
|||
|
||||
private static bool CanFit(Map map, int x, int y, int z)
|
||||
{
|
||||
bool hasSurface = false;
|
||||
|
||||
LandTile lt = map.Tiles.GetLandTile(x, y);
|
||||
int lowZ = 0, avgZ = 0, topZ = 0;
|
||||
|
||||
|
|
@ -357,8 +355,8 @@ namespace Server
|
|||
|
||||
if ((landFlags & TileFlag.Impassable) != 0 && topZ > z && z + 16 > lowZ)
|
||||
return false;
|
||||
if ((landFlags & TileFlag.Impassable) == 0 && z == avgZ && !lt.Ignored)
|
||||
hasSurface = true;
|
||||
|
||||
bool hasSurface = (landFlags & TileFlag.Impassable) == 0 && z == avgZ && !lt.Ignored;
|
||||
|
||||
StaticTile[] staticTiles = map.Tiles.GetStaticTiles(x, y);
|
||||
|
||||
|
|
@ -376,8 +374,8 @@ namespace Server
|
|||
|
||||
if ((surface || impassable) && staticTiles[i].Z + id.CalcHeight > z && z + 16 > staticTiles[i].Z)
|
||||
return false;
|
||||
if (surface && !impassable && z == staticTiles[i].Z + id.CalcHeight)
|
||||
hasSurface = true;
|
||||
|
||||
hasSurface |= surface && !impassable && z == staticTiles[i].Z + id.CalcHeight;
|
||||
}
|
||||
|
||||
Sector sector = map.GetSector(x, y);
|
||||
|
|
@ -395,8 +393,8 @@ namespace Server
|
|||
|
||||
if ((surface || impassable) && item.Z + id.CalcHeight > z && z + 16 > item.Z)
|
||||
return false;
|
||||
if (surface && !impassable && z == item.Z + id.CalcHeight)
|
||||
hasSurface = true;
|
||||
|
||||
hasSurface |= surface && !impassable && z == item.Z + id.CalcHeight;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -413,9 +411,9 @@ namespace Server
|
|||
floor.Add(p);
|
||||
|
||||
for (int xo = -1; xo <= 1; ++xo)
|
||||
for (int yo = -1; yo <= 1; ++yo)
|
||||
if ((xo != 0 || yo != 0) && IsFloor(map, x + xo, y + yo, false))
|
||||
RecurseFindFloor(map, x + xo, y + yo, floor);
|
||||
for (int yo = -1; yo <= 1; ++yo)
|
||||
if ((xo != 0 || yo != 0) && IsFloor(map, x + xo, y + yo, false))
|
||||
RecurseFindFloor(map, x + xo, y + yo, floor);
|
||||
}
|
||||
|
||||
[Flags]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
|
||||
|
|
|
|||
|
|
@ -23,21 +23,12 @@ namespace Server.Misc
|
|||
|
||||
public static void FatigueOnDamage(Mobile m, int damage)
|
||||
{
|
||||
double fatigue = 0.0;
|
||||
|
||||
switch (DFA)
|
||||
double fatigue = DFA switch
|
||||
{
|
||||
case DFAlgorithm.Standard:
|
||||
{
|
||||
fatigue = damage * (100.0 / m.Hits) * ((double)m.Stam / 100) - 5.0;
|
||||
break;
|
||||
}
|
||||
case DFAlgorithm.PainSpike:
|
||||
{
|
||||
fatigue = damage * (100.0 / m.Hits + (50.0 + m.Stam) / 100 - 1.0) - 5.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
DFAlgorithm.Standard => damage * (100.0 / m.Hits) * ((double)m.Stam / 100) - 5.0,
|
||||
DFAlgorithm.PainSpike => damage * (100.0 / m.Hits + (50.0 + m.Stam) / 100 - 1.0) - 5.0,
|
||||
_ => 0.0,
|
||||
};
|
||||
|
||||
if (fatigue > 0)
|
||||
m.Stam -= (int)fatigue;
|
||||
|
|
@ -117,4 +108,4 @@ namespace Server.Misc
|
|||
return Mobile.BodyWeight + m.TotalWeight > GetMaxWeight(m) + OverloadAllowance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue