Updates code to C# 7, fixes various issues, and styling [PR #1]

This commit is contained in:
Kamron Batman 2018-09-16 21:35:57 -07:00 • committed by GitHub
commit 445eddff68
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3349 changed files with 442574 additions and 463352 deletions

View file

@ -1,10 +0,0 @@
# http://editorconfig.org
root=true
[*]
indent_style = tab
tab_width = 4
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

View file

@ -1,46 +1,46 @@
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using Server;
using Server.Misc;
namespace Server
{
public class AccessRestrictions
{
public static void Initialize()
{
EventSink.SocketConnect += new SocketConnectEventHandler( EventSink_SocketConnect );
}
private static void EventSink_SocketConnect( SocketConnectEventArgs e )
{
try
{
IPAddress ip = ((IPEndPoint)e.Socket.RemoteEndPoint).Address;
public class AccessRestrictions
{
public static void Initialize()
{
EventSink.SocketConnect += EventSink_SocketConnect;
}
if ( Firewall.IsBlocked( ip ) )
{
Console.WriteLine( "Client: {0}: Firewall blocked connection attempt.", ip );
e.AllowConnection = false;
return;
}
else if ( IPLimiter.SocketBlock && !IPLimiter.Verify( ip ) )
{
Console.WriteLine( "Client: {0}: Past IP limit threshold", ip );
private static void EventSink_SocketConnect(SocketConnectEventArgs e)
{
try
{
IPAddress ip = ((IPEndPoint)e.Socket.RemoteEndPoint).Address;
using ( StreamWriter op = new StreamWriter( "ipLimits.log", true ) )
op.WriteLine( "{0}\tPast IP limit threshold\t{1}", ip, DateTime.UtcNow );
e.AllowConnection = false;
return;
}
}
catch
{
e.AllowConnection = false;
}
}
}
if (Firewall.IsBlocked(ip))
{
Console.WriteLine("Client: {0}: Firewall blocked connection attempt.", ip);
e.AllowConnection = false;
return;
}
if (IPLimiter.SocketBlock && !IPLimiter.Verify(ip))
{
Console.WriteLine("Client: {0}: Past IP limit threshold", ip);
using (StreamWriter op = new StreamWriter("ipLimits.log", true))
{
op.WriteLine("{0}\tPast IP limit threshold\t{1}", ip, DateTime.UtcNow);
}
e.AllowConnection = false;
}
}
catch
{
e.AllowConnection = false;
}
}
}
}

View file

@ -1,15 +1,9 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
using Server;
using Server.Commands;
using Server.Items;
using Server.Misc;
using Server.Mobiles;
using Server.Multis;
@ -25,24 +19,18 @@ namespace Server.Accounting
public static readonly TimeSpan EmptyInactiveDuration = TimeSpan.FromDays(30.0);
private string m_Username, m_Email, m_PlainPassword, m_CryptPassword, m_NewCryptPassword;
private AccessLevel m_AccessLevel;
private int m_Flags;
private DateTime m_Created, m_LastLogin;
private TimeSpan m_TotalGameTime;
private List<AccountComment> m_Comments;
private List<AccountTag> m_Tags;
private Mobile[] m_Mobiles;
private string[] m_IPRestrictions;
private IPAddress[] m_LoginIPs;
private HardwareInfo m_HardwareInfo;
/// <summary>
/// Deletes the account, all characters of the account, and all houses of those characters
/// </summary>
public void Delete()
{
for ( int i = 0; i < this.Length; ++i )
for ( int i = 0; i < Length; ++i )
{
Mobile m = this[i];
@ -60,38 +48,26 @@ namespace Server.Accounting
m_Mobiles[i] = null;
}
if ( m_LoginIPs.Length != 0 && AccountHandler.IPTable.ContainsKey( m_LoginIPs[0] ) )
--AccountHandler.IPTable[m_LoginIPs[0]];
if ( LoginIPs.Length != 0 && AccountHandler.IPTable.ContainsKey( LoginIPs[0] ) )
--AccountHandler.IPTable[LoginIPs[0]];
Accounts.Remove( m_Username );
Accounts.Remove( Username );
}
/// <summary>
/// Object detailing information about the hardware of the last person to log into this account
/// </summary>
public HardwareInfo HardwareInfo
{
get { return m_HardwareInfo; }
set { m_HardwareInfo = value; }
}
public HardwareInfo HardwareInfo { get; set; }
/// <summary>
/// List of IP addresses for restricted access. '*' wildcard supported. If the array contains zero entries, all IP addresses are allowed.
/// </summary>
public string[] IPRestrictions
{
get { return m_IPRestrictions; }
set { m_IPRestrictions = value; }
}
public string[] IPRestrictions { get; set; }
/// <summary>
/// List of IP addresses which have successfully logged into this account.
/// </summary>
public IPAddress[] LoginIPs
{
get { return m_LoginIPs; }
set { m_LoginIPs = value; }
}
public IPAddress[] LoginIPs { get; set; }
/// <summary>
/// List of account comments. Type of contained objects is AccountComment.
@ -112,65 +88,41 @@ namespace Server.Accounting
/// <summary>
/// Account username. Case insensitive validation.
/// </summary>
public string Username
{
get { return m_Username; }
set { m_Username = value; }
}
public string Username { get; set; }
/// <summary>
/// Account email address.
/// </summary>
public string Email
{
get { return m_Email; }
set { m_Email = value; }
}
public string Email { get; set; }
/// <summary>
/// Account password. Plain text. Case sensitive validation. May be null.
/// </summary>
public string PlainPassword
{
get { return m_PlainPassword; }
set { m_PlainPassword = value; }
}
public string PlainPassword { get; set; }
/// <summary>
/// Account password. Hashed with MD5. May be null.
/// </summary>
public string CryptPassword
{
get { return m_CryptPassword; }
set { m_CryptPassword = value; }
}
public string CryptPassword { get; set; }
/// <summary>
/// Account username and password hashed with SHA1. May be null.
/// </summary>
public string NewCryptPassword
{
get { return m_NewCryptPassword; }
set { m_NewCryptPassword = value; }
}
public string NewCryptPassword { get; set; }
/// <summary>
/// Initial AccessLevel for new characters created on this account.
/// </summary>
public AccessLevel AccessLevel
{
get { return m_AccessLevel; }
set { m_AccessLevel = value; }
get => m_AccessLevel;
set => m_AccessLevel = value;
}
/// <summary>
/// Internal bitfield of account flags. Consider using direct access properties (Banned, Young), or GetFlag/SetFlag methods
/// </summary>
public int Flags
{
get { return m_Flags; }
set { m_Flags = value; }
}
public int Flags { get; set; }
/// <summary>
/// Gets or sets a flag indicating if this account is banned.
@ -199,7 +151,7 @@ namespace Server.Accounting
return true;
}
set { SetFlag( 0, value ); }
set => SetFlag( 0, value );
}
/// <summary>
@ -207,7 +159,7 @@ namespace Server.Accounting
/// </summary>
public bool Young
{
get { return !GetFlag( 1 ); }
get => !GetFlag( 1 );
set
{
SetFlag( 1, !value );
@ -223,33 +175,26 @@ namespace Server.Accounting
/// <summary>
/// The date and time of when this account was created.
/// </summary>
public DateTime Created
{
get { return m_Created; }
}
public DateTime Created { get; }
/// <summary>
/// Gets or sets the date and time when this account was last accessed.
/// </summary>
public DateTime LastLogin
{
get { return m_LastLogin; }
set { m_LastLogin = value; }
}
public DateTime LastLogin { get; set; }
/// <summary>
/// An account is considered inactive based upon LastLogin and InactiveDuration. If the account is empty, it is based upon EmptyInactiveDuration
/// </summary>
public bool Inactive
{
get
get
{
if( this.AccessLevel != AccessLevel.Player )
if ( AccessLevel != AccessLevel.Player )
return false;
TimeSpan inactiveLength = DateTime.UtcNow - m_LastLogin;
TimeSpan inactiveLength = DateTime.UtcNow - LastLogin;
return (inactiveLength > ((this.Count == 0) ? EmptyInactiveDuration : InactiveDuration));
return (inactiveLength > ((Count == 0) ? EmptyInactiveDuration : InactiveDuration));
}
}
@ -263,9 +208,7 @@ namespace Server.Accounting
{
for ( int i = 0; i < m_Mobiles.Length; i++ )
{
PlayerMobile m = m_Mobiles[i] as PlayerMobile;
if ( m != null && m.NetState != null )
if ( m_Mobiles[i] is PlayerMobile m && m.NetState != null )
return m_TotalGameTime + ( DateTime.UtcNow - m.SessionStart );
}
@ -279,7 +222,7 @@ namespace Server.Accounting
/// <param name="index">The zero-based flag index.</param>
public bool GetFlag( int index )
{
return ( m_Flags & ( 1 << index ) ) != 0;
return ( Flags & ( 1 << index ) ) != 0;
}
/// <summary>
@ -290,9 +233,9 @@ namespace Server.Accounting
public void SetFlag( int index, bool value )
{
if ( value )
m_Flags |= ( 1 << index );
Flags |= ( 1 << index );
else
m_Flags &= ~( 1 << index );
Flags &= ~( 1 << index );
}
/// <summary>
@ -448,25 +391,25 @@ namespace Server.Accounting
{
case PasswordProtection.None:
{
m_PlainPassword = plainPassword;
m_CryptPassword = null;
m_NewCryptPassword = null;
PlainPassword = plainPassword;
CryptPassword = null;
NewCryptPassword = null;
break;
}
case PasswordProtection.Crypt:
{
m_PlainPassword = null;
m_CryptPassword = HashMD5( plainPassword );
m_NewCryptPassword = null;
PlainPassword = null;
CryptPassword = HashMD5( plainPassword );
NewCryptPassword = null;
break;
}
default: // PasswordProtection.NewCrypt
{
m_PlainPassword = null;
m_CryptPassword = null;
m_NewCryptPassword = HashSHA1( m_Username + plainPassword );
PlainPassword = null;
CryptPassword = null;
NewCryptPassword = HashSHA1( Username + plainPassword );
break;
}
@ -478,19 +421,19 @@ namespace Server.Accounting
bool ok;
PasswordProtection curProt;
if ( m_PlainPassword != null )
if ( PlainPassword != null )
{
ok = ( m_PlainPassword == plainPassword );
ok = ( PlainPassword == plainPassword );
curProt = PasswordProtection.None;
}
else if ( m_CryptPassword != null )
else if ( CryptPassword != null )
{
ok = ( m_CryptPassword == HashMD5( plainPassword ) );
ok = ( CryptPassword == HashMD5( plainPassword ) );
curProt = PasswordProtection.Crypt;
}
else
{
ok = ( m_NewCryptPassword == HashSHA1( m_Username + plainPassword ) );
ok = ( NewCryptPassword == HashSHA1( Username + plainPassword ) );
curProt = PasswordProtection.NewCrypt;
}
@ -504,16 +447,14 @@ namespace Server.Accounting
public static void Initialize()
{
EventSink.Connected += new ConnectedEventHandler( EventSink_Connected );
EventSink.Disconnected += new DisconnectedEventHandler( EventSink_Disconnected );
EventSink.Login += new LoginEventHandler( EventSink_Login );
EventSink.Connected += EventSink_Connected;
EventSink.Disconnected += EventSink_Disconnected;
EventSink.Login += EventSink_Login;
}
private static void EventSink_Connected( ConnectedEventArgs e )
{
Account acc = e.Mobile.Account as Account;
if ( acc == null )
if ( !(e.Mobile.Account is Account acc) )
return;
if ( acc.Young && acc.m_YoungTimer == null )
@ -525,9 +466,7 @@ namespace Server.Accounting
private static void EventSink_Disconnected( DisconnectedEventArgs e )
{
Account acc = e.Mobile.Account as Account;
if ( acc == null )
if ( !(e.Mobile.Account is Account acc) )
return;
if ( acc.m_YoungTimer != null )
@ -536,8 +475,7 @@ namespace Server.Accounting
acc.m_YoungTimer = null;
}
PlayerMobile m = e.Mobile as PlayerMobile;
if ( m == null )
if ( !(e.Mobile is PlayerMobile m) )
return;
acc.m_TotalGameTime += DateTime.UtcNow - m.SessionStart;
@ -545,14 +483,10 @@ namespace Server.Accounting
private static void EventSink_Login( LoginEventArgs e )
{
PlayerMobile m = e.Mobile as PlayerMobile;
if ( m == null )
if ( !(e.Mobile is PlayerMobile m) )
return;
Account acc = m.Account as Account;
if ( acc == null )
if ( !(m.Account is Account acc) )
return;
if ( m.Young && acc.Young )
@ -566,13 +500,11 @@ namespace Server.Accounting
public void RemoveYoungStatus( int message )
{
this.Young = false;
Young = false;
for ( int i = 0; i < m_Mobiles.Length; i++ )
{
PlayerMobile m = m_Mobiles[i] as PlayerMobile;
if ( m != null && m.Young )
if ( m_Mobiles[i] is PlayerMobile m && m.Young )
{
m.Young = false;
@ -613,26 +545,26 @@ namespace Server.Accounting
public Account( string username, string password )
{
m_Username = username;
Username = username;
SetPassword( password );
m_AccessLevel = AccessLevel.Player;
m_Created = m_LastLogin = DateTime.UtcNow;
Created = LastLogin = DateTime.UtcNow;
m_TotalGameTime = TimeSpan.Zero;
m_Mobiles = new Mobile[7];
m_IPRestrictions = new string[0];
m_LoginIPs = new IPAddress[0];
IPRestrictions = new string[0];
LoginIPs = new IPAddress[0];
Accounts.Add( this );
}
public Account( XmlElement node )
{
m_Username = Utility.GetText( node["username"], "empty" );
Username = Utility.GetText( node["username"], "empty" );
string plainPassword = Utility.GetText( node["password"], null );
string cryptPassword = Utility.GetText( node["cryptPassword"], null );
@ -645,9 +577,9 @@ namespace Server.Accounting
if ( plainPassword != null )
SetPassword( plainPassword );
else if ( newCryptPassword != null )
m_NewCryptPassword = newCryptPassword;
NewCryptPassword = newCryptPassword;
else if ( cryptPassword != null )
m_CryptPassword = cryptPassword;
CryptPassword = cryptPassword;
else
SetPassword( "empty" );
@ -656,11 +588,11 @@ namespace Server.Accounting
case PasswordProtection.Crypt:
{
if ( cryptPassword != null )
m_CryptPassword = cryptPassword;
CryptPassword = cryptPassword;
else if ( plainPassword != null )
SetPassword( plainPassword );
else if ( newCryptPassword != null )
m_NewCryptPassword = newCryptPassword;
NewCryptPassword = newCryptPassword;
else
SetPassword( "empty" );
@ -669,11 +601,11 @@ namespace Server.Accounting
default: // PasswordProtection.NewCrypt
{
if ( newCryptPassword != null )
m_NewCryptPassword = newCryptPassword;
NewCryptPassword = newCryptPassword;
else if ( plainPassword != null )
SetPassword( plainPassword );
else if ( cryptPassword != null )
m_CryptPassword = cryptPassword;
CryptPassword = cryptPassword;
else
SetPassword( "empty" );
@ -682,18 +614,18 @@ namespace Server.Accounting
}
Enum.TryParse( Utility.GetText( node["accessLevel"], "Player" ), true, out m_AccessLevel );
m_Flags = Utility.GetXMLInt32( Utility.GetText( node["flags"], "0" ), 0 );
m_Created = Utility.GetXMLDateTime( Utility.GetText( node["created"], null ), DateTime.UtcNow );
m_LastLogin = Utility.GetXMLDateTime( Utility.GetText( node["lastLogin"], null ), DateTime.UtcNow );
Flags = Utility.GetXMLInt32( Utility.GetText( node["flags"], "0" ), 0 );
Created = Utility.GetXMLDateTime( Utility.GetText( node["created"], null ), DateTime.UtcNow );
LastLogin = Utility.GetXMLDateTime( Utility.GetText( node["lastLogin"], null ), DateTime.UtcNow );
TotalGold = Utility.GetXMLInt32( Utility.GetText(node["totalGold"], "0" ), 0 );
TotalPlat = Utility.GetXMLInt32(Utility.GetText(node["totalPlat"], "0"), 0);
m_Mobiles = LoadMobiles( node );
m_Comments = LoadComments( node );
m_Tags = LoadTags( node );
m_LoginIPs = LoadAddressList( node );
m_IPRestrictions = LoadAccessCheck( node );
LoginIPs = LoadAddressList( node );
IPRestrictions = LoadAccessCheck( node );
for ( int i = 0; i < m_Mobiles.Length; ++i )
{
@ -706,15 +638,13 @@ namespace Server.Accounting
{
for ( int i = 0; i < m_Mobiles.Length; i++ )
{
PlayerMobile m = m_Mobiles[i] as PlayerMobile;
if ( m != null )
if ( m_Mobiles[i] is PlayerMobile m )
totalGameTime += m.GameTime;
}
}
m_TotalGameTime = totalGameTime;
if ( this.Young )
if ( Young )
CheckYoung();
Accounts.Add( this );
@ -776,7 +706,7 @@ namespace Server.Accounting
{
IPAddress address;
if( IPAddress.TryParse( Utility.GetText( ip, null ), out address ) )
if ( IPAddress.TryParse( Utility.GetText( ip, null ), out address ) )
{
list[count] = Utility.Intern( address );
count++;
@ -895,7 +825,7 @@ namespace Server.Accounting
}
public bool HasAccess( IPAddress ipAddress ) {
AccessLevel level = Misc.AccountHandler.LockdownLevel;
AccessLevel level = AccountHandler.LockdownLevel;
if ( level > AccessLevel.Player )
{
@ -907,7 +837,7 @@ namespace Server.Accounting
}
else
{
for ( int i = 0; !hasAccess && i < this.Length; ++i )
for ( int i = 0; !hasAccess && i < Length; ++i )
{
Mobile m = this[i];
@ -920,10 +850,10 @@ namespace Server.Accounting
return false;
}
bool accessAllowed = ( m_IPRestrictions.Length == 0 || IPLimiter.IsExempt( ipAddress ) );
bool accessAllowed = ( IPRestrictions.Length == 0 || IPLimiter.IsExempt( ipAddress ) );
for ( int i = 0; !accessAllowed && i < m_IPRestrictions.Length; ++i )
accessAllowed = Utility.IPMatch( m_IPRestrictions[i], ipAddress );
for ( int i = 0; !accessAllowed && i < IPRestrictions.Length; ++i )
accessAllowed = Utility.IPMatch( IPRestrictions[i], ipAddress );
return accessAllowed;
}
@ -943,7 +873,7 @@ namespace Server.Accounting
if ( IPLimiter.IsExempt( ipAddress ) )
return;
if ( m_LoginIPs.Length == 0 ) {
if ( LoginIPs.Length == 0 ) {
if ( AccountHandler.IPTable.ContainsKey( ipAddress ) )
AccountHandler.IPTable[ipAddress]++;
else
@ -952,19 +882,19 @@ namespace Server.Accounting
bool contains = false;
for ( int i = 0; !contains && i < m_LoginIPs.Length; ++i )
contains = m_LoginIPs[i].Equals( ipAddress );
for ( int i = 0; !contains && i < LoginIPs.Length; ++i )
contains = LoginIPs[i].Equals( ipAddress );
if ( contains )
return;
IPAddress[] old = m_LoginIPs;
m_LoginIPs = new IPAddress[old.Length + 1];
IPAddress[] old = LoginIPs;
LoginIPs = new IPAddress[old.Length + 1];
for ( int i = 0; i < old.Length; ++i )
m_LoginIPs[i] = old[i];
LoginIPs[i] = old[i];
m_LoginIPs[old.Length] = ipAddress;
LoginIPs[old.Length] = ipAddress;
}
/// <summary>
@ -978,7 +908,7 @@ namespace Server.Accounting
}
public bool CheckAccess( IPAddress ipAddress ) {
bool hasAccess = this.HasAccess( ipAddress );
bool hasAccess = HasAccess( ipAddress );
if ( hasAccess ) {
LogAccess( ipAddress );
@ -996,27 +926,27 @@ namespace Server.Accounting
xml.WriteStartElement( "account" );
xml.WriteStartElement( "username" );
xml.WriteString( m_Username );
xml.WriteString( Username );
xml.WriteEndElement();
if ( m_PlainPassword != null )
if ( PlainPassword != null )
{
xml.WriteStartElement( "password" );
xml.WriteString( m_PlainPassword );
xml.WriteString( PlainPassword );
xml.WriteEndElement();
}
if ( m_CryptPassword != null )
if ( CryptPassword != null )
{
xml.WriteStartElement( "cryptPassword" );
xml.WriteString( m_CryptPassword );
xml.WriteString( CryptPassword );
xml.WriteEndElement();
}
if ( m_NewCryptPassword != null )
if ( NewCryptPassword != null )
{
xml.WriteStartElement( "newCryptPassword" );
xml.WriteString( m_NewCryptPassword );
xml.WriteString( NewCryptPassword );
xml.WriteEndElement();
}
@ -1027,19 +957,19 @@ namespace Server.Accounting
xml.WriteEndElement();
}
if ( m_Flags != 0 )
if ( Flags != 0 )
{
xml.WriteStartElement( "flags" );
xml.WriteString( XmlConvert.ToString( m_Flags ) );
xml.WriteString( XmlConvert.ToString( Flags ) );
xml.WriteEndElement();
}
xml.WriteStartElement( "created" );
xml.WriteString( XmlConvert.ToString( m_Created, XmlDateTimeSerializationMode.Utc ) );
xml.WriteString( XmlConvert.ToString( Created, XmlDateTimeSerializationMode.Utc ) );
xml.WriteEndElement();
xml.WriteStartElement( "lastLogin" );
xml.WriteString( XmlConvert.ToString( m_LastLogin, XmlDateTimeSerializationMode.Utc ) );
xml.WriteString( XmlConvert.ToString( LastLogin, XmlDateTimeSerializationMode.Utc ) );
xml.WriteEndElement();
xml.WriteStartElement( "totalGameTime" );
@ -1085,30 +1015,30 @@ namespace Server.Accounting
xml.WriteEndElement();
}
if ( m_LoginIPs.Length > 0 )
if ( LoginIPs.Length > 0 )
{
xml.WriteStartElement( "addressList" );
xml.WriteAttributeString( "count", m_LoginIPs.Length.ToString() );
xml.WriteAttributeString( "count", LoginIPs.Length.ToString() );
for ( int i = 0; i < m_LoginIPs.Length; ++i )
for ( int i = 0; i < LoginIPs.Length; ++i )
{
xml.WriteStartElement( "ip" );
xml.WriteString( m_LoginIPs[i].ToString() );
xml.WriteString( LoginIPs[i].ToString() );
xml.WriteEndElement();
}
xml.WriteEndElement();
}
if ( m_IPRestrictions.Length > 0 )
if ( IPRestrictions.Length > 0 )
{
xml.WriteStartElement( "accessCheck" );
for ( int i = 0; i < m_IPRestrictions.Length; ++i )
for ( int i = 0; i < IPRestrictions.Length; ++i )
{
xml.WriteStartElement( "ip" );
xml.WriteString( m_IPRestrictions[i] );
xml.WriteString( IPRestrictions[i] );
xml.WriteEndElement();
}
@ -1135,7 +1065,7 @@ namespace Server.Accounting
{
int count = 0;
for ( int i = 0; i < this.Length; ++i )
for ( int i = 0; i < Length; ++i )
{
if ( this[i] != null )
++count;
@ -1148,18 +1078,12 @@ namespace Server.Accounting
/// <summary>
/// Gets the maximum amount of characters allowed to be created on this account. Values other than 1, 5, 6, or 7 are not supported by the client.
/// </summary>
public int Limit
{
get { return ( Core.SA ? 7 : Core.AOS ? 6 : 5 ); }
}
public int Limit => ( Core.SA ? 7 : Core.AOS ? 6 : 5 );
/// <summary>
/// Gets the maximum amount of characters that this account can hold.
/// </summary>
public int Length
{
get { return m_Mobiles.Length; }
}
public int Length => m_Mobiles.Length;
/// <summary>
/// Gets or sets the character at a specified index for this account. Out of bound index values are handled; null returned for get, ignored for set.
@ -1200,7 +1124,7 @@ namespace Server.Accounting
public override string ToString()
{
return m_Username;
return Username;
}
public int CompareTo( Account other )
@ -1208,7 +1132,7 @@ namespace Server.Accounting
if ( other == null )
return 1;
return m_Username.CompareTo( other.m_Username );
return Username.CompareTo( other.Username );
}
public int CompareTo( IAccount other )
@ -1216,13 +1140,13 @@ namespace Server.Accounting
if ( other == null )
return 1;
return m_Username.CompareTo( other.Username );
return Username.CompareTo( other.Username );
}
public int CompareTo( object obj )
{
if ( obj is Account )
return this.CompareTo( (Account) obj );
if ( obj is Account account )
return CompareTo( account );
throw new ArgumentException();
}

View file

@ -1,148 +1,128 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using Server;
using Server.Network;
namespace Server.Accounting
{
public class AccountAttackLimiter
{
public static bool Enabled = true;
public class AccountAttackLimiter
{
public static bool Enabled = true;
public static void Initialize()
{
if ( !Enabled )
return;
private static List<InvalidAccountAccessLog> m_List = new List<InvalidAccountAccessLog>();
PacketHandlers.RegisterThrottler( 0x80, new ThrottlePacketCallback( Throttle_Callback ) );
PacketHandlers.RegisterThrottler( 0x91, new ThrottlePacketCallback( Throttle_Callback ) );
PacketHandlers.RegisterThrottler( 0xCF, new ThrottlePacketCallback( Throttle_Callback ) );
}
public static void Initialize()
{
if (!Enabled)
return;
public static bool Throttle_Callback( NetState ns )
{
InvalidAccountAccessLog accessLog = FindAccessLog( ns );
PacketHandlers.RegisterThrottler(0x80, Throttle_Callback);
PacketHandlers.RegisterThrottler(0x91, Throttle_Callback);
PacketHandlers.RegisterThrottler(0xCF, Throttle_Callback);
}
if ( accessLog == null )
return true;
public static bool Throttle_Callback(NetState ns)
{
InvalidAccountAccessLog accessLog = FindAccessLog(ns);
return ( DateTime.UtcNow >= (accessLog.LastAccessTime + ComputeThrottle( accessLog.Counts )) );
}
if (accessLog == null)
return true;
private static List<InvalidAccountAccessLog> m_List = new List<InvalidAccountAccessLog>();
return DateTime.UtcNow >= accessLog.LastAccessTime + ComputeThrottle(accessLog.Counts);
}
public static InvalidAccountAccessLog FindAccessLog( NetState ns )
{
if ( ns == null )
return null;
public static InvalidAccountAccessLog FindAccessLog(NetState ns)
{
if (ns == null)
return null;
IPAddress ipAddress = ns.Address;
IPAddress ipAddress = ns.Address;
for ( int i = 0; i < m_List.Count; ++i )
{
InvalidAccountAccessLog accessLog = m_List[i];
for (int i = 0; i < m_List.Count; ++i)
{
InvalidAccountAccessLog accessLog = m_List[i];
if ( accessLog.HasExpired )
m_List.RemoveAt( i-- );
else if ( accessLog.Address.Equals( ipAddress ) )
return accessLog;
}
if (accessLog.HasExpired)
m_List.RemoveAt(i--);
else if (accessLog.Address.Equals(ipAddress))
return accessLog;
}
return null;
}
return null;
}
public static void RegisterInvalidAccess( NetState ns )
{
if ( ns == null || !Enabled )
return;
public static void RegisterInvalidAccess(NetState ns)
{
if (ns == null || !Enabled)
return;
InvalidAccountAccessLog accessLog = FindAccessLog( ns );
InvalidAccountAccessLog accessLog = FindAccessLog(ns);
if ( accessLog == null )
m_List.Add( accessLog = new InvalidAccountAccessLog( ns.Address ) );
if (accessLog == null)
m_List.Add(accessLog = new InvalidAccountAccessLog(ns.Address));
accessLog.Counts += 1;
accessLog.RefreshAccessTime();
accessLog.Counts += 1;
accessLog.RefreshAccessTime();
if ( accessLog.Counts >= 3 ) {
try {
using ( StreamWriter op = new StreamWriter( "throttle.log", true ) ) {
op.WriteLine(
"{0}\t{1}\t{2}",
DateTime.UtcNow,
ns,
accessLog.Counts
);
}
}
catch {
}
}
}
if (accessLog.Counts >= 3)
try
{
using (StreamWriter op = new StreamWriter("throttle.log", true))
{
op.WriteLine(
"{0}\t{1}\t{2}",
DateTime.UtcNow,
ns,
accessLog.Counts
);
}
}
catch
{
}
}
public static TimeSpan ComputeThrottle( int counts )
{
if ( counts >= 15 )
return TimeSpan.FromMinutes( 5.0 );
public static TimeSpan ComputeThrottle(int counts)
{
if (counts >= 15)
return TimeSpan.FromMinutes(5.0);
if ( counts >= 10 )
return TimeSpan.FromMinutes( 1.0 );
if (counts >= 10)
return TimeSpan.FromMinutes(1.0);
if ( counts >= 5 )
return TimeSpan.FromSeconds( 20.0 );
if (counts >= 5)
return TimeSpan.FromSeconds(20.0);
if ( counts >= 3 )
return TimeSpan.FromSeconds( 10.0 );
if (counts >= 3)
return TimeSpan.FromSeconds(10.0);
if ( counts >= 1 )
return TimeSpan.FromSeconds( 2.0 );
if (counts >= 1)
return TimeSpan.FromSeconds(2.0);
return TimeSpan.Zero;
}
}
return TimeSpan.Zero;
}
}
public class InvalidAccountAccessLog
{
private IPAddress m_Address;
private DateTime m_LastAccessTime;
private int m_Counts;
public class InvalidAccountAccessLog
{
public InvalidAccountAccessLog(IPAddress address)
{
Address = address;
RefreshAccessTime();
}
public IPAddress Address
{
get{ return m_Address; }
set{ m_Address = value; }
}
public IPAddress Address{ get; set; }
public DateTime LastAccessTime
{
get{ return m_LastAccessTime; }
set{ m_LastAccessTime = value; }
}
public DateTime LastAccessTime{ get; set; }
public bool HasExpired
{
get{ return ( DateTime.UtcNow >= ( m_LastAccessTime + TimeSpan.FromHours( 1.0 ) ) ); }
}
public bool HasExpired => DateTime.UtcNow >= LastAccessTime + TimeSpan.FromHours(1.0);
public int Counts
{
get{ return m_Counts; }
set{ m_Counts = value; }
}
public int Counts{ get; set; }
public void RefreshAccessTime()
{
m_LastAccessTime = DateTime.UtcNow;
}
public InvalidAccountAccessLog( IPAddress address )
{
m_Address = address;
RefreshAccessTime();
}
}
public void RefreshAccessTime()
{
LastAccessTime = DateTime.UtcNow;
}
}
}

View file

@ -3,75 +3,71 @@ using System.Xml;
namespace Server.Accounting
{
public class AccountComment
{
private string m_AddedBy;
private string m_Content;
private DateTime m_LastModified;
public class AccountComment
{
private string m_Content;
/// <summary>
/// A string representing who added this comment.
/// </summary>
public string AddedBy
{
get{ return m_AddedBy; }
}
/// <summary>
/// Constructs a new AccountComment instance.
/// </summary>
/// <param name="addedBy">Initial AddedBy value.</param>
/// <param name="content">Initial Content value.</param>
public AccountComment(string addedBy, string content)
{
AddedBy = addedBy;
m_Content = content;
LastModified = DateTime.UtcNow;
}
/// <summary>
/// Gets or sets the body of this comment. Setting this value will reset LastModified.
/// </summary>
public string Content
{
get{ return m_Content; }
set{ m_Content = value; m_LastModified = DateTime.UtcNow; }
}
/// <summary>
/// Deserializes an AccountComment instance from an xml element.
/// </summary>
/// <param name="node">The XmlElement instance from which to deserialize.</param>
public AccountComment(XmlElement node)
{
AddedBy = Utility.GetAttribute(node, "addedBy", "empty");
LastModified = Utility.GetXMLDateTime(Utility.GetAttribute(node, "lastModified"), DateTime.UtcNow);
m_Content = Utility.GetText(node, "");
}
/// <summary>
/// The date and time when this account was last modified -or- the comment creation time, if never modified.
/// </summary>
public DateTime LastModified
{
get{ return m_LastModified; }
}
/// <summary>
/// A string representing who added this comment.
/// </summary>
public string AddedBy{ get; }
/// <summary>
/// Constructs a new AccountComment instance.
/// </summary>
/// <param name="addedBy">Initial AddedBy value.</param>
/// <param name="content">Initial Content value.</param>
public AccountComment( string addedBy, string content )
{
m_AddedBy = addedBy;
m_Content = content;
m_LastModified = DateTime.UtcNow;
}
/// <summary>
/// Gets or sets the body of this comment. Setting this value will reset LastModified.
/// </summary>
public string Content
{
get => m_Content;
set
{
m_Content = value;
LastModified = DateTime.UtcNow;
}
}
/// <summary>
/// Deserializes an AccountComment instance from an xml element.
/// </summary>
/// <param name="node">The XmlElement instance from which to deserialize.</param>
public AccountComment( XmlElement node )
{
m_AddedBy = Utility.GetAttribute( node, "addedBy", "empty" );
m_LastModified = Utility.GetXMLDateTime( Utility.GetAttribute( node, "lastModified" ), DateTime.UtcNow );
m_Content = Utility.GetText( node, "" );
}
/// <summary>
/// The date and time when this account was last modified -or- the comment creation time, if never modified.
/// </summary>
public DateTime LastModified{ get; private set; }
/// <summary>
/// Serializes this AccountComment instance to an XmlTextWriter.
/// </summary>
/// <param name="xml">The XmlTextWriter instance from which to serialize.</param>
public void Save( XmlTextWriter xml )
{
xml.WriteStartElement( "comment" );
/// <summary>
/// Serializes this AccountComment instance to an XmlTextWriter.
/// </summary>
/// <param name="xml">The XmlTextWriter instance from which to serialize.</param>
public void Save(XmlTextWriter xml)
{
xml.WriteStartElement("comment");
xml.WriteAttributeString( "addedBy", m_AddedBy );
xml.WriteAttributeString("addedBy", AddedBy);
xml.WriteAttributeString( "lastModified", XmlConvert.ToString( m_LastModified, XmlDateTimeSerializationMode.Utc ) );
xml.WriteAttributeString("lastModified", XmlConvert.ToString(LastModified, XmlDateTimeSerializationMode.Utc));
xml.WriteString( m_Content );
xml.WriteString(m_Content);
xml.WriteEndElement();
}
}
xml.WriteEndElement();
}
}
}

View file

@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using Server;
using Server.Accounting;
using Server.Commands;
using Server.Engines.Help;
@ -11,425 +10,417 @@ using Server.Regions;
namespace Server.Misc
{
public enum PasswordProtection
{
None,
Crypt,
NewCrypt
}
public enum PasswordProtection
{
None,
Crypt,
NewCrypt
}
public class AccountHandler
{
private static int MaxAccountsPerIP = 1;
private static bool AutoAccountCreation = true;
private static bool RestrictDeletion = !TestCenter.Enabled;
private static TimeSpan DeleteDelay = TimeSpan.FromDays( 7.0 );
public class AccountHandler
{
private static int MaxAccountsPerIP = 1;
private static bool AutoAccountCreation = true;
private static bool RestrictDeletion = !TestCenter.Enabled;
private static TimeSpan DeleteDelay = TimeSpan.FromDays(7.0);
public static PasswordProtection ProtectPasswords = PasswordProtection.NewCrypt;
public static PasswordProtection ProtectPasswords = PasswordProtection.NewCrypt;
private static AccessLevel m_LockdownLevel;
private static CityInfo[] StartingCities =
{
new CityInfo("New Haven", "New Haven Bank", 1150168, 3667, 2625, 0),
new CityInfo("Yew", "The Empath Abbey", 1075072, 633, 858, 0),
new CityInfo("Minoc", "The Barnacle", 1075073, 2476, 413, 15),
new CityInfo("Britain", "The Wayfarer's Inn", 1075074, 1602, 1591, 20),
new CityInfo("Moonglow", "The Scholars Inn", 1075075, 4408, 1168, 0),
new CityInfo("Trinsic", "The Traveler's Inn", 1075076, 1845, 2745, 0),
new CityInfo("Jhelom", "The Mercenary Inn", 1075078, 1374, 3826, 0),
new CityInfo("Skara Brae", "The Falconer's Inn", 1075079, 618, 2234, 0),
new CityInfo("Vesper", "The Ironwood Inn", 1075080, 2771, 976, 0)
};
public static AccessLevel LockdownLevel
{
get{ return m_LockdownLevel; }
set{ m_LockdownLevel = value; }
}
/* Old Haven/Magincia Locations
new CityInfo( "Britain", "Sweet Dreams Inn", 1496, 1628, 10 );
// ..
// Trinsic
new CityInfo( "Magincia", "The Great Horns Tavern", 3734, 2222, 20 ),
// Jhelom
// ..
new CityInfo( "Haven", "Buckler's Hideaway", 3667, 2625, 0 )
private static CityInfo[] StartingCities = new CityInfo[]
{
new CityInfo( "New Haven", "New Haven Bank", 1150168, 3667, 2625, 0 ),
new CityInfo( "Yew", "The Empath Abbey", 1075072, 633, 858, 0 ),
new CityInfo( "Minoc", "The Barnacle", 1075073, 2476, 413, 15 ),
new CityInfo( "Britain", "The Wayfarer's Inn", 1075074, 1602, 1591, 20 ),
new CityInfo( "Moonglow", "The Scholars Inn", 1075075, 4408, 1168, 0 ),
new CityInfo( "Trinsic", "The Traveler's Inn", 1075076, 1845, 2745, 0 ),
new CityInfo( "Jhelom", "The Mercenary Inn", 1075078, 1374, 3826, 0 ),
new CityInfo( "Skara Brae", "The Falconer's Inn", 1075079, 618, 2234, 0 ),
new CityInfo( "Vesper", "The Ironwood Inn", 1075080, 2771, 976, 0 )
};
if ( Core.AOS )
{
//CityInfo haven = new CityInfo( "Haven", "Uzeraan's Mansion", 3618, 2591, 0 );
CityInfo haven = new CityInfo( "Haven", "Uzeraan's Mansion", 3503, 2574, 14 );
StartingCities[StartingCities.Length - 1] = haven;
}
*/
/* Old Haven/Magincia Locations
new CityInfo( "Britain", "Sweet Dreams Inn", 1496, 1628, 10 );
// ..
// Trinsic
new CityInfo( "Magincia", "The Great Horns Tavern", 3734, 2222, 20 ),
// Jhelom
// ..
new CityInfo( "Haven", "Buckler's Hideaway", 3667, 2625, 0 )
private static bool PasswordCommandEnabled = false;
if ( Core.AOS )
{
//CityInfo haven = new CityInfo( "Haven", "Uzeraan's Mansion", 3618, 2591, 0 );
CityInfo haven = new CityInfo( "Haven", "Uzeraan's Mansion", 3503, 2574, 14 );
StartingCities[StartingCities.Length - 1] = haven;
}
*/
private static Dictionary<IPAddress, int> m_IPTable;
private static bool PasswordCommandEnabled = false;
private static readonly char[] m_ForbiddenChars =
{
'<', '>', ':', '"', '/', '\\', '|', '?', '*'
};
public static void Initialize()
{
EventSink.DeleteRequest += new DeleteRequestEventHandler( EventSink_DeleteRequest );
EventSink.AccountLogin += new AccountLoginEventHandler( EventSink_AccountLogin );
EventSink.GameLogin += new GameLoginEventHandler( EventSink_GameLogin );
public static AccessLevel LockdownLevel{ get; set; }
if ( PasswordCommandEnabled )
CommandSystem.Register( "Password", AccessLevel.Player, new CommandEventHandler( Password_OnCommand ) );
}
public static Dictionary<IPAddress, int> IPTable
{
get
{
if (m_IPTable == null)
{
m_IPTable = new Dictionary<IPAddress, int>();
[Usage( "Password <newPassword> <repeatPassword>" )]
[Description( "Changes the password of the commanding players account. Requires the same C-class IP address as the account's creator." )]
public static void Password_OnCommand( CommandEventArgs e )
{
Mobile from = e.Mobile;
Account acct = from.Account as Account;
foreach (Account a in Accounts.GetAccounts())
if (a.LoginIPs.Length > 0)
{
IPAddress ip = a.LoginIPs[0];
if ( acct == null )
return;
if (m_IPTable.ContainsKey(ip))
m_IPTable[ip]++;
else
m_IPTable[ip] = 1;
}
}
IPAddress[] accessList = acct.LoginIPs;
return m_IPTable;
}
}
if ( accessList.Length == 0 )
return;
public static void Initialize()
{
EventSink.DeleteRequest += EventSink_DeleteRequest;
EventSink.AccountLogin += EventSink_AccountLogin;
EventSink.GameLogin += EventSink_GameLogin;
NetState ns = from.NetState;
if (PasswordCommandEnabled)
CommandSystem.Register("Password", AccessLevel.Player, Password_OnCommand);
}
if ( ns == null )
return;
[Usage("Password <newPassword> <repeatPassword>")]
[Description(
"Changes the password of the commanding players account. Requires the same C-class IP address as the account's creator.")]
public static void Password_OnCommand(CommandEventArgs e)
{
Mobile from = e.Mobile;
if ( e.Length == 0 )
{
from.SendMessage( "You must specify the new password." );
return;
}
else if ( e.Length == 1 )
{
from.SendMessage( "To prevent potential typing mistakes, you must type the password twice. Use the format:" );
from.SendMessage( "Password \"(newPassword)\" \"(repeated)\"" );
return;
}
if (!(from.Account is Account acct))
return;
string pass = e.GetString( 0 );
string pass2 = e.GetString( 1 );
IPAddress[] accessList = acct.LoginIPs;
if ( pass != pass2 )
{
from.SendMessage( "The passwords do not match." );
return;
}
if (accessList.Length == 0)
return;
bool isSafe = true;
NetState ns = from.NetState;
for ( int i = 0; isSafe && i < pass.Length; ++i )
isSafe = ( pass[i] >= 0x20 && pass[i] < 0x7F );
if (ns == null)
return;
if ( !isSafe )
{
from.SendMessage( "That is not a valid password." );
return;
}
if (e.Length == 0)
{
from.SendMessage("You must specify the new password.");
return;
}
try
{
IPAddress ipAddress = ns.Address;
if (e.Length == 1)
{
from.SendMessage("To prevent potential typing mistakes, you must type the password twice. Use the format:");
from.SendMessage("Password \"(newPassword)\" \"(repeated)\"");
return;
}
if ( Utility.IPMatchClassC( accessList[0], ipAddress ) )
{
acct.SetPassword( pass );
from.SendMessage( "The password to your account has changed." );
}
else
{
PageEntry entry = PageQueue.GetEntry( from );
string pass = e.GetString(0);
string pass2 = e.GetString(1);
if ( entry != null )
{
if ( entry.Message.StartsWith( "[Automated: Change Password]" ) )
from.SendMessage( "You already have a password change request in the help system queue." );
else
from.SendMessage( "Your IP address does not match that which created this account." );
}
else if ( PageQueue.CheckAllowedToPage( from ) )
{
from.SendMessage( "Your IP address does not match that which created this account. A page has been entered into the help system on your behalf." );
if (pass != pass2)
{
from.SendMessage("The passwords do not match.");
return;
}
from.SendLocalizedMessage( 501234, "", 0x35 ); /* The next available Counselor/Game Master will respond as soon as possible.
bool isSafe = true;
for (int i = 0; isSafe && i < pass.Length; ++i)
isSafe = pass[i] >= 0x20 && pass[i] < 0x7F;
if (!isSafe)
{
from.SendMessage("That is not a valid password.");
return;
}
try
{
IPAddress ipAddress = ns.Address;
if (Utility.IPMatchClassC(accessList[0], ipAddress))
{
acct.SetPassword(pass);
from.SendMessage("The password to your account has changed.");
}
else
{
PageEntry entry = PageQueue.GetEntry(from);
if (entry != null)
{
if (entry.Message.StartsWith("[Automated: Change Password]"))
from.SendMessage("You already have a password change request in the help system queue.");
else
from.SendMessage("Your IP address does not match that which created this account.");
}
else if (PageQueue.CheckAllowedToPage(from))
{
from.SendMessage(
"Your IP address does not match that which created this account. A page has been entered into the help system on your behalf.");
from.SendLocalizedMessage(501234, "",
0x35); /* The next available Counselor/Game Master will respond as soon as possible.
* Please check your Journal for messages every few minutes.
*/
PageQueue.Enqueue( new PageEntry( from, String.Format( "[Automated: Change Password]<br>Desired password: {0}<br>Current IP address: {1}<br>Account IP address: {2}", pass, ipAddress, accessList[0] ), PageType.Account ) );
}
PageQueue.Enqueue(new PageEntry(from,
$"[Automated: Change Password]<br>Desired password: {pass}<br>Current IP address: {ipAddress}<br>Account IP address: {accessList[0]}",
PageType.Account));
}
}
}
catch
{
}
}
}
}
catch
{
}
}
private static void EventSink_DeleteRequest(DeleteRequestEventArgs e)
{
NetState state = e.State;
int index = e.Index;
private static void EventSink_DeleteRequest( DeleteRequestEventArgs e )
{
NetState state = e.State;
int index = e.Index;
if (!(state.Account is Account acct))
{
state.Dispose();
}
else if (index < 0 || index >= acct.Length)
{
state.Send(new DeleteResult(DeleteResultType.BadRequest));
state.Send(new CharacterListUpdate(acct));
}
else
{
Mobile m = acct[index];
Account acct = state.Account as Account;
if (m == null)
{
state.Send(new DeleteResult(DeleteResultType.CharNotExist));
state.Send(new CharacterListUpdate(acct));
}
else if (m.NetState != null)
{
state.Send(new DeleteResult(DeleteResultType.CharBeingPlayed));
state.Send(new CharacterListUpdate(acct));
}
else if (RestrictDeletion && DateTime.UtcNow < m.CreationTime + DeleteDelay)
{
state.Send(new DeleteResult(DeleteResultType.CharTooYoung));
state.Send(new CharacterListUpdate(acct));
}
else if (m.AccessLevel == AccessLevel.Player &&
Region.Find(m.LogoutLocation, m.LogoutMap).GetRegion(typeof(Jail)) != null
) //Don't need to check current location, if netstate is null, they're logged out
{
state.Send(new DeleteResult(DeleteResultType.BadRequest));
state.Send(new CharacterListUpdate(acct));
}
else
{
Console.WriteLine("Client: {0}: Deleting character {1} (0x{2:X})", state, index, m.Serial.Value);
if ( acct == null )
{
state.Dispose();
}
else if ( index < 0 || index >= acct.Length )
{
state.Send( new DeleteResult( DeleteResultType.BadRequest ) );
state.Send( new CharacterListUpdate( acct ) );
}
else
{
Mobile m = acct[index];
acct.Comments.Add(new AccountComment("System", $"Character #{index + 1} {m} deleted by {state}"));
if ( m == null )
{
state.Send( new DeleteResult( DeleteResultType.CharNotExist ) );
state.Send( new CharacterListUpdate( acct ) );
}
else if ( m.NetState != null )
{
state.Send( new DeleteResult( DeleteResultType.CharBeingPlayed ) );
state.Send( new CharacterListUpdate( acct ) );
}
else if ( RestrictDeletion && DateTime.UtcNow < (m.CreationTime + DeleteDelay) )
{
state.Send( new DeleteResult( DeleteResultType.CharTooYoung ) );
state.Send( new CharacterListUpdate( acct ) );
}
else if ( m.AccessLevel == AccessLevel.Player && Region.Find( m.LogoutLocation, m.LogoutMap ).GetRegion( typeof( Jail ) ) != null ) //Don't need to check current location, if netstate is null, they're logged out
{
state.Send( new DeleteResult( DeleteResultType.BadRequest ) );
state.Send( new CharacterListUpdate( acct ) );
}
else
{
Console.WriteLine( "Client: {0}: Deleting character {1} (0x{2:X})", state, index, m.Serial.Value );
m.Delete();
state.Send(new CharacterListUpdate(acct));
}
}
}
acct.Comments.Add( new AccountComment( "System", String.Format( "Character #{0} {1} deleted by {2}", index + 1, m, state ) ) );
public static bool CanCreate(IPAddress ip)
{
if (!IPTable.ContainsKey(ip))
return true;
m.Delete();
state.Send( new CharacterListUpdate( acct ) );
}
}
}
return IPTable[ip] < MaxAccountsPerIP;
}
public static bool CanCreate( IPAddress ip )
{
if ( !IPTable.ContainsKey( ip ) )
return true;
private static bool IsForbiddenChar(char c)
{
for (int i = 0; i < m_ForbiddenChars.Length; ++i)
if (c == m_ForbiddenChars[i])
return true;
return ( IPTable[ip] < MaxAccountsPerIP );
}
return false;
}
private static Dictionary<IPAddress, Int32> m_IPTable;
private static Account CreateAccount(NetState state, string un, string pw)
{
if (un.Length == 0 || pw.Length == 0)
return null;
public static Dictionary<IPAddress, Int32> IPTable
{
get
{
if ( m_IPTable == null )
{
m_IPTable = new Dictionary<IPAddress, Int32>();
bool isSafe = !(un.StartsWith(" ") || un.EndsWith(" ") || un.EndsWith("."));
foreach ( Account a in Accounts.GetAccounts() )
if ( a.LoginIPs.Length > 0 )
{
IPAddress ip = a.LoginIPs[0];
for (int i = 0; isSafe && i < un.Length; ++i)
isSafe = un[i] >= 0x20 && un[i] < 0x7F && !IsForbiddenChar(un[i]);
if ( m_IPTable.ContainsKey( ip ) )
m_IPTable[ip]++;
else
m_IPTable[ip] = 1;
}
}
for (int i = 0; isSafe && i < pw.Length; ++i)
isSafe = pw[i] >= 0x20 && pw[i] < 0x7F;
return m_IPTable;
}
}
if (!isSafe)
return null;
private static readonly char[] m_ForbiddenChars = new char[]
{
'<', '>', ':', '"', '/', '\\', '|', '?', '*'
};
if (!CanCreate(state.Address))
{
Console.WriteLine("Login: {0}: Account '{1}' not created, ip already has {2} account{3}.", state, un,
MaxAccountsPerIP, MaxAccountsPerIP == 1 ? "" : "s");
return null;
}
private static bool IsForbiddenChar( char c )
{
for ( int i = 0; i < m_ForbiddenChars.Length; ++i )
if ( c == m_ForbiddenChars[i] )
return true;
Console.WriteLine("Login: {0}: Creating new account '{1}'", state, un);
return false;
}
Account a = new Account(un, pw);
private static Account CreateAccount( NetState state, string un, string pw )
{
if ( un.Length == 0 || pw.Length == 0 )
return null;
return a;
}
bool isSafe = !( un.StartsWith( " " ) || un.EndsWith( " " ) || un.EndsWith( "." ) );
public static void EventSink_AccountLogin(AccountLoginEventArgs e)
{
if (!IPLimiter.SocketBlock && !IPLimiter.Verify(e.State.Address))
{
e.Accepted = false;
e.RejectReason = ALRReason.InUse;
for ( int i = 0; isSafe && i < un.Length; ++i )
isSafe = ( un[i] >= 0x20 && un[i] < 0x7F && !IsForbiddenChar( un[i] ) );
Console.WriteLine("Login: {0}: Past IP limit threshold", e.State);
for ( int i = 0; isSafe && i < pw.Length; ++i )
isSafe = ( pw[i] >= 0x20 && pw[i] < 0x7F );
using (StreamWriter op = new StreamWriter("ipLimits.log", true))
{
op.WriteLine("{0}\tPast IP limit threshold\t{1}", e.State, DateTime.UtcNow);
}
if ( !isSafe )
return null;
return;
}
if ( !CanCreate( state.Address ) )
{
Console.WriteLine( "Login: {0}: Account '{1}' not created, ip already has {2} account{3}.", state, un, MaxAccountsPerIP, MaxAccountsPerIP == 1 ? "" : "s" );
return null;
}
string un = e.Username;
string pw = e.Password;
Console.WriteLine( "Login: {0}: Creating new account '{1}'", state, un );
e.Accepted = false;
Account a = new Account( un, pw );
if (!(Accounts.GetAccount(un) is Account acct))
{
if (AutoAccountCreation && un.Trim().Length > 0
) // To prevent someone from making an account of just '' or a bunch of meaningless spaces
{
e.State.Account = acct = CreateAccount(e.State, un, pw);
e.Accepted = acct?.CheckAccess(e.State) ?? false;
return a;
}
if (!e.Accepted)
e.RejectReason = ALRReason.BadComm;
}
else
{
Console.WriteLine("Login: {0}: Invalid username '{1}'", e.State, un);
e.RejectReason = ALRReason.Invalid;
}
}
else if (!acct.HasAccess(e.State))
{
Console.WriteLine("Login: {0}: Access denied for '{1}'", e.State, un);
e.RejectReason = LockdownLevel > AccessLevel.Player ? ALRReason.BadComm : ALRReason.BadPass;
}
else if (!acct.CheckPassword(pw))
{
Console.WriteLine("Login: {0}: Invalid password for '{1}'", e.State, un);
e.RejectReason = ALRReason.BadPass;
}
else if (acct.Banned)
{
Console.WriteLine("Login: {0}: Banned account '{1}'", e.State, un);
e.RejectReason = ALRReason.Blocked;
}
else
{
Console.WriteLine("Login: {0}: Valid credentials for '{1}'", e.State, un);
e.State.Account = acct;
e.Accepted = true;
public static void EventSink_AccountLogin( AccountLoginEventArgs e )
{
if ( !IPLimiter.SocketBlock && !IPLimiter.Verify( e.State.Address ) )
{
e.Accepted = false;
e.RejectReason = ALRReason.InUse;
acct.LogAccess(e.State);
}
Console.WriteLine( "Login: {0}: Past IP limit threshold", e.State );
if (!e.Accepted)
AccountAttackLimiter.RegisterInvalidAccess(e.State);
}
using ( StreamWriter op = new StreamWriter( "ipLimits.log", true ) )
op.WriteLine( "{0}\tPast IP limit threshold\t{1}", e.State, DateTime.UtcNow );
public static void EventSink_GameLogin(GameLoginEventArgs e)
{
if (!IPLimiter.SocketBlock && !IPLimiter.Verify(e.State.Address))
{
e.Accepted = false;
return;
}
Console.WriteLine("Login: {0}: Past IP limit threshold", e.State);
string un = e.Username;
string pw = e.Password;
using (StreamWriter op = new StreamWriter("ipLimits.log", true))
{
op.WriteLine("{0}\tPast IP limit threshold\t{1}", e.State, DateTime.UtcNow);
}
e.Accepted = false;
Account acct = Accounts.GetAccount( un ) as Account;
return;
}
if ( acct == null )
{
if ( AutoAccountCreation && un.Trim().Length > 0 ) // To prevent someone from making an account of just '' or a bunch of meaningless spaces
{
e.State.Account = acct = CreateAccount( e.State, un, pw );
e.Accepted = acct == null ? false : acct.CheckAccess( e.State );
string un = e.Username;
string pw = e.Password;
if ( !e.Accepted )
e.RejectReason = ALRReason.BadComm;
}
else
{
Console.WriteLine( "Login: {0}: Invalid username '{1}'", e.State, un );
e.RejectReason = ALRReason.Invalid;
}
}
else if ( !acct.HasAccess( e.State ) )
{
Console.WriteLine( "Login: {0}: Access denied for '{1}'", e.State, un );
e.RejectReason = ( m_LockdownLevel > AccessLevel.Player ? ALRReason.BadComm : ALRReason.BadPass );
}
else if ( !acct.CheckPassword( pw ) )
{
Console.WriteLine( "Login: {0}: Invalid password for '{1}'", e.State, un );
e.RejectReason = ALRReason.BadPass;
}
else if ( acct.Banned )
{
Console.WriteLine( "Login: {0}: Banned account '{1}'", e.State, un );
e.RejectReason = ALRReason.Blocked;
}
else
{
Console.WriteLine( "Login: {0}: Valid credentials for '{1}'", e.State, un );
e.State.Account = acct;
e.Accepted = true;
if (!(Accounts.GetAccount(un) is Account acct))
{
e.Accepted = false;
}
else if (!acct.HasAccess(e.State))
{
Console.WriteLine("Login: {0}: Access denied for '{1}'", e.State, un);
e.Accepted = false;
}
else if (!acct.CheckPassword(pw))
{
Console.WriteLine("Login: {0}: Invalid password for '{1}'", e.State, un);
e.Accepted = false;
}
else if (acct.Banned)
{
Console.WriteLine("Login: {0}: Banned account '{1}'", e.State, un);
e.Accepted = false;
}
else
{
acct.LogAccess(e.State);
acct.LogAccess( e.State );
}
Console.WriteLine("Login: {0}: Account '{1}' at character list", e.State, un);
e.State.Account = acct;
e.Accepted = true;
e.CityInfo = StartingCities;
}
if ( !e.Accepted )
AccountAttackLimiter.RegisterInvalidAccess( e.State );
}
if (!e.Accepted)
AccountAttackLimiter.RegisterInvalidAccess(e.State);
}
public static void EventSink_GameLogin( GameLoginEventArgs e )
{
if ( !IPLimiter.SocketBlock && !IPLimiter.Verify( e.State.Address ) )
{
e.Accepted = false;
public static bool CheckAccount(Mobile mobCheck, Mobile accCheck)
{
if (accCheck?.Account is Account a)
for (int i = 0; i < a.Length; ++i)
if (a[i] == mobCheck)
return true;
Console.WriteLine( "Login: {0}: Past IP limit threshold", e.State );
using ( StreamWriter op = new StreamWriter( "ipLimits.log", true ) )
op.WriteLine( "{0}\tPast IP limit threshold\t{1}", e.State, DateTime.UtcNow );
return;
}
string un = e.Username;
string pw = e.Password;
Account acct = Accounts.GetAccount( un ) as Account;
if ( acct == null )
{
e.Accepted = false;
}
else if ( !acct.HasAccess( e.State ) )
{
Console.WriteLine( "Login: {0}: Access denied for '{1}'", e.State, un );
e.Accepted = false;
}
else if ( !acct.CheckPassword( pw ) )
{
Console.WriteLine( "Login: {0}: Invalid password for '{1}'", e.State, un );
e.Accepted = false;
}
else if ( acct.Banned )
{
Console.WriteLine( "Login: {0}: Banned account '{1}'", e.State, un );
e.Accepted = false;
}
else
{
acct.LogAccess( e.State );
Console.WriteLine( "Login: {0}: Account '{1}' at character list", e.State, un );
e.State.Account = acct;
e.Accepted = true;
e.CityInfo = StartingCities;
}
if ( !e.Accepted )
AccountAttackLimiter.RegisterInvalidAccess( e.State );
}
public static bool CheckAccount( Mobile mobCheck, Mobile accCheck )
{
if ( accCheck != null )
{
Account a = accCheck.Account as Account;
if ( a != null )
{
for ( int i = 0; i < a.Length; ++i )
{
if ( a[i] == mobCheck )
return true;
}
}
}
return false;
}
}
return false;
}
}
}

View file

@ -1,61 +1,50 @@
using System;
using System.Xml;
namespace Server.Accounting
{
public class AccountTag
{
private string m_Name, m_Value;
public class AccountTag
{
/// <summary>
/// Constructs a new AccountTag instance with a specific name and value.
/// </summary>
/// <param name="name">Initial name.</param>
/// <param name="value">Initial value.</param>
public AccountTag(string name, string value)
{
Name = name;
Value = value;
}
/// <summary>
/// Gets or sets the name of this tag.
/// </summary>
public string Name
{
get{ return m_Name; }
set{ m_Name = value; }
}
/// <summary>
/// Deserializes an AccountTag instance from an xml element.
/// </summary>
/// <param name="node">The XmlElement instance from which to deserialize.</param>
public AccountTag(XmlElement node)
{
Name = Utility.GetAttribute(node, "name", "empty");
Value = Utility.GetText(node, "");
}
/// <summary>
/// Gets or sets the value of this tag.
/// </summary>
public string Value
{
get{ return m_Value; }
set{ m_Value = value; }
}
/// <summary>
/// Gets or sets the name of this tag.
/// </summary>
public string Name{ get; set; }
/// <summary>
/// Constructs a new AccountTag instance with a specific name and value.
/// </summary>
/// <param name="name">Initial name.</param>
/// <param name="value">Initial value.</param>
public AccountTag( string name, string value )
{
m_Name = name;
m_Value = value;
}
/// <summary>
/// Gets or sets the value of this tag.
/// </summary>
public string Value{ get; set; }
/// <summary>
/// Deserializes an AccountTag instance from an xml element.
/// </summary>
/// <param name="node">The XmlElement instance from which to deserialize.</param>
public AccountTag( XmlElement node )
{
m_Name = Utility.GetAttribute( node, "name", "empty" );
m_Value = Utility.GetText( node, "" );
}
/// <summary>
/// Serializes this AccountTag instance to an XmlTextWriter.
/// </summary>
/// <param name="xml">The XmlTextWriter instance from which to serialize.</param>
public void Save( XmlTextWriter xml )
{
xml.WriteStartElement( "tag" );
xml.WriteAttributeString( "name", m_Name );
xml.WriteString( m_Value );
xml.WriteEndElement();
}
}
/// <summary>
/// Serializes this AccountTag instance to an XmlTextWriter.
/// </summary>
/// <param name="xml">The XmlTextWriter instance from which to serialize.</param>
public void Save(XmlTextWriter xml)
{
xml.WriteStartElement("tag");
xml.WriteAttributeString("name", Name);
xml.WriteString(Value);
xml.WriteEndElement();
}
}
}

View file

@ -1,104 +1,101 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Xml;
namespace Server.Accounting
{
public class Accounts
{
private static Dictionary<string, IAccount> m_Accounts = new Dictionary<string, IAccount>();
public class Accounts
{
private static Dictionary<string, IAccount> m_Accounts = new Dictionary<string, IAccount>();
public static void Configure()
{
EventSink.WorldLoad += new WorldLoadEventHandler( Load );
EventSink.WorldSave += new WorldSaveEventHandler( Save );
}
static Accounts()
{
}
static Accounts()
{
}
public static int Count => m_Accounts.Count;
public static int Count => m_Accounts.Count;
public static void Configure()
{
EventSink.WorldLoad += Load;
EventSink.WorldSave += Save;
}
public static ICollection<IAccount> GetAccounts()
{
return m_Accounts.Values;
}
public static ICollection<IAccount> GetAccounts()
{
return m_Accounts.Values;
}
public static IAccount GetAccount( string username )
{
m_Accounts.TryGetValue( username, out IAccount a );
public static IAccount GetAccount(string username)
{
m_Accounts.TryGetValue(username, out IAccount a);
return a;
}
return a;
}
public static void Add( IAccount a )
{
m_Accounts[a.Username] = a;
}
public static void Add(IAccount a)
{
m_Accounts[a.Username] = a;
}
public static void Remove( string username )
{
m_Accounts.Remove( username );
}
public static void Remove(string username)
{
m_Accounts.Remove(username);
}
public static void Load()
{
m_Accounts = new Dictionary<string, IAccount>( 32, StringComparer.OrdinalIgnoreCase );
public static void Load()
{
m_Accounts = new Dictionary<string, IAccount>(32, StringComparer.OrdinalIgnoreCase);
string filePath = Path.Combine( "Saves/Accounts", "accounts.xml" );
string filePath = Path.Combine("Saves/Accounts", "accounts.xml");
if ( !File.Exists( filePath ) )
return;
if (!File.Exists(filePath))
return;
XmlDocument doc = new XmlDocument();
doc.Load( filePath );
XmlDocument doc = new XmlDocument();
doc.Load(filePath);
XmlElement root = doc["accounts"];
XmlElement root = doc["accounts"];
foreach ( XmlElement account in root.GetElementsByTagName( "account" ) )
{
try
{
Account acct = new Account( account );
}
catch
{
Console.WriteLine( "Warning: Account instance load failed" );
}
}
}
foreach (XmlElement account in root.GetElementsByTagName("account"))
try
{
Account acct = new Account(account);
}
catch
{
Console.WriteLine("Warning: Account instance load failed");
}
}
public static void Save( WorldSaveEventArgs e )
{
if ( !Directory.Exists( "Saves/Accounts" ) )
Directory.CreateDirectory( "Saves/Accounts" );
public static void Save(WorldSaveEventArgs e)
{
if (!Directory.Exists("Saves/Accounts"))
Directory.CreateDirectory("Saves/Accounts");
string filePath = Path.Combine( "Saves/Accounts", "accounts.xml" );
string filePath = Path.Combine("Saves/Accounts", "accounts.xml");
using ( StreamWriter op = new StreamWriter( filePath ) )
{
XmlTextWriter xml = new XmlTextWriter( op );
using (StreamWriter op = new StreamWriter(filePath))
{
XmlTextWriter xml = new XmlTextWriter(op);
xml.Formatting = Formatting.Indented;
xml.IndentChar = '\t';
xml.Indentation = 1;
xml.Formatting = Formatting.Indented;
xml.IndentChar = '\t';
xml.Indentation = 1;
xml.WriteStartDocument( true );
xml.WriteStartDocument(true);
xml.WriteStartElement( "accounts" );
xml.WriteStartElement("accounts");
xml.WriteAttributeString( "count", m_Accounts.Count.ToString() );
xml.WriteAttributeString("count", m_Accounts.Count.ToString());
foreach ( Account a in GetAccounts() )
a.Save( xml );
foreach (Account a in GetAccounts())
a.Save(xml);
xml.WriteEndElement();
xml.WriteEndElement();
xml.Close();
}
}
}
}
xml.Close();
}
}
}
}

View file

@ -1,344 +1,303 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
namespace Server
{
public class Firewall
{
#region Firewall Entries
public interface IFirewallEntry
{
bool IsBlocked( IPAddress address );
}
public class IPFirewallEntry : IFirewallEntry
{
IPAddress m_Address;
public IPFirewallEntry( IPAddress address )
{
m_Address = address;
}
public bool IsBlocked( IPAddress address )
{
return m_Address.Equals( address );
}
public override string ToString()
{
return m_Address.ToString();
}
public override bool Equals( object obj )
{
if( obj is IPAddress )
{
return obj.Equals( m_Address );
}
else if( obj is string )
{
IPAddress otherAddress;
if( IPAddress.TryParse( (string)obj, out otherAddress ) )
return otherAddress.Equals( m_Address );
}
else if( obj is IPFirewallEntry )
{
return m_Address.Equals( ((IPFirewallEntry)obj).m_Address );
}
return false;
}
public override int GetHashCode()
{
return m_Address.GetHashCode();
}
}
public class CIDRFirewallEntry : IFirewallEntry
{
IPAddress m_CIDRPrefix;
int m_CIDRLength;
public CIDRFirewallEntry( IPAddress cidrPrefix, int cidrLength )
{
m_CIDRPrefix = cidrPrefix;
m_CIDRLength = cidrLength;
}
public bool IsBlocked( IPAddress address )
{
return Utility.IPMatchCIDR( m_CIDRPrefix, address, m_CIDRLength );
}
public override string ToString()
{
return String.Format( "{0}/{1}", m_CIDRPrefix, m_CIDRLength );
}
public override bool Equals( object obj )
{
if( obj is string )
{
string entry= (string)obj;
string[] str = entry.Split( '/' );
if( str.Length == 2 )
{
IPAddress cidrPrefix;
if( IPAddress.TryParse( str[0], out cidrPrefix ) )
{
int cidrLength;
if( int.TryParse( str[1], out cidrLength ) )
return m_CIDRPrefix.Equals( cidrPrefix ) && m_CIDRLength.Equals( cidrLength );
}
}
}
else if( obj is CIDRFirewallEntry )
{
CIDRFirewallEntry entry = obj as CIDRFirewallEntry;
return m_CIDRPrefix.Equals( entry.m_CIDRPrefix ) && m_CIDRLength.Equals( entry.m_CIDRLength );
}
return false;
}
public override int GetHashCode()
{
return m_CIDRPrefix.GetHashCode() ^ m_CIDRLength.GetHashCode();
}
}
public class WildcardIPFirewallEntry : IFirewallEntry
{
string m_Entry;
bool m_Valid = true;
public WildcardIPFirewallEntry( string entry )
{
m_Entry = entry;
}
public bool IsBlocked( IPAddress address )
{
if( !m_Valid )
return false; //Why process if it's invalid? it'll return false anyway after processing it.
return Utility.IPMatch( m_Entry, address, ref m_Valid );
}
public override string ToString()
{
return m_Entry.ToString();
}
public override bool Equals( object obj )
{
if( obj is string )
return obj.Equals( m_Entry );
else if( obj is WildcardIPFirewallEntry )
return m_Entry.Equals( ((WildcardIPFirewallEntry)obj).m_Entry );
return false;
}
public override int GetHashCode()
{
return m_Entry.GetHashCode();
}
}
#endregion
private static List<IFirewallEntry> m_Blocked;
static Firewall()
{
m_Blocked = new List<IFirewallEntry>();
string path = "firewall.cfg";
if ( File.Exists( path ) )
{
using ( StreamReader ip = new StreamReader( path ) )
{
string line;
while ( (line = ip.ReadLine()) != null )
{
line = line.Trim();
if ( line.Length == 0 )
continue;
m_Blocked.Add( ToFirewallEntry( line ) );
/*
object toAdd;
IPAddress addr;
if( IPAddress.TryParse( line, out addr ) )
toAdd = addr;
else
toAdd = line;
m_Blocked.Add( toAdd.ToString() );
* */
}
}
}
}
public static List<IFirewallEntry> List
{
get
{
return m_Blocked;
}
}
public static IFirewallEntry ToFirewallEntry( object entry )
{
if( entry is IFirewallEntry )
return (IFirewallEntry)entry;
else if( entry is IPAddress )
return new IPFirewallEntry( (IPAddress)entry );
else if( entry is string )
return ToFirewallEntry( (string)entry );
return null;
}
public static IFirewallEntry ToFirewallEntry( string entry )
{
IPAddress addr;
if( IPAddress.TryParse( entry, out addr ) )
return new IPFirewallEntry( addr );
//Try CIDR parse
string[] str = entry.Split( '/' );
if( str.Length == 2 )
{
IPAddress cidrPrefix;
if( IPAddress.TryParse( str[0], out cidrPrefix ) )
{
int cidrLength;
if( int.TryParse( str[1], out cidrLength ) )
return new CIDRFirewallEntry( cidrPrefix, cidrLength );
}
}
return new WildcardIPFirewallEntry( entry );
}
public static void RemoveAt( int index )
{
m_Blocked.RemoveAt( index );
Save();
}
public static void Remove( object obj )
{
IFirewallEntry entry = ToFirewallEntry( obj );
if( entry != null )
{
m_Blocked.Remove( entry );
Save();
}
}
public static void Add( object obj )
{
if( obj is IPAddress )
Add( (IPAddress)obj );
else if( obj is string )
Add( (string)obj );
else if( obj is IFirewallEntry )
Add( (IFirewallEntry)obj );
}
public static void Add( IFirewallEntry entry )
{
if( !m_Blocked.Contains( entry ) )
m_Blocked.Add( entry );
Save();
}
public static void Add( string pattern )
{
IFirewallEntry entry = ToFirewallEntry( pattern );
if( !m_Blocked.Contains( entry ) )
m_Blocked.Add( entry );
Save();
}
public static void Add( IPAddress ip )
{
IFirewallEntry entry = new IPFirewallEntry( ip );
if( !m_Blocked.Contains( entry ) )
m_Blocked.Add( entry );
Save();
}
public static void Save()
{
string path = "firewall.cfg";
using ( StreamWriter op = new StreamWriter( path ) )
{
for ( int i = 0; i < m_Blocked.Count; ++i )
op.WriteLine( m_Blocked[i] );
}
}
public static bool IsBlocked( IPAddress ip )
{
for( int i = 0; i < m_Blocked.Count; i++ )
{
if( m_Blocked[i].IsBlocked( ip ) )
return true;
}
return false;
/*
bool contains = false;
for ( int i = 0; !contains && i < m_Blocked.Count; ++i )
{
if ( m_Blocked[i] is IPAddress )
contains = ip.Equals( m_Blocked[i] );
public class Firewall
{
static Firewall()
{
List = new List<IFirewallEntry>();
string path = "firewall.cfg";
if (File.Exists(path))
using (StreamReader ip = new StreamReader(path))
{
string line;
while ((line = ip.ReadLine()) != null)
{
line = line.Trim();
if (line.Length == 0)
continue;
List.Add(ToFirewallEntry(line));
/*
object toAdd;
IPAddress addr;
if ( IPAddress.TryParse( line, out addr ) )
toAdd = addr;
else
toAdd = line;
m_Blocked.Add( toAdd.ToString() );
* */
}
}
}
public static List<IFirewallEntry> List{ get; }
public static IFirewallEntry ToFirewallEntry(object entry)
{
if (entry is IFirewallEntry firewallEntry)
return firewallEntry;
if (entry is IPAddress address)
return new IPFirewallEntry(address);
if (entry is string s)
return ToFirewallEntry(s);
return null;
}
public static IFirewallEntry ToFirewallEntry(string entry)
{
if (IPAddress.TryParse(entry, out IPAddress addr))
return new IPFirewallEntry(addr);
//Try CIDR parse
string[] str = entry.Split('/');
if (str.Length == 2)
if (IPAddress.TryParse(str[0], out IPAddress cidrPrefix))
if (int.TryParse(str[1], out int cidrLength))
return new CIDRFirewallEntry(cidrPrefix, cidrLength);
return new WildcardIPFirewallEntry(entry);
}
public static void RemoveAt(int index)
{
List.RemoveAt(index);
Save();
}
public static void Remove(object obj)
{
IFirewallEntry entry = ToFirewallEntry(obj);
if (entry != null)
{
List.Remove(entry);
Save();
}
}
public static void Add(object obj)
{
if (obj is IPAddress address)
Add(address);
else if (obj is string s)
Add(s);
else if (obj is IFirewallEntry entry)
Add(entry);
}
public static void Add(IFirewallEntry entry)
{
if (!List.Contains(entry))
List.Add(entry);
Save();
}
public static void Add(string pattern)
{
IFirewallEntry entry = ToFirewallEntry(pattern);
if (!List.Contains(entry))
List.Add(entry);
Save();
}
public static void Add(IPAddress ip)
{
IFirewallEntry entry = new IPFirewallEntry(ip);
if (!List.Contains(entry))
List.Add(entry);
Save();
}
public static void Save()
{
string path = "firewall.cfg";
using (StreamWriter op = new StreamWriter(path))
{
for (int i = 0; i < List.Count; ++i)
op.WriteLine(List[i]);
}
}
public static bool IsBlocked(IPAddress ip)
{
for (int i = 0; i < List.Count; i++)
if (List[i].IsBlocked(ip))
return true;
return false;
/*
bool contains = false;
for ( int i = 0; !contains && i < m_Blocked.Count; ++i )
{
if ( m_Blocked[i] is IPAddress )
contains = ip.Equals( m_Blocked[i] );
else if ( m_Blocked[i] is String )
{
string s = (string)m_Blocked[i];
contains = Utility.IPMatchCIDR( s, ip );
if( !contains )
if ( !contains )
contains = Utility.IPMatch( s, ip );
}
}
}
return contains;
* */
}
}
return contains;
* */
}
#region Firewall Entries
public interface IFirewallEntry
{
bool IsBlocked(IPAddress address);
}
public class IPFirewallEntry : IFirewallEntry
{
private IPAddress m_Address;
public IPFirewallEntry(IPAddress address)
{
m_Address = address;
}
public bool IsBlocked(IPAddress address)
{
return m_Address.Equals(address);
}
public override string ToString()
{
return m_Address.ToString();
}
public override bool Equals(object obj)
{
if (obj is IPAddress) return obj.Equals(m_Address);
if (obj is string s)
{
if (IPAddress.TryParse(s, out IPAddress otherAddress))
return otherAddress.Equals(m_Address);
}
else if (obj is IPFirewallEntry entry)
{
return m_Address.Equals(entry.m_Address);
}
return false;
}
public override int GetHashCode()
{
return m_Address.GetHashCode();
}
}
public class CIDRFirewallEntry : IFirewallEntry
{
private int m_CIDRLength;
private IPAddress m_CIDRPrefix;
public CIDRFirewallEntry(IPAddress cidrPrefix, int cidrLength)
{
m_CIDRPrefix = cidrPrefix;
m_CIDRLength = cidrLength;
}
public bool IsBlocked(IPAddress address)
{
return Utility.IPMatchCIDR(m_CIDRPrefix, address, m_CIDRLength);
}
public override string ToString()
{
return $"{m_CIDRPrefix}/{m_CIDRLength}";
}
public override bool Equals(object obj)
{
if (obj is string entry)
{
string[] str = entry.Split('/');
if (str.Length == 2)
if (IPAddress.TryParse(str[0], out IPAddress cidrPrefix))
if (int.TryParse(str[1], out int cidrLength))
return m_CIDRPrefix.Equals(cidrPrefix) && m_CIDRLength.Equals(cidrLength);
}
else if (obj is CIDRFirewallEntry cidrEntry)
{
return m_CIDRPrefix.Equals(cidrEntry.m_CIDRPrefix) && m_CIDRLength.Equals(cidrEntry.m_CIDRLength);
}
return false;
}
public override int GetHashCode()
{
return m_CIDRPrefix.GetHashCode() ^ m_CIDRLength.GetHashCode();
}
}
public class WildcardIPFirewallEntry : IFirewallEntry
{
private string m_Entry;
private bool m_Valid = true;
public WildcardIPFirewallEntry(string entry)
{
m_Entry = entry;
}
public bool IsBlocked(IPAddress address)
{
if (!m_Valid)
return false; //Why process if it's invalid? it'll return false anyway after processing it.
return Utility.IPMatch(m_Entry, address, ref m_Valid);
}
public override string ToString()
{
return m_Entry;
}
public override bool Equals(object obj)
{
if (obj is string)
return obj.Equals(m_Entry);
return obj is WildcardIPFirewallEntry entry && m_Entry.Equals(entry.m_Entry);
}
public override int GetHashCode()
{
return m_Entry.GetHashCode();
}
}
#endregion
}
}

View file

@ -1,59 +1,53 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using Server;
using Server.Network;
namespace Server.Misc
{
public class IPLimiter
{
public static bool Enabled = true;
public static bool SocketBlock = true; // true to block at connection, false to block at login request
public class IPLimiter
{
public static bool Enabled = true;
public static bool SocketBlock = true; // true to block at connection, false to block at login request
public static int MaxAddresses = 10;
public static IPAddress[] Exemptions = new IPAddress[] //For hosting services where there are cases where IPs can be proxied
{
//IPAddress.Parse( "127.0.0.1" ),
};
public static int MaxAddresses = 10;
public static bool IsExempt( IPAddress ip )
{
for ( int i = 0; i < Exemptions.Length; i++ )
{
if ( ip.Equals( Exemptions[i] ) )
return true;
}
public static IPAddress[] Exemptions =
{
//IPAddress.Parse( "127.0.0.1" ),
};
return false;
}
public static bool IsExempt(IPAddress ip)
{
for (int i = 0; i < Exemptions.Length; i++)
if (ip.Equals(Exemptions[i]))
return true;
public static bool Verify( IPAddress ourAddress )
{
if ( !Enabled || IsExempt( ourAddress ) )
return true;
return false;
}
List<NetState> netStates = NetState.Instances;
public static bool Verify(IPAddress ourAddress)
{
if (!Enabled || IsExempt(ourAddress))
return true;
int count = 0;
List<NetState> netStates = NetState.Instances;
for ( int i = 0; i < netStates.Count; ++i )
{
NetState compState = netStates[i];
int count = 0;
if ( ourAddress.Equals( compState.Address ) )
{
++count;
for (int i = 0; i < netStates.Count; ++i)
{
NetState compState = netStates[i];
if ( count >= MaxAddresses )
return false;
}
}
if (ourAddress.Equals(compState.Address))
{
++count;
return true;
}
}
if (count >= MaxAddresses)
return false;
}
}
return true;
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -2,39 +2,33 @@ using System;
namespace Server
{
public class UsageAttribute : Attribute
{
private string m_Usage;
public class UsageAttribute : Attribute
{
public UsageAttribute(string usage)
{
Usage = usage;
}
public string Usage{ get{ return m_Usage; } }
public string Usage{ get; }
}
public UsageAttribute( string usage )
{
m_Usage = usage;
}
}
public class DescriptionAttribute : Attribute
{
public DescriptionAttribute(string description)
{
Description = description;
}
public class DescriptionAttribute : Attribute
{
private string m_Description;
public string Description{ get; }
}
public string Description{ get{ return m_Description; } }
public class AliasesAttribute : Attribute
{
public AliasesAttribute(params string[] aliases)
{
Aliases = aliases;
}
public DescriptionAttribute( string description )
{
m_Description = description;
}
}
public class AliasesAttribute : Attribute
{
private string[] m_Aliases;
public string[] Aliases{ get{ return m_Aliases; } }
public AliasesAttribute( params string[] aliases )
{
m_Aliases = aliases;
}
}
public string[] Aliases{ get; }
}
}

View file

@ -1,458 +1,423 @@
using System;
using System.Reflection;
using System.Collections;
using Server;
using System.Reflection;
using Server.Commands.Generic;
using Server.Gumps;
using Server.Network;
using Server.Commands;
using Server.Commands.Generic;
namespace Server.Commands
{
public class Batch : BaseCommand
{
private BaseCommandImplementor m_Scope;
private string m_Condition;
private ArrayList m_BatchCommands;
public BaseCommandImplementor Scope
{
get{ return m_Scope; }
set{ m_Scope = value; }
}
public string Condition
{
get{ return m_Condition; }
set{ m_Condition = value; }
}
public ArrayList BatchCommands
{
get{ return m_BatchCommands; }
}
public Batch()
{
Commands = new string[]{ "Batch" };
ListOptimized = true;
m_BatchCommands = new ArrayList();
m_Condition = "";
}
public override void ExecuteList( CommandEventArgs e, ArrayList list )
{
if ( list.Count == 0 )
{
LogFailure( "Nothing was found to use this command on." );
return;
}
try
{
BaseCommand[] commands = new BaseCommand[m_BatchCommands.Count];
CommandEventArgs[] eventArgs = new CommandEventArgs[m_BatchCommands.Count];
for ( int i = 0; i < m_BatchCommands.Count; ++i )
{
BatchCommand bc = (BatchCommand)m_BatchCommands[i];
string commandString, argString;
string[] args;
bc.GetDetails( out commandString, out argString, out args );
BaseCommand command = m_Scope.Commands[commandString];
commands[i] = command;
eventArgs[i] = new CommandEventArgs( e.Mobile, commandString, argString, args );
if ( command == null )
{
e.Mobile.SendMessage( "That is either an invalid command name or one that does not support this modifier: {0}.", commandString );
return;
}
else if ( e.Mobile.AccessLevel < command.AccessLevel )
{
e.Mobile.SendMessage( "You do not have access to that command: {0}.", commandString );
return;
}
else if ( !command.ValidateArgs( m_Scope, eventArgs[i] ) )
{
return;
}
}
for ( int i = 0; i < commands.Length; ++i )
{
BaseCommand command = commands[i];
BatchCommand bc = (BatchCommand)m_BatchCommands[i];
if ( list.Count > 20 )
CommandLogging.Enabled = false;
ArrayList usedList;
if ( Utility.InsensitiveCompare( bc.Object, "Current" ) == 0 )
{
usedList = list;
}
else
{
Hashtable propertyChains = new Hashtable();
usedList = new ArrayList( list.Count );
for ( int j = 0; j < list.Count; ++j )
{
object obj = list[j];
if ( obj == null )
continue;
Type type = obj.GetType();
PropertyInfo[] chain = (PropertyInfo[])propertyChains[type];
string failReason = "";
if ( chain == null && !propertyChains.Contains( type ) )
propertyChains[type] = chain = Properties.GetPropertyInfoChain( e.Mobile, type, bc.Object, PropertyAccess.Read, ref failReason );
if ( chain == null )
continue;
PropertyInfo endProp = Properties.GetPropertyInfo( ref obj, chain, ref failReason );
if ( endProp == null )
continue;
try
{
obj = endProp.GetValue( obj, null );
if ( obj != null )
usedList.Add( obj );
}
catch
{
}
}
}
command.ExecuteList( eventArgs[i], usedList );
if ( list.Count > 20 )
CommandLogging.Enabled = true;
command.Flush( e.Mobile, list.Count > 20 );
}
}
catch ( Exception ex )
{
e.Mobile.SendMessage( ex.Message );
}
}
public bool Run( Mobile from )
{
if ( m_Scope == null )
{
from.SendMessage( "You must select the batch command scope." );
return false;
}
else if ( m_Condition.Length > 0 && !m_Scope.SupportsConditionals )
{
from.SendMessage( "This command scope does not support conditionals." );
return false;
}
else if ( m_Condition.Length > 0 && !Utility.InsensitiveStartsWith( m_Condition, "where" ) )
{
from.SendMessage( "The condition field must start with \"where\"." );
return false;
}
string[] args = CommandSystem.Split( m_Condition );
m_Scope.Process( from, this, args );
return true;
}
public static void Initialize()
{
CommandSystem.Register( "Batch", AccessLevel.Counselor, new CommandEventHandler( Batch_OnCommand ) );
}
[Usage( "Batch" )]
[Description( "Allows multiple commands to be run at the same time." )]
public static void Batch_OnCommand( CommandEventArgs e )
{
Batch batch = new Batch();
e.Mobile.SendGump( new BatchGump( e.Mobile, batch ) );
}
}
public class BatchCommand
{
private string m_Command;
private string m_Object;
public string Command
{
get{ return m_Command; }
set{ m_Command = value; }
}
public string Object
{
get{ return m_Object; }
set{ m_Object = value; }
}
public void GetDetails( out string command, out string argString, out string[] args )
{
int indexOf = m_Command.IndexOf( ' ' );
if ( indexOf >= 0 )
{
argString = m_Command.Substring( indexOf + 1 );
command = m_Command.Substring( 0, indexOf );
args = CommandSystem.Split( argString );
}
else
{
argString = "";
command = m_Command.ToLower();
args = new string[0];
}
}
public BatchCommand( string command, string obj )
{
m_Command = command;
m_Object = obj;
}
}
public class BatchGump : BaseGridGump
{
private Mobile m_From;
private Batch m_Batch;
public BatchGump( Mobile from, Batch batch ) : base( 30, 30 )
{
m_From = from;
m_Batch = batch;
Render();
}
public void Render()
{
AddNewPage();
/* Header */
AddEntryHeader( 20 );
AddEntryHtml( 180, Center( "Batch Commands" ) );
AddEntryHeader( 20 );
AddNewLine();
AddEntryHeader( 9 );
AddEntryLabel( 191, "Run Batch" );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, GetButtonID( 1, 0, 0 ), ArrowRightWidth, ArrowRightHeight );
AddNewLine();
AddBlankLine();
/* Scope */
AddEntryHeader( 20 );
AddEntryHtml( 180, Center( "Scope" ) );
AddEntryHeader( 20 );
AddNewLine();
AddEntryHeader( 9 );
AddEntryLabel( 191, m_Batch.Scope == null ? "Select Scope" : m_Batch.Scope.Accessors[0] );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, GetButtonID( 1, 0, 1 ), ArrowRightWidth, ArrowRightHeight );
AddNewLine();
AddBlankLine();
/* Condition */
AddEntryHeader( 20 );
AddEntryHtml( 180, Center( "Condition" ) );
AddEntryHeader( 20 );
AddNewLine();
AddEntryHeader( 9 );
AddEntryText( 202, 0, m_Batch.Condition );
AddEntryHeader( 9 );
AddNewLine();
AddBlankLine();
/* Commands */
AddEntryHeader( 20 );
AddEntryHtml( 180, Center( "Commands" ) );
AddEntryHeader( 20 );
for ( int i = 0; i < m_Batch.BatchCommands.Count; ++i )
{
BatchCommand bc = (BatchCommand)m_Batch.BatchCommands[i];
AddNewLine();
AddImageTiled( CurrentX, CurrentY, 9, 2, 0x24A8 );
AddImageTiled( CurrentX, CurrentY + 2, 2, EntryHeight + OffsetSize + EntryHeight - 4, 0x24A8 );
AddImageTiled( CurrentX, CurrentY + EntryHeight + OffsetSize + EntryHeight - 2, 9, 2, 0x24A8 );
AddImageTiled( CurrentX + 3, CurrentY + 3, 6, EntryHeight + EntryHeight - 4 - OffsetSize, HeaderGumpID );
IncreaseX( 9 );
AddEntryText( 202, 1+(i*2), bc.Command );
AddEntryHeader( 9, 2 );
AddNewLine();
IncreaseX( 9 );
AddEntryText( 202, 2+(i*2), bc.Object );
}
AddNewLine();
AddEntryHeader( 9 );
AddEntryLabel( 191, "Add New Command" );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, GetButtonID( 1, 0, 2 ), ArrowRightWidth, ArrowRightHeight );
FinishPage();
}
public override void OnResponse( NetState sender, RelayInfo info )
{
int type, index;
if ( !SplitButtonID( info.ButtonID, 1, out type, out index ) )
return;
TextRelay entry = info.GetTextEntry( 0 );
if ( entry != null )
m_Batch.Condition = entry.Text;
for ( int i = m_Batch.BatchCommands.Count - 1; i >= 0; --i )
{
BatchCommand sc = (BatchCommand)m_Batch.BatchCommands[i];
entry = info.GetTextEntry( 1 + (i * 2) );
if ( entry != null )
sc.Command = entry.Text;
entry = info.GetTextEntry( 2 + (i * 2) );
if ( entry != null )
sc.Object = entry.Text;
if ( sc.Command.Length == 0 && sc.Object.Length == 0 )
m_Batch.BatchCommands.RemoveAt( i );
}
switch ( type )
{
case 0: // main
{
switch ( index )
{
case 0: // run
{
m_Batch.Run( m_From );
break;
}
case 1: // set scope
{
m_From.SendGump( new BatchScopeGump( m_From, m_Batch ) );
return;
}
case 2: // add command
{
m_Batch.BatchCommands.Add( new BatchCommand( "", "" ) );
break;
}
}
break;
}
}
m_From.SendGump( new BatchGump( m_From, m_Batch ) );
}
}
public class BatchScopeGump : BaseGridGump
{
private Mobile m_From;
private Batch m_Batch;
public BatchScopeGump( Mobile from, Batch batch ) : base( 30, 30 )
{
m_From = from;
m_Batch = batch;
Render();
}
public void Render()
{
AddNewPage();
/* Header */
AddEntryHeader( 20 );
AddEntryHtml( 140, Center( "Change Scope" ) );
AddEntryHeader( 20 );
/* Options */
for ( int i = 0; i < BaseCommandImplementor.Implementors.Count; ++i )
{
BaseCommandImplementor impl = BaseCommandImplementor.Implementors[i];
if ( m_From.AccessLevel < impl.AccessLevel )
continue;
AddNewLine();
AddEntryLabel( 20 + OffsetSize + 140, impl.Accessors[0] );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, GetButtonID( 1, 0, i ), ArrowRightWidth, ArrowRightHeight );
}
FinishPage();
}
public override void OnResponse( NetState sender, RelayInfo info )
{
int type, index;
if ( SplitButtonID( info.ButtonID, 1, out type, out index ) )
{
switch ( type )
{
case 0:
{
if ( index < BaseCommandImplementor.Implementors.Count )
{
BaseCommandImplementor impl = BaseCommandImplementor.Implementors[index];
if ( m_From.AccessLevel >= impl.AccessLevel )
m_Batch.Scope = impl;
}
break;
}
}
}
m_From.SendGump( new BatchGump( m_From, m_Batch ) );
}
}
}
public class Batch : BaseCommand
{
public Batch()
{
Commands = new[] { "Batch" };
ListOptimized = true;
BatchCommands = new ArrayList();
Condition = "";
}
public BaseCommandImplementor Scope{ get; set; }
public string Condition{ get; set; }
public ArrayList BatchCommands{ get; }
public override void ExecuteList(CommandEventArgs e, ArrayList list)
{
if (list.Count == 0)
{
LogFailure("Nothing was found to use this command on.");
return;
}
try
{
BaseCommand[] commands = new BaseCommand[BatchCommands.Count];
CommandEventArgs[] eventArgs = new CommandEventArgs[BatchCommands.Count];
for (int i = 0; i < BatchCommands.Count; ++i)
{
BatchCommand bc = (BatchCommand)BatchCommands[i];
bc.GetDetails(out string commandString, out string argString, out string[] args);
BaseCommand command = Scope.Commands[commandString];
commands[i] = command;
eventArgs[i] = new CommandEventArgs(e.Mobile, commandString, argString, args);
if (command == null)
{
e.Mobile.SendMessage(
"That is either an invalid command name or one that does not support this modifier: {0}.",
commandString);
return;
}
if (e.Mobile.AccessLevel < command.AccessLevel)
{
e.Mobile.SendMessage("You do not have access to that command: {0}.", commandString);
return;
}
if (!command.ValidateArgs(Scope, eventArgs[i])) return;
}
for (int i = 0; i < commands.Length; ++i)
{
BaseCommand command = commands[i];
BatchCommand bc = (BatchCommand)BatchCommands[i];
if (list.Count > 20)
CommandLogging.Enabled = false;
ArrayList usedList;
if (Utility.InsensitiveCompare(bc.Object, "Current") == 0)
{
usedList = list;
}
else
{
Hashtable propertyChains = new Hashtable();
usedList = new ArrayList(list.Count);
for (int j = 0; j < list.Count; ++j)
{
object obj = list[j];
if (obj == null)
continue;
Type type = obj.GetType();
PropertyInfo[] chain = (PropertyInfo[])propertyChains[type];
string failReason = "";
if (chain == null && !propertyChains.Contains(type))
propertyChains[type] = chain = Properties.GetPropertyInfoChain(e.Mobile, type, bc.Object,
PropertyAccess.Read, ref failReason);
if (chain == null)
continue;
PropertyInfo endProp = Properties.GetPropertyInfo(ref obj, chain, ref failReason);
if (endProp == null)
continue;
try
{
obj = endProp.GetValue(obj, null);
if (obj != null)
usedList.Add(obj);
}
catch
{
}
}
}
command.ExecuteList(eventArgs[i], usedList);
if (list.Count > 20)
CommandLogging.Enabled = true;
command.Flush(e.Mobile, list.Count > 20);
}
}
catch (Exception ex)
{
e.Mobile.SendMessage(ex.Message);
}
}
public bool Run(Mobile from)
{
if (Scope == null)
{
from.SendMessage("You must select the batch command scope.");
return false;
}
if (Condition.Length > 0 && !Scope.SupportsConditionals)
{
from.SendMessage("This command scope does not support conditionals.");
return false;
}
if (Condition.Length > 0 && !Utility.InsensitiveStartsWith(Condition, "where"))
{
from.SendMessage("The condition field must start with \"where\".");
return false;
}
string[] args = CommandSystem.Split(Condition);
Scope.Process(from, this, args);
return true;
}
public static void Initialize()
{
CommandSystem.Register("Batch", AccessLevel.Counselor, Batch_OnCommand);
}
[Usage("Batch")]
[Description("Allows multiple commands to be run at the same time.")]
public static void Batch_OnCommand(CommandEventArgs e)
{
e.Mobile.SendGump(new BatchGump(e.Mobile, new Batch()));
}
}
public class BatchCommand
{
public BatchCommand(string command, string obj)
{
Command = command;
Object = obj;
}
public string Command{ get; set; }
public string Object{ get; set; }
public void GetDetails(out string command, out string argString, out string[] args)
{
int indexOf = Command.IndexOf(' ');
if (indexOf >= 0)
{
argString = Command.Substring(indexOf + 1);
command = Command.Substring(0, indexOf);
args = CommandSystem.Split(argString);
}
else
{
argString = "";
command = Command.ToLower();
args = new string[0];
}
}
}
public class BatchGump : BaseGridGump
{
private Batch m_Batch;
private Mobile m_From;
public BatchGump(Mobile from, Batch batch) : base(30, 30)
{
m_From = from;
m_Batch = batch;
Render();
}
public void Render()
{
AddNewPage();
/* Header */
AddEntryHeader(20);
AddEntryHtml(180, Center("Batch Commands"));
AddEntryHeader(20);
AddNewLine();
AddEntryHeader(9);
AddEntryLabel(191, "Run Batch");
AddEntryButton(20, ArrowRightID1, ArrowRightID2, GetButtonID(1, 0, 0), ArrowRightWidth, ArrowRightHeight);
AddNewLine();
AddBlankLine();
/* Scope */
AddEntryHeader(20);
AddEntryHtml(180, Center("Scope"));
AddEntryHeader(20);
AddNewLine();
AddEntryHeader(9);
AddEntryLabel(191, m_Batch.Scope == null ? "Select Scope" : m_Batch.Scope.Accessors[0]);
AddEntryButton(20, ArrowRightID1, ArrowRightID2, GetButtonID(1, 0, 1), ArrowRightWidth, ArrowRightHeight);
AddNewLine();
AddBlankLine();
/* Condition */
AddEntryHeader(20);
AddEntryHtml(180, Center("Condition"));
AddEntryHeader(20);
AddNewLine();
AddEntryHeader(9);
AddEntryText(202, 0, m_Batch.Condition);
AddEntryHeader(9);
AddNewLine();
AddBlankLine();
/* Commands */
AddEntryHeader(20);
AddEntryHtml(180, Center("Commands"));
AddEntryHeader(20);
for (int i = 0; i < m_Batch.BatchCommands.Count; ++i)
{
BatchCommand bc = (BatchCommand)m_Batch.BatchCommands[i];
AddNewLine();
AddImageTiled(CurrentX, CurrentY, 9, 2, 0x24A8);
AddImageTiled(CurrentX, CurrentY + 2, 2, EntryHeight + OffsetSize + EntryHeight - 4, 0x24A8);
AddImageTiled(CurrentX, CurrentY + EntryHeight + OffsetSize + EntryHeight - 2, 9, 2, 0x24A8);
AddImageTiled(CurrentX + 3, CurrentY + 3, 6, EntryHeight + EntryHeight - 4 - OffsetSize, HeaderGumpID);
IncreaseX(9);
AddEntryText(202, 1 + i * 2, bc.Command);
AddEntryHeader(9, 2);
AddNewLine();
IncreaseX(9);
AddEntryText(202, 2 + i * 2, bc.Object);
}
AddNewLine();
AddEntryHeader(9);
AddEntryLabel(191, "Add New Command");
AddEntryButton(20, ArrowRightID1, ArrowRightID2, GetButtonID(1, 0, 2), ArrowRightWidth, ArrowRightHeight);
FinishPage();
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (!SplitButtonID(info.ButtonID, 1, out int type, out int index))
return;
TextRelay entry = info.GetTextEntry(0);
if (entry != null)
m_Batch.Condition = entry.Text;
for (int i = m_Batch.BatchCommands.Count - 1; i >= 0; --i)
{
BatchCommand sc = (BatchCommand)m_Batch.BatchCommands[i];
entry = info.GetTextEntry(1 + i * 2);
if (entry != null)
sc.Command = entry.Text;
entry = info.GetTextEntry(2 + i * 2);
if (entry != null)
sc.Object = entry.Text;
if (sc.Command.Length == 0 && sc.Object.Length == 0)
m_Batch.BatchCommands.RemoveAt(i);
}
switch (type)
{
case 0: // main
{
switch (index)
{
case 0: // run
{
m_Batch.Run(m_From);
break;
}
case 1: // set scope
{
m_From.SendGump(new BatchScopeGump(m_From, m_Batch));
return;
}
case 2: // add command
{
m_Batch.BatchCommands.Add(new BatchCommand("", ""));
break;
}
}
break;
}
}
m_From.SendGump(new BatchGump(m_From, m_Batch));
}
}
public class BatchScopeGump : BaseGridGump
{
private Batch m_Batch;
private Mobile m_From;
public BatchScopeGump(Mobile from, Batch batch) : base(30, 30)
{
m_From = from;
m_Batch = batch;
Render();
}
public void Render()
{
AddNewPage();
/* Header */
AddEntryHeader(20);
AddEntryHtml(140, Center("Change Scope"));
AddEntryHeader(20);
/* Options */
for (int i = 0; i < BaseCommandImplementor.Implementors.Count; ++i)
{
BaseCommandImplementor impl = BaseCommandImplementor.Implementors[i];
if (m_From.AccessLevel < impl.AccessLevel)
continue;
AddNewLine();
AddEntryLabel(20 + OffsetSize + 140, impl.Accessors[0]);
AddEntryButton(20, ArrowRightID1, ArrowRightID2, GetButtonID(1, 0, i), ArrowRightWidth, ArrowRightHeight);
}
FinishPage();
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (SplitButtonID(info.ButtonID, 1, out int type, out int index))
switch (type)
{
case 0:
{
if (index < BaseCommandImplementor.Implementors.Count)
{
BaseCommandImplementor impl = BaseCommandImplementor.Implementors[index];
if (m_From.AccessLevel >= impl.AccessLevel)
m_Batch.Scope = impl;
}
break;
}
}
m_From.SendGump(new BatchGump(m_From, m_Batch));
}
}
}

View file

@ -1,68 +1,66 @@
using System;
using Server;
using Server.Targeting;
namespace Server
{
public delegate void BoundingBoxCallback( Mobile from, Map map, Point3D start, Point3D end, object state );
public delegate void BoundingBoxCallback(Mobile from, Map map, Point3D start, Point3D end, object state);
public class BoundingBoxPicker
{
public static void Begin( Mobile from, BoundingBoxCallback callback, object state )
{
from.SendMessage( "Target the first location of the bounding box." );
from.Target = new PickTarget( callback, state );
}
public class BoundingBoxPicker
{
public static void Begin(Mobile from, BoundingBoxCallback callback, object state)
{
from.SendMessage("Target the first location of the bounding box.");
from.Target = new PickTarget(callback, state);
}
private class PickTarget : Target
{
private Point3D m_Store;
private bool m_First;
private Map m_Map;
private BoundingBoxCallback m_Callback;
private object m_State;
private class PickTarget : Target
{
private BoundingBoxCallback m_Callback;
private bool m_First;
private Map m_Map;
private object m_State;
private Point3D m_Store;
public PickTarget( BoundingBoxCallback callback, object state ) : this( Point3D.Zero, true, null, callback, state )
{
}
public PickTarget(BoundingBoxCallback callback, object state) : this(Point3D.Zero, true, null, callback, state)
{
}
public PickTarget( Point3D store, bool first, Map map, BoundingBoxCallback callback, object state ) : base( -1, true, TargetFlags.None )
{
m_Store = store;
m_First = first;
m_Map = map;
m_Callback = callback;
m_State = state;
}
public PickTarget(Point3D store, bool first, Map map, BoundingBoxCallback callback, object state) : base(-1,
true, TargetFlags.None)
{
m_Store = store;
m_First = first;
m_Map = map;
m_Callback = callback;
m_State = state;
}
protected override void OnTarget( Mobile from, object targeted )
{
IPoint3D p = targeted as IPoint3D;
protected override void OnTarget(Mobile from, object targeted)
{
if (!(targeted is IPoint3D p))
return;
if ( p == null )
return;
else if ( p is Item )
p = ((Item)p).GetWorldTop();
if (p is Item item)
p = item.GetWorldTop();
if ( m_First )
{
from.SendMessage( "Target another location to complete the bounding box." );
from.Target = new PickTarget( new Point3D( p ), false, from.Map, m_Callback, m_State );
}
else if ( from.Map != m_Map )
{
from.SendMessage( "Both locations must reside on the same map." );
}
else if ( m_Map != null && m_Map != Map.Internal && m_Callback != null )
{
Point3D start = m_Store;
Point3D end = new Point3D( p );
if (m_First)
{
from.SendMessage("Target another location to complete the bounding box.");
from.Target = new PickTarget(new Point3D(p), false, from.Map, m_Callback, m_State);
}
else if (from.Map != m_Map)
{
from.SendMessage("Both locations must reside on the same map.");
}
else if (m_Map != null && m_Map != Map.Internal && m_Callback != null)
{
Point3D start = m_Store;
Point3D end = new Point3D(p);
Utility.FixPoints( ref start, ref end );
Utility.FixPoints(ref start, ref end);
m_Callback( from, m_Map, start, end, m_State );
}
}
}
}
m_Callback(from, m_Map, start, end, m_State);
}
}
}
}
}

View file

@ -1,92 +1,87 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Network;
namespace Server.Commands
{
public class ConvertPlayers
{
public static void Initialize()
{
CommandSystem.Register( "ConvertPlayers", AccessLevel.Administrator, new CommandEventHandler( Convert_OnCommand ) );
}
public static void Convert_OnCommand( CommandEventArgs e )
{
e.Mobile.SendMessage( "Converting all players to PlayerMobile. You will be disconnected. Please Restart the server after the world has finished saving." );
List<Mobile> mobs = new List<Mobile>( World.Mobiles.Values );
int count = 0;
foreach ( Mobile m in mobs )
{
if ( m.Player && !(m is PlayerMobile ) )
{
count++;
if ( m.NetState != null )
m.NetState.Dispose();
PlayerMobile pm = new PlayerMobile( m.Serial );
pm.DefaultMobileInit();
List<Item> copy = new List<Item>( m.Items );
for (int i=0;i<copy.Count;i++)
pm.AddItem( copy[i] );
CopyProps( pm, m );
for (int i=0;i<m.Skills.Length;i++)
{
pm.Skills[i].Base = m.Skills[i].Base;
pm.Skills[i].SetLockNoRelay( m.Skills[i].Lock );
}
World.Mobiles[m.Serial] = pm;
}
}
if ( count > 0 )
{
NetState.ProcessDisposedQueue();
World.Save();
Console.WriteLine( "{0} players have been converted to PlayerMobile. {1}.", count, Core.Service ? "The server is now restarting" : "Press any key to restart the server" );
if ( !Core.Service )
Console.ReadKey( true );
public class ConvertPlayers
{
public static void Initialize()
{
CommandSystem.Register("ConvertPlayers", AccessLevel.Administrator, Convert_OnCommand);
}
Core.Kill( true );
}
else
{
e.Mobile.SendMessage( "Couldn't find any Players to convert." );
}
}
private static void CopyProps( Mobile to, Mobile from )
{
Type type = typeof( Mobile );
PropertyInfo[] props = type.GetProperties( BindingFlags.Public | BindingFlags.Instance );
for (int p=0;p<props.Length;p++)
{
PropertyInfo prop = props[p];
if ( prop.CanRead && prop.CanWrite )
{
try
{
prop.SetValue( to, prop.GetValue( from, null ), null );
}
catch
{
}
}
}
}
}
}
public static void Convert_OnCommand(CommandEventArgs e)
{
e.Mobile.SendMessage(
"Converting all players to PlayerMobile. You will be disconnected. Please Restart the server after the world has finished saving.");
List<Mobile> mobs = new List<Mobile>(World.Mobiles.Values);
int count = 0;
foreach (Mobile m in mobs)
if (m.Player && !(m is PlayerMobile))
{
count++;
m.NetState?.Dispose();
PlayerMobile pm = new PlayerMobile(m.Serial);
pm.DefaultMobileInit();
List<Item> copy = new List<Item>(m.Items);
for (int i = 0; i < copy.Count; i++)
pm.AddItem(copy[i]);
CopyProps(pm, m);
for (int i = 0; i < m.Skills.Length; i++)
{
pm.Skills[i].Base = m.Skills[i].Base;
pm.Skills[i].SetLockNoRelay(m.Skills[i].Lock);
}
World.Mobiles[m.Serial] = pm;
}
if (count > 0)
{
NetState.ProcessDisposedQueue();
World.Save();
Console.WriteLine("{0} players have been converted to PlayerMobile. {1}.", count,
Core.Service ? "The server is now restarting" : "Press any key to restart the server");
if (!Core.Service)
Console.ReadKey(true);
Core.Kill(true);
}
else
{
e.Mobile.SendMessage("Couldn't find any Players to convert.");
}
}
private static void CopyProps(Mobile to, Mobile from)
{
Type type = typeof(Mobile);
PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
for (int p = 0; p < props.Length; p++)
{
PropertyInfo prop = props[p];
if (prop.CanRead && prop.CanWrite)
try
{
prop.SetValue(to, prop.GetValue(from, null), null);
}
catch
{
}
}
}
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,29 +1,26 @@
using System;
using Server;
namespace Server.Commands
{
public static class DragEffects
{
public static void Initialize()
{
CommandSystem.Register( "DragEffects", AccessLevel.Developer, new CommandEventHandler( DragEffects_OnCommand ) );
}
public static class DragEffects
{
public static void Initialize()
{
CommandSystem.Register("DragEffects", AccessLevel.Developer, DragEffects_OnCommand);
}
[Usage( "DragEffects [enable=false]" )]
[Description( "Enables or disables the item drag and drop effects." )]
public static void DragEffects_OnCommand( CommandEventArgs e )
{
if ( e.Length == 0 )
{
e.Mobile.SendMessage( "Drag effects are currently {0}.", Mobile.DragEffects ? "enabled" : "disabled" );
}
else
{
Mobile.DragEffects = e.GetBoolean( 0 );
[Usage("DragEffects [enable=false]")]
[Description("Enables or disables the item drag and drop effects.")]
public static void DragEffects_OnCommand(CommandEventArgs e)
{
if (e.Length == 0)
{
e.Mobile.SendMessage("Drag effects are currently {0}.", Mobile.DragEffects ? "enabled" : "disabled");
}
else
{
Mobile.DragEffects = e.GetBoolean(0);
e.Mobile.SendMessage( "Drag effects have been {0}.", Mobile.DragEffects ? "enabled" : "disabled" );
}
}
}
}
e.Mobile.SendMessage("Drag effects have been {0}.", Mobile.DragEffects ? "enabled" : "disabled");
}
}
}
}

View file

@ -5,143 +5,131 @@ using Server.Targeting;
namespace Server.Commands
{
public class Dupe
{
public static void Initialize()
{
CommandSystem.Register( "Dupe", AccessLevel.GameMaster, new CommandEventHandler( Dupe_OnCommand ) );
CommandSystem.Register( "DupeInBag", AccessLevel.GameMaster, new CommandEventHandler( DupeInBag_OnCommand ) );
}
public class Dupe
{
public static void Initialize()
{
CommandSystem.Register("Dupe", AccessLevel.GameMaster, Dupe_OnCommand);
CommandSystem.Register("DupeInBag", AccessLevel.GameMaster, DupeInBag_OnCommand);
}
[Usage( "Dupe [amount]" )]
[Description( "Dupes a targeted item." )]
private static void Dupe_OnCommand( CommandEventArgs e )
{
int amount = 1;
if ( e.Length >= 1 )
amount = e.GetInt32( 0 );
e.Mobile.Target = new DupeTarget( false, amount > 0 ? amount : 1 );
e.Mobile.SendMessage( "What do you wish to dupe?" );
}
[Usage("Dupe [amount]")]
[Description("Dupes a targeted item.")]
private static void Dupe_OnCommand(CommandEventArgs e)
{
int amount = 1;
if (e.Length >= 1)
amount = e.GetInt32(0);
e.Mobile.Target = new DupeTarget(false, amount > 0 ? amount : 1);
e.Mobile.SendMessage("What do you wish to dupe?");
}
[Usage( "DupeInBag <count>" )]
[Description( "Dupes an item at it's current location (count) number of times." )]
private static void DupeInBag_OnCommand( CommandEventArgs e )
{
int amount = 1;
if ( e.Length >= 1 )
amount = e.GetInt32( 0 );
[Usage("DupeInBag <count>")]
[Description("Dupes an item at it's current location (count) number of times.")]
private static void DupeInBag_OnCommand(CommandEventArgs e)
{
int amount = 1;
if (e.Length >= 1)
amount = e.GetInt32(0);
e.Mobile.Target = new DupeTarget( true, amount > 0 ? amount : 1 );
e.Mobile.SendMessage( "What do you wish to dupe?" );
}
e.Mobile.Target = new DupeTarget(true, amount > 0 ? amount : 1);
e.Mobile.SendMessage("What do you wish to dupe?");
}
private class DupeTarget : Target
{
private bool m_InBag;
private int m_Amount;
public static void CopyProperties(Item dest, Item src)
{
PropertyInfo[] props = src.GetType().GetProperties();
public DupeTarget( bool inbag, int amount )
: base( 15, false, TargetFlags.None )
{
m_InBag = inbag;
m_Amount = amount;
}
for (int i = 0; i < props.Length; i++)
try
{
if (props[i].CanRead && props[i].CanWrite) props[i].SetValue(dest, props[i].GetValue(src, null), null);
}
catch
{
//Console.WriteLine( "Denied" );
}
}
protected override void OnTarget( Mobile from, object targ )
{
bool done = false;
if ( !( targ is Item ) )
{
from.SendMessage( "You can only dupe items." );
return;
}
private class DupeTarget : Target
{
private int m_Amount;
private bool m_InBag;
CommandLogging.WriteLine( from, "{0} {1} duping {2} (inBag={3}; amount={4})", from.AccessLevel, CommandLogging.Format( from ), CommandLogging.Format( targ ), m_InBag, m_Amount );
public DupeTarget(bool inbag, int amount)
: base(15, false, TargetFlags.None)
{
m_InBag = inbag;
m_Amount = amount;
}
Item copy = (Item)targ;
Container pack;
protected override void OnTarget(Mobile from, object targ)
{
bool done = false;
if (!(targ is Item))
{
from.SendMessage("You can only dupe items.");
return;
}
if ( m_InBag )
{
if ( copy.Parent is Container )
pack = (Container)copy.Parent;
else if ( copy.Parent is Mobile )
pack = ( (Mobile)copy.Parent ).Backpack;
else
pack = null;
}
else
pack = from.Backpack;
CommandLogging.WriteLine(from, "{0} {1} duping {2} (inBag={3}; amount={4})", from.AccessLevel,
CommandLogging.Format(from), CommandLogging.Format(targ), m_InBag, m_Amount);
Type t = copy.GetType();
Item copy = (Item)targ;
Container pack = null;
//ConstructorInfo[] info = t.GetConstructors();
if (m_InBag)
{
if (copy.Parent is Container cont)
pack = cont;
else if (copy.Parent is Mobile m)
pack = m.Backpack;
}
else
{
pack = from.Backpack;
}
ConstructorInfo c = t.GetConstructor( Type.EmptyTypes );
Type t = copy.GetType();
if ( c != null )
{
try
{
from.SendMessage( "Duping {0}...", m_Amount );
for ( int i = 0; i < m_Amount; i++ )
{
object o = c.Invoke( null );
//ConstructorInfo[] info = t.GetConstructors();
if ( o != null && o is Item )
{
Item newItem = (Item)o;
CopyProperties( newItem, copy );//copy.Dupe( item, copy.Amount );
copy.OnAfterDuped( newItem );
newItem.Parent = null;
ConstructorInfo c = t.GetConstructor(Type.EmptyTypes);
if ( pack != null )
pack.DropItem( newItem );
else
newItem.MoveToWorld( from.Location, from.Map );
if (c != null)
try
{
from.SendMessage("Duping {0}...", m_Amount);
for (int i = 0; i < m_Amount; i++)
if (c.Invoke(null) is Item newItem)
{
CopyProperties(newItem, copy); //copy.Dupe( item, copy.Amount );
copy.OnAfterDuped(newItem);
newItem.Parent = null;
newItem.InvalidateProperties();
if (pack != null)
pack.DropItem(newItem);
else
newItem.MoveToWorld(from.Location, from.Map);
CommandLogging.WriteLine( from, "{0} {1} duped {2} creating {3}", from.AccessLevel, CommandLogging.Format( from ), CommandLogging.Format( targ ), CommandLogging.Format( newItem ) );
}
}
from.SendMessage( "Done" );
done = true;
}
catch
{
from.SendMessage( "Error!" );
return;
}
}
newItem.InvalidateProperties();
if ( !done )
{
from.SendMessage( "Unable to dupe. Item must have a 0 parameter constructor." );
}
}
}
CommandLogging.WriteLine(from, "{0} {1} duped {2} creating {3}", from.AccessLevel,
CommandLogging.Format(from), CommandLogging.Format(targ),
CommandLogging.Format(newItem));
}
public static void CopyProperties( Item dest, Item src )
{
PropertyInfo[] props = src.GetType().GetProperties();
from.SendMessage("Done");
done = true;
}
catch
{
from.SendMessage("Error!");
return;
}
for ( int i = 0; i < props.Length; i++ )
{
try
{
if ( props[i].CanRead && props[i].CanWrite )
{
//Console.WriteLine( "Setting {0} = {1}", props[i].Name, props[i].GetValue( src, null ) );
props[i].SetValue( dest, props[i].GetValue( src, null ), null );
}
}
catch
{
//Console.WriteLine( "Denied" );
}
}
}
}
}
if (!done) from.SendMessage("Unable to dupe. Item must have a 0 parameter constructor.");
}
}
}
}

View file

@ -1,68 +1,64 @@
using System;
using System.Collections;
using System.IO;
using Server;
using Server.Items;
namespace Server.Commands
{
public class ExportCommand
{
private const string ExportFile = @"C:\Uo\WorldForge\items.wsc";
public class ExportCommand
{
private const string ExportFile = @"C:\Uo\WorldForge\items.wsc";
public static void Initialize()
{
CommandSystem.Register( "ExportWSC", AccessLevel.Administrator, new CommandEventHandler( Export_OnCommand ) );
}
public static void Initialize()
{
CommandSystem.Register("ExportWSC", AccessLevel.Administrator, Export_OnCommand);
}
public static void Export_OnCommand( CommandEventArgs e )
{
StreamWriter w = new StreamWriter( ExportFile );
ArrayList remove = new ArrayList();
int count = 0;
public static void Export_OnCommand(CommandEventArgs e)
{
StreamWriter w = new StreamWriter(ExportFile);
ArrayList remove = new ArrayList();
int count = 0;
e.Mobile.SendMessage( "Exporting all static items to \"{0}\"...", ExportFile );
e.Mobile.SendMessage( "This will delete all static items in the world. Please make a backup." );
e.Mobile.SendMessage("Exporting all static items to \"{0}\"...", ExportFile);
e.Mobile.SendMessage("This will delete all static items in the world. Please make a backup.");
foreach ( Item item in World.Items.Values )
{
if ( ( item is Static || item is BaseFloor || item is BaseWall )
&& item.RootParent == null )
{
w.WriteLine( "SECTION WORLDITEM {0}", count );
w.WriteLine( "{" );
w.WriteLine( "SERIAL {0}", item.Serial );
w.WriteLine( "NAME #" );
w.WriteLine( "NAME2 #" );
w.WriteLine( "ID {0}", item.ItemID );
w.WriteLine( "X {0}", item.X );
w.WriteLine( "Y {0}", item.Y );
w.WriteLine( "Z {0}", item.Z );
w.WriteLine( "COLOR {0}", item.Hue );
w.WriteLine( "CONT -1" );
w.WriteLine( "TYPE 0" );
w.WriteLine( "AMOUNT 1" );
w.WriteLine( "WEIGHT 255" );
w.WriteLine( "OWNER -1" );
w.WriteLine( "SPAWN -1" );
w.WriteLine( "VALUE 1" );
w.WriteLine( "}" );
w.WriteLine( "" );
foreach (Item item in World.Items.Values)
if ((item is Static || item is BaseFloor || item is BaseWall)
&& item.RootParent == null)
{
w.WriteLine("SECTION WORLDITEM {0}", count);
w.WriteLine("{");
w.WriteLine("SERIAL {0}", item.Serial);
w.WriteLine("NAME #");
w.WriteLine("NAME2 #");
w.WriteLine("ID {0}", item.ItemID);
w.WriteLine("X {0}", item.X);
w.WriteLine("Y {0}", item.Y);
w.WriteLine("Z {0}", item.Z);
w.WriteLine("COLOR {0}", item.Hue);
w.WriteLine("CONT -1");
w.WriteLine("TYPE 0");
w.WriteLine("AMOUNT 1");
w.WriteLine("WEIGHT 255");
w.WriteLine("OWNER -1");
w.WriteLine("SPAWN -1");
w.WriteLine("VALUE 1");
w.WriteLine("}");
w.WriteLine("");
count++;
remove.Add( item );
w.Flush();
}
}
count++;
remove.Add(item);
w.Flush();
}
w.Close();
w.Close();
foreach( Item item in remove )
item.Delete();
foreach (Item item in remove)
item.Delete();
e.Mobile.SendMessage( "Export complete. Exported {0} statics.", count );
}
}
e.Mobile.SendMessage("Export complete. Exported {0} statics.", count);
}
}
}
/*SECTION WORLDITEM 1
{
@ -80,4 +76,4 @@ WEIGHT 25500
OWNER -1
SPAWN -1
VALUE 1
}*/
}*/

View file

@ -1,426 +1,410 @@
using System;
using System.IO;
using System.Xml;
using System.Collections;
using System.IO;
using System.Reflection;
using Server;
using System.Text;
using System.Xml;
using Server.Items;
namespace Server.Commands
{
public class Categorization
{
private static CategoryEntry m_RootItems, m_RootMobiles;
public class Categorization
{
private static CategoryEntry m_RootItems, m_RootMobiles;
public static CategoryEntry Items
{
get
{
if ( m_RootItems == null )
Load();
private static Type typeofItem = typeof(Item);
private static Type typeofMobile = typeof(Mobile);
private static Type typeofConstructible = typeof(ConstructibleAttribute);
return m_RootItems;
}
}
public static CategoryEntry Items
{
get
{
if (m_RootItems == null)
Load();
public static CategoryEntry Mobiles
{
get
{
if ( m_RootMobiles == null )
Load();
return m_RootItems;
}
}
return m_RootMobiles;
}
}
public static CategoryEntry Mobiles
{
get
{
if (m_RootMobiles == null)
Load();
public static void Initialize()
{
CommandSystem.Register( "RebuildCategorization", AccessLevel.Administrator, new CommandEventHandler( RebuildCategorization_OnCommand ) );
}
return m_RootMobiles;
}
}
[Usage( "RebuildCategorization" )]
[Description( "Rebuilds the categorization data file used by the Add command." )]
public static void RebuildCategorization_OnCommand( CommandEventArgs e )
{
CategoryEntry root = new CategoryEntry( null, "Add Menu", new CategoryEntry[]{ Items, Mobiles } );
public static void Initialize()
{
CommandSystem.Register("RebuildCategorization", AccessLevel.Administrator, RebuildCategorization_OnCommand);
}
Export( root, "Data/objects.xml", "Objects" );
[Usage("RebuildCategorization")]
[Description("Rebuilds the categorization data file used by the Add command.")]
public static void RebuildCategorization_OnCommand(CommandEventArgs e)
{
CategoryEntry root = new CategoryEntry(null, "Add Menu", new[] { Items, Mobiles });
e.Mobile.SendMessage( "Categorization menu rebuilt." );
}
Export(root, "Data/objects.xml", "Objects");
public static void RecurseFindCategories( CategoryEntry ce, ArrayList list )
{
list.Add( ce );
e.Mobile.SendMessage("Categorization menu rebuilt.");
}
for ( int i = 0; i < ce.SubCategories.Length; ++i )
RecurseFindCategories( ce.SubCategories[i], list );
}
public static void RecurseFindCategories(CategoryEntry ce, ArrayList list)
{
list.Add(ce);
public static void Export( CategoryEntry ce, string fileName, string title )
{
XmlTextWriter xml = new XmlTextWriter( fileName, System.Text.Encoding.UTF8 );
for (int i = 0; i < ce.SubCategories.Length; ++i)
RecurseFindCategories(ce.SubCategories[i], list);
}
xml.Indentation = 1;
xml.IndentChar = '\t';
xml.Formatting = Formatting.Indented;
public static void Export(CategoryEntry ce, string fileName, string title)
{
XmlTextWriter xml = new XmlTextWriter(fileName, Encoding.UTF8);
xml.WriteStartDocument( true );
xml.Indentation = 1;
xml.IndentChar = '\t';
xml.Formatting = Formatting.Indented;
RecurseExport( xml, ce );
xml.WriteStartDocument(true);
xml.Flush();
xml.Close();
}
RecurseExport(xml, ce);
public static void RecurseExport( XmlTextWriter xml, CategoryEntry ce )
{
xml.WriteStartElement( "category" );
xml.Flush();
xml.Close();
}
xml.WriteAttributeString( "title", ce.Title );
public static void RecurseExport(XmlTextWriter xml, CategoryEntry ce)
{
xml.WriteStartElement("category");
ArrayList subCats = new ArrayList( ce.SubCategories );
xml.WriteAttributeString("title", ce.Title);
subCats.Sort( new CategorySorter() );
ArrayList subCats = new ArrayList(ce.SubCategories);
for ( int i = 0; i < subCats.Count; ++i )
RecurseExport( xml, (CategoryEntry)subCats[i] );
subCats.Sort(new CategorySorter());
ce.Matched.Sort( new CategorySorter() );
for (int i = 0; i < subCats.Count; ++i)
RecurseExport(xml, (CategoryEntry)subCats[i]);
for ( int i = 0; i < ce.Matched.Count; ++i )
{
CategoryTypeEntry cte = (CategoryTypeEntry)ce.Matched[i];
ce.Matched.Sort(new CategorySorter());
xml.WriteStartElement( "object" );
for (int i = 0; i < ce.Matched.Count; ++i)
{
CategoryTypeEntry cte = (CategoryTypeEntry)ce.Matched[i];
xml.WriteAttributeString( "type", cte.Type.ToString() );
xml.WriteStartElement("object");
object obj = cte.Object;
xml.WriteAttributeString("type", cte.Type.ToString());
if ( obj is Item )
{
Item item = (Item)obj;
if (cte.Object is Item item)
{
int itemID = item.ItemID;
int itemID = item.ItemID;
if (item is BaseAddon addon && addon.Components.Count == 1)
itemID = addon.Components[0].ItemID;
if ( item is BaseAddon && ((BaseAddon)item).Components.Count == 1 )
itemID = ((AddonComponent)(((BaseAddon)item).Components[0])).ItemID;
if (itemID > TileData.MaxItemValue)
itemID = 1;
if ( itemID > TileData.MaxItemValue )
itemID = 1;
xml.WriteAttributeString("gfx", XmlConvert.ToString(itemID));
xml.WriteAttributeString( "gfx", XmlConvert.ToString( itemID ) );
int hue = item.Hue & 0x7FFF;
int hue = item.Hue & 0x7FFF;
if ((hue & 0x4000) != 0)
hue = 0;
if ( (hue & 0x4000) != 0 )
hue = 0;
if (hue != 0)
xml.WriteAttributeString("hue", XmlConvert.ToString(hue));
if ( hue != 0 )
xml.WriteAttributeString( "hue", XmlConvert.ToString( hue ) );
item.Delete();
}
else if (cte.Object is Mobile mob)
{
int itemID = ShrinkTable.Lookup(mob, 1);
item.Delete();
}
else if ( obj is Mobile )
{
Mobile mob = (Mobile)obj;
xml.WriteAttributeString("gfx", XmlConvert.ToString(itemID));
int itemID = ShrinkTable.Lookup( mob, 1 );
int hue = mob.Hue & 0x7FFF;
xml.WriteAttributeString( "gfx", XmlConvert.ToString( itemID ) );
if ((hue & 0x4000) != 0)
hue = 0;
int hue = mob.Hue & 0x7FFF;
if (hue != 0)
xml.WriteAttributeString("hue", XmlConvert.ToString(hue));
if ( (hue & 0x4000) != 0 )
hue = 0;
mob.Delete();
}
if ( hue != 0 )
xml.WriteAttributeString( "hue", XmlConvert.ToString( hue ) );
xml.WriteEndElement();
}
mob.Delete();
}
xml.WriteEndElement();
}
xml.WriteEndElement();
}
public static void Load()
{
ArrayList types = new ArrayList();
xml.WriteEndElement();
}
AddTypes(Core.Assembly, types);
public static void Load()
{
ArrayList types = new ArrayList();
for (int i = 0; i < ScriptCompiler.Assemblies.Length; ++i)
AddTypes(ScriptCompiler.Assemblies[i], types);
AddTypes( Core.Assembly, types );
m_RootItems = Load(types, "Data/items.cfg");
m_RootMobiles = Load(types, "Data/mobiles.cfg");
}
for ( int i = 0; i < ScriptCompiler.Assemblies.Length; ++i )
AddTypes( ScriptCompiler.Assemblies[i], types );
private static CategoryEntry Load(ArrayList types, string config)
{
CategoryLine[] lines = CategoryLine.Load(config);
m_RootItems = Load( types, "Data/items.cfg" );
m_RootMobiles = Load( types, "Data/mobiles.cfg" );
}
if (lines.Length > 0)
{
int index = 0;
CategoryEntry root = new CategoryEntry(null, lines, ref index);
private static CategoryEntry Load( ArrayList types, string config )
{
CategoryLine[] lines = CategoryLine.Load( config );
Fill(root, types);
if ( lines.Length > 0 )
{
int index = 0;
CategoryEntry root = new CategoryEntry( null, lines, ref index );
return root;
}
Fill( root, types );
return new CategoryEntry();
}
return root;
}
private static bool IsConstructible(Type type)
{
if (!type.IsSubclassOf(typeofItem) && !type.IsSubclassOf(typeofMobile))
return false;
return new CategoryEntry();
}
ConstructorInfo ctor = type.GetConstructor(Type.EmptyTypes);
private static Type typeofItem = typeof( Item );
private static Type typeofMobile = typeof( Mobile );
private static Type typeofConstructible = typeof( ConstructibleAttribute );
return ctor != null && ctor.IsDefined(typeofConstructible, false);
}
private static bool IsConstructible( Type type )
{
if ( !type.IsSubclassOf( typeofItem ) && !type.IsSubclassOf( typeofMobile ) )
return false;
private static void AddTypes(Assembly asm, ArrayList types)
{
Type[] allTypes = asm.GetTypes();
ConstructorInfo ctor = type.GetConstructor( Type.EmptyTypes );
for (int i = 0; i < allTypes.Length; ++i)
{
Type type = allTypes[i];
return ( ctor != null && ctor.IsDefined( typeofConstructible, false ) );
}
if (type.IsAbstract)
continue;
private static void AddTypes( Assembly asm, ArrayList types )
{
Type[] allTypes = asm.GetTypes();
if (IsConstructible(type))
types.Add(type);
}
}
for ( int i = 0; i < allTypes.Length; ++i )
{
Type type = allTypes[i];
private static void Fill(CategoryEntry root, ArrayList list)
{
for (int i = 0; i < list.Count; ++i)
{
Type type = (Type)list[i];
CategoryEntry match = GetDeepestMatch(root, type);
if ( type.IsAbstract )
continue;
if (match == null)
continue;
if ( IsConstructible( type ) )
types.Add( type );
}
}
try
{
match.Matched.Add(new CategoryTypeEntry(type));
}
catch
{
}
}
}
private static void Fill( CategoryEntry root, ArrayList list )
{
for ( int i = 0; i < list.Count; ++i )
{
Type type = (Type)list[i];
CategoryEntry match = GetDeepestMatch( root, type );
if ( match == null )
continue;
try
{
match.Matched.Add( new CategoryTypeEntry( type ) );
}
catch
{
}
}
}
private static CategoryEntry GetDeepestMatch( CategoryEntry root, Type type )
{
if ( !root.IsMatch( type ) )
return null;
for ( int i = 0; i < root.SubCategories.Length; ++i )
{
CategoryEntry check = GetDeepestMatch( root.SubCategories[i], type );
if ( check != null )
return check;
}
return root;
}
}
public class CategorySorter : IComparer
{
public int Compare( object x, object y )
{
string a = null, b = null;
if ( x is CategoryEntry )
a = ((CategoryEntry)x).Title;
else if ( x is CategoryTypeEntry )
a = ((CategoryTypeEntry)x).Type.Name;
if ( y is CategoryEntry )
b = ((CategoryEntry)y).Title;
else if ( y is CategoryTypeEntry )
b = ((CategoryTypeEntry)y).Type.Name;
if ( a == null && b == null )
return 0;
if ( a == null )
return 1;
if ( b == null )
return -1;
private static CategoryEntry GetDeepestMatch(CategoryEntry root, Type type)
{
if (!root.IsMatch(type))
return null;
return a.CompareTo( b );
}
}
public class CategoryTypeEntry
{
private Type m_Type;
private object m_Object;
public Type Type{ get{ return m_Type; } }
public object Object{ get{ return m_Object; } }
public CategoryTypeEntry( Type type )
{
m_Type = type;
m_Object = Activator.CreateInstance( type );
}
}
public class CategoryEntry
{
private string m_Title;
private Type[] m_Matches;
private CategoryEntry[] m_SubCategories;
private CategoryEntry m_Parent;
private ArrayList m_Matched;
public string Title{ get{ return m_Title; } }
public Type[] Matches{ get{ return m_Matches; } }
public CategoryEntry Parent{ get{ return m_Parent; } }
public CategoryEntry[] SubCategories{ get{ return m_SubCategories; } }
public ArrayList Matched{ get{ return m_Matched; } }
public CategoryEntry()
{
m_Title = "(empty)";
m_Matches = new Type[0];
m_SubCategories = new CategoryEntry[0];
m_Matched = new ArrayList();
}
public CategoryEntry( CategoryEntry parent, string title, CategoryEntry[] subCats )
{
m_Parent = parent;
m_Title = title;
m_SubCategories = subCats;
m_Matches = new Type[0];
m_Matched = new ArrayList();
}
public bool IsMatch( Type type )
{
bool isMatch = false;
for ( int i = 0; !isMatch && i < m_Matches.Length; ++i )
isMatch = ( type == m_Matches[i] || type.IsSubclassOf( m_Matches[i] ) );
return isMatch;
}
public CategoryEntry( CategoryEntry parent, CategoryLine[] lines, ref int index )
{
m_Parent = parent;
string text = lines[index].Text;
int start = text.IndexOf( '(' );
if ( start < 0 )
throw new FormatException( String.Format( "Input string not correctly formatted ('{0}')", text ) );
for (int i = 0; i < root.SubCategories.Length; ++i)
{
CategoryEntry check = GetDeepestMatch(root.SubCategories[i], type);
m_Title = text.Substring( 0, start ).Trim();
int end = text.IndexOf( ')', ++start );
if (check != null)
return check;
}
if ( end < start )
throw new FormatException( String.Format( "Input string not correctly formatted ('{0}')", text ) );
text = text.Substring( start, end-start );
string[] split = text.Split( ';' );
return root;
}
}
ArrayList list = new ArrayList();
public class CategorySorter : IComparer
{
public int Compare(object x, object y)
{
string a = null, b = null;
for ( int i = 0; i < split.Length; ++i )
{
Type type = ScriptCompiler.FindTypeByName( split[i].Trim() );
if (x is CategoryEntry entry)
a = entry.Title;
else if (x is CategoryTypeEntry xTypeEntry)
a = xTypeEntry.Type.Name;
if ( type == null )
Console.WriteLine( "Match type not found ('{0}')", split[i].Trim() );
else
list.Add( type );
}
if (y is CategoryEntry categoryEntry)
b = categoryEntry.Title;
else if (y is CategoryTypeEntry yTypeEntry)
b = yTypeEntry.Type.Name;
m_Matches = (Type[])list.ToArray( typeof( Type ) );
list.Clear();
if (a == null && b == null)
return 0;
int ourIndentation = lines[index].Indentation;
++index;
if (a == null)
return 1;
while ( index < lines.Length && lines[index].Indentation > ourIndentation )
list.Add( new CategoryEntry( this, lines, ref index ) );
if (b == null)
return -1;
m_SubCategories = (CategoryEntry[])list.ToArray( typeof( CategoryEntry ) );
list.Clear();
m_Matched = list;
}
}
public class CategoryLine
{
private int m_Indentation;
private string m_Text;
return a.CompareTo(b);
}
}
public int Indentation{ get{ return m_Indentation; } }
public string Text{ get{ return m_Text; } }
public class CategoryTypeEntry
{
public CategoryTypeEntry(Type type)
{
Type = type;
Object = Activator.CreateInstance(type);
}
public CategoryLine( string input )
{
int index;
public Type Type{ get; }
for ( index = 0; index < input.Length; ++index )
{
if ( Char.IsLetter( input, index ) )
break;
}
public object Object{ get; }
}
if ( index >= input.Length )
throw new FormatException( String.Format( "Input string not correctly formatted ('{0}')", input ) );
public class CategoryEntry
{
public CategoryEntry()
{
Title = "(empty)";
Matches = new Type[0];
SubCategories = new CategoryEntry[0];
Matched = new ArrayList();
}
m_Indentation = index;
m_Text = input.Substring( index );
}
public CategoryEntry(CategoryEntry parent, string title, CategoryEntry[] subCats)
{
Parent = parent;
Title = title;
SubCategories = subCats;
Matches = new Type[0];
Matched = new ArrayList();
}
public static CategoryLine[] Load( string path )
{
ArrayList list = new ArrayList();
public CategoryEntry(CategoryEntry parent, CategoryLine[] lines, ref int index)
{
Parent = parent;
if ( File.Exists( path ) )
{
using ( StreamReader ip = new StreamReader( path ) )
{
string line;
string text = lines[index].Text;
while ( (line = ip.ReadLine()) != null )
list.Add( new CategoryLine( line ) );
}
}
int start = text.IndexOf('(');
return (CategoryLine[])list.ToArray( typeof( CategoryLine ) );
}
}
if (start < 0)
throw new FormatException($"Input string not correctly formatted ('{text}')");
Title = text.Substring(0, start).Trim();
int end = text.IndexOf(')', ++start);
if (end < start)
throw new FormatException($"Input string not correctly formatted ('{text}')");
text = text.Substring(start, end - start);
string[] split = text.Split(';');
ArrayList list = new ArrayList();
for (int i = 0; i < split.Length; ++i)
{
Type type = ScriptCompiler.FindTypeByName(split[i].Trim());
if (type == null)
Console.WriteLine("Match type not found ('{0}')", split[i].Trim());
else
list.Add(type);
}
Matches = (Type[])list.ToArray(typeof(Type));
list.Clear();
int ourIndentation = lines[index].Indentation;
++index;
while (index < lines.Length && lines[index].Indentation > ourIndentation)
list.Add(new CategoryEntry(this, lines, ref index));
SubCategories = (CategoryEntry[])list.ToArray(typeof(CategoryEntry));
list.Clear();
Matched = list;
}
public string Title{ get; }
public Type[] Matches{ get; }
public CategoryEntry Parent{ get; }
public CategoryEntry[] SubCategories{ get; }
public ArrayList Matched{ get; }
public bool IsMatch(Type type)
{
bool isMatch = false;
for (int i = 0; !isMatch && i < Matches.Length; ++i)
isMatch = type == Matches[i] || type.IsSubclassOf(Matches[i]);
return isMatch;
}
}
public class CategoryLine
{
public CategoryLine(string input)
{
int index;
for (index = 0; index < input.Length; ++index)
if (char.IsLetter(input, index))
break;
if (index >= input.Length)
throw new FormatException($"Input string not correctly formatted ('{input}')");
Indentation = index;
Text = input.Substring(index);
}
public int Indentation{ get; }
public string Text{ get; }
public static CategoryLine[] Load(string path)
{
ArrayList list = new ArrayList();
if (File.Exists(path))
using (StreamReader ip = new StreamReader(path))
{
string line;
while ((line = ip.ReadLine()) != null)
list.Add(new CategoryLine(line));
}
return (CategoryLine[])list.ToArray(typeof(CategoryLine));
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,205 +1,158 @@
using System;
using System.Collections;
using Server;
using Server.Gumps;
namespace Server.Commands.Generic
{
public enum ObjectTypes
{
Both,
Items,
Mobiles,
All
}
public enum ObjectTypes
{
Both,
Items,
Mobiles,
All
}
public abstract class BaseCommand
{
private string[] m_Commands;
private AccessLevel m_AccessLevel;
private CommandSupport m_Implementors;
private ObjectTypes m_ObjectTypes;
private bool m_ListOptimized;
private string m_Usage;
private string m_Description;
public abstract class BaseCommand
{
private ArrayList m_Responses, m_Failures;
public bool ListOptimized
{
get{ return m_ListOptimized; }
set{ m_ListOptimized = value; }
}
public BaseCommand()
{
m_Responses = new ArrayList();
m_Failures = new ArrayList();
}
public string[] Commands
{
get{ return m_Commands; }
set{ m_Commands = value; }
}
public bool ListOptimized{ get; set; }
public string Usage
{
get{ return m_Usage; }
set{ m_Usage = value; }
}
public string[] Commands{ get; set; }
public string Description
{
get{ return m_Description; }
set{ m_Description = value; }
}
public string Usage{ get; set; }
public AccessLevel AccessLevel
{
get{ return m_AccessLevel; }
set{ m_AccessLevel = value; }
}
public string Description{ get; set; }
public ObjectTypes ObjectTypes
{
get{ return m_ObjectTypes; }
set{ m_ObjectTypes = value; }
}
public AccessLevel AccessLevel{ get; set; }
public CommandSupport Supports
{
get{ return m_Implementors; }
set{ m_Implementors = value; }
}
public ObjectTypes ObjectTypes{ get; set; }
public BaseCommand()
{
m_Responses = new ArrayList();
m_Failures = new ArrayList();
}
public CommandSupport Supports{ get; set; }
public static bool IsAccessible( Mobile from, object obj )
{
if ( from.AccessLevel >= AccessLevel.Administrator || obj == null )
return true;
public static bool IsAccessible(Mobile from, object obj)
{
if (from.AccessLevel >= AccessLevel.Administrator || obj == null)
return true;
Mobile mob;
Mobile mob = null;
if ( obj is Mobile )
mob = (Mobile)obj;
else if ( obj is Item )
mob = ((Item)obj).RootParent as Mobile;
else
mob = null;
if (obj is Mobile m)
mob = m;
else if (obj is Item item)
mob = item.RootParent as Mobile;
if ( mob == null || mob == from || from.AccessLevel > mob.AccessLevel )
return true;
return mob == null || mob == from || from.AccessLevel > mob.AccessLevel;
}
return false;
}
public virtual void ExecuteList(CommandEventArgs e, ArrayList list)
{
for (int i = 0; i < list.Count; ++i)
Execute(e, list[i]);
}
public virtual void ExecuteList( CommandEventArgs e, ArrayList list )
{
for ( int i = 0; i < list.Count; ++i )
Execute( e, list[i] );
}
public virtual void Execute(CommandEventArgs e, object obj)
{
}
public virtual void Execute( CommandEventArgs e, object obj )
{
}
public virtual bool ValidateArgs(BaseCommandImplementor impl, CommandEventArgs e)
{
return true;
}
public virtual bool ValidateArgs( BaseCommandImplementor impl, CommandEventArgs e )
{
return true;
}
public void AddResponse(string message)
{
for (int i = 0; i < m_Responses.Count; ++i)
{
MessageEntry entry = (MessageEntry)m_Responses[i];
private ArrayList m_Responses, m_Failures;
if (entry.m_Message == message)
{
++entry.m_Count;
return;
}
}
private class MessageEntry
{
public string m_Message;
public int m_Count;
if (m_Responses.Count == 10)
return;
public MessageEntry( string message )
{
m_Message = message;
m_Count = 1;
}
m_Responses.Add(new MessageEntry(message));
}
public override string ToString()
{
if ( m_Count > 1 )
return String.Format( "{0} ({1})", m_Message, m_Count );
public void AddResponse(Gump gump)
{
m_Responses.Add(gump);
}
return m_Message;
}
}
public void LogFailure(string message)
{
for (int i = 0; i < m_Failures.Count; ++i)
{
MessageEntry entry = (MessageEntry)m_Failures[i];
public void AddResponse( string message )
{
for ( int i = 0; i < m_Responses.Count; ++i )
{
MessageEntry entry = (MessageEntry)m_Responses[i];
if (entry.m_Message == message)
{
++entry.m_Count;
return;
}
}
if ( entry.m_Message == message )
{
++entry.m_Count;
return;
}
}
if (m_Failures.Count == 10)
return;
if ( m_Responses.Count == 10 )
return;
m_Failures.Add(new MessageEntry(message));
}
m_Responses.Add( new MessageEntry( message ) );
}
public void Flush(Mobile from, bool flushToLog)
{
if (m_Responses.Count > 0)
for (int i = 0; i < m_Responses.Count; ++i)
{
object obj = m_Responses[i];
public void AddResponse( Gump gump )
{
m_Responses.Add( gump );
}
if (obj is MessageEntry entry)
{
from.SendMessage(entry.ToString());
public void LogFailure( string message )
{
for ( int i = 0; i < m_Failures.Count; ++i )
{
MessageEntry entry = (MessageEntry)m_Failures[i];
if (flushToLog)
CommandLogging.WriteLine(from, entry.ToString());
}
else if (obj is Gump gump)
{
from.SendGump(gump);
}
}
else
for (int i = 0; i < m_Failures.Count; ++i)
from.SendMessage(((MessageEntry)m_Failures[i]).ToString());
if ( entry.m_Message == message )
{
++entry.m_Count;
return;
}
}
m_Responses.Clear();
m_Failures.Clear();
}
if ( m_Failures.Count == 10 )
return;
private class MessageEntry
{
public int m_Count;
public string m_Message;
m_Failures.Add( new MessageEntry( message ) );
}
public MessageEntry(string message)
{
m_Message = message;
m_Count = 1;
}
public void Flush( Mobile from, bool flushToLog )
{
if ( m_Responses.Count > 0 )
{
for ( int i = 0; i < m_Responses.Count; ++i )
{
object obj = m_Responses[i];
public override string ToString()
{
if (m_Count > 1)
return $"{m_Message} ({m_Count})";
if ( obj is MessageEntry )
{
from.SendMessage( ((MessageEntry)obj).ToString() );
if ( flushToLog )
CommandLogging.WriteLine( from, ((MessageEntry)obj).ToString() );
}
else if ( obj is Gump )
{
from.SendGump( (Gump) obj );
}
}
}
else
{
for ( int i = 0; i < m_Failures.Count; ++i )
from.SendMessage( ((MessageEntry)m_Failures[i]).ToString() );
}
m_Responses.Clear();
m_Failures.Clear();
}
}
return m_Message;
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Gumps;
using Server.Items;
using Server.Multis;
@ -9,197 +7,204 @@ using Server.Targeting;
namespace Server.Commands.Generic
{
public class DesignInsertCommand : BaseCommand
{
public static void Initialize()
{
TargetCommands.Register( new DesignInsertCommand() );
}
public class DesignInsertCommand : BaseCommand
{
public enum DesignInsertResult
{
Valid,
InvalidItem,
NotInHouse,
OutsideHouseBounds
}
public DesignInsertCommand()
{
AccessLevel = AccessLevel.GameMaster;
Supports = CommandSupport.Single | CommandSupport.Area;
Commands = new string[] { "DesignInsert" };
ObjectTypes = ObjectTypes.Items;
Usage = "DesignInsert [allItems=false]";
Description = "Inserts multiple targeted items into a customizable house's design.";
}
public DesignInsertCommand()
{
AccessLevel = AccessLevel.GameMaster;
Supports = CommandSupport.Single | CommandSupport.Area;
Commands = new[] { "DesignInsert" };
ObjectTypes = ObjectTypes.Items;
Usage = "DesignInsert [allItems=false]";
Description = "Inserts multiple targeted items into a customizable house's design.";
}
#region Single targeting mode
public override void Execute( CommandEventArgs e, object obj )
{
Target t = new DesignInsertTarget( new List<HouseFoundation>(), ( e.Length < 1 || !e.GetBoolean( 0 ) ) );
t.Invoke( e.Mobile, obj );
}
public static void Initialize()
{
TargetCommands.Register(new DesignInsertCommand());
}
private class DesignInsertTarget : Target
{
private List<HouseFoundation> m_Foundations;
private bool m_StaticsOnly;
public static DesignInsertResult ProcessInsert(Item item, bool staticsOnly, out HouseFoundation house)
{
house = null;
public DesignInsertTarget( List<HouseFoundation> foundations, bool staticsOnly )
: base( -1, false, TargetFlags.None )
{
m_Foundations = foundations;
m_StaticsOnly = staticsOnly;
}
if (item == null || item is BaseMulti || item is HouseSign || staticsOnly && !(item is Static))
return DesignInsertResult.InvalidItem;
protected override void OnTargetCancel( Mobile from, TargetCancelType cancelType )
{
if ( m_Foundations.Count != 0 )
{
from.SendMessage( "Your changes have been committed. Updating..." );
house = BaseHouse.FindHouseAt(item) as HouseFoundation;
foreach ( HouseFoundation house in m_Foundations )
house.Delta( ItemDelta.Update );
}
}
if (house == null)
return DesignInsertResult.NotInHouse;
protected override void OnTarget( Mobile from, object obj )
{
HouseFoundation house;
DesignInsertResult result = ProcessInsert( obj as Item, m_StaticsOnly, out house );
int x = item.X - house.X;
int y = item.Y - house.Y;
int z = item.Z - house.Z;
switch ( result )
{
case DesignInsertResult.Valid:
{
if ( m_Foundations.Count == 0 )
from.SendMessage( "The item has been inserted into the house design. Press ESC when you are finished." );
else
from.SendMessage( "The item has been inserted into the house design." );
if (!TryInsertIntoState(house.CurrentState, item.ItemID, x, y, z))
return DesignInsertResult.OutsideHouseBounds;
if ( !m_Foundations.Contains( house ) )
m_Foundations.Add( house );
TryInsertIntoState(house.DesignState, item.ItemID, x, y, z);
item.Delete();
break;
}
case DesignInsertResult.InvalidItem:
{
from.SendMessage( "That cannot be inserted. Try again." );
break;
}
case DesignInsertResult.NotInHouse:
case DesignInsertResult.OutsideHouseBounds:
{
from.SendMessage( "That item is not inside a customizable house. Try again." );
break;
}
}
return DesignInsertResult.Valid;
}
from.Target = new DesignInsertTarget( m_Foundations, m_StaticsOnly );
}
}
#endregion
private static bool TryInsertIntoState(DesignState state, int itemID, int x, int y, int z)
{
MultiComponentList mcl = state.Components;
#region Area targeting mode
public override void ExecuteList( CommandEventArgs e, ArrayList list )
{
e.Mobile.SendGump( new WarningGump( 1060637, 30720, String.Format( "You are about to insert {0} objects. This cannot be undone without a full server revert.<br><br>Continue?", list.Count ), 0xFFC000, 420, 280, new WarningGumpCallback( OnConfirmCallback ), new object[] { e, list, ( e.Length < 1 || !e.GetBoolean( 0 ) ) } ) );
AddResponse( "Awaiting confirmation..." );
}
if (x < mcl.Min.X || y < mcl.Min.Y || x > mcl.Max.X || y > mcl.Max.Y)
return false;
private void OnConfirmCallback( Mobile from, bool okay, object state )
{
object[] states = (object[])state;
CommandEventArgs e = (CommandEventArgs)states[0];
ArrayList list = (ArrayList)states[1];
bool staticsOnly = (bool)states[2];
mcl.Add(itemID, x, y, z);
state.OnRevised();
bool flushToLog = false;
return true;
}
if ( okay )
{
List<HouseFoundation> foundations = new List<HouseFoundation>();
flushToLog = ( list.Count > 20 );
#region Single targeting mode
for ( int i = 0; i < list.Count; ++i )
{
HouseFoundation house;
DesignInsertResult result = ProcessInsert( list[i] as Item, staticsOnly, out house );
public override void Execute(CommandEventArgs e, object obj)
{
Target t = new DesignInsertTarget(new List<HouseFoundation>(), e.Length < 1 || !e.GetBoolean(0));
t.Invoke(e.Mobile, obj);
}
switch ( result )
{
case DesignInsertResult.Valid:
{
AddResponse( "The item has been inserted into the house design." );
private class DesignInsertTarget : Target
{
private List<HouseFoundation> m_Foundations;
private bool m_StaticsOnly;
if ( !foundations.Contains( house ) )
foundations.Add( house );
public DesignInsertTarget(List<HouseFoundation> foundations, bool staticsOnly)
: base(-1, false, TargetFlags.None)
{
m_Foundations = foundations;
m_StaticsOnly = staticsOnly;
}
break;
}
case DesignInsertResult.InvalidItem:
{
LogFailure( "That cannot be inserted." );
break;
}
case DesignInsertResult.NotInHouse:
case DesignInsertResult.OutsideHouseBounds:
{
LogFailure( "That item is not inside a customizable house." );
break;
}
}
}
protected override void OnTargetCancel(Mobile from, TargetCancelType cancelType)
{
if (m_Foundations.Count != 0)
{
from.SendMessage("Your changes have been committed. Updating...");
foreach ( HouseFoundation house in foundations )
house.Delta( ItemDelta.Update );
}
else
{
AddResponse( "Command aborted." );
}
foreach (HouseFoundation house in m_Foundations)
house.Delta(ItemDelta.Update);
}
}
Flush( from, flushToLog );
}
#endregion
protected override void OnTarget(Mobile from, object obj)
{
HouseFoundation house;
DesignInsertResult result = ProcessInsert(obj as Item, m_StaticsOnly, out house);
public enum DesignInsertResult
{
Valid,
InvalidItem,
NotInHouse,
OutsideHouseBounds
}
switch (result)
{
case DesignInsertResult.Valid:
{
if (m_Foundations.Count == 0)
from.SendMessage(
"The item has been inserted into the house design. Press ESC when you are finished.");
else
from.SendMessage("The item has been inserted into the house design.");
public static DesignInsertResult ProcessInsert( Item item, bool staticsOnly, out HouseFoundation house )
{
house = null;
if (!m_Foundations.Contains(house))
m_Foundations.Add(house);
if ( item == null || item is BaseMulti || item is HouseSign || ( staticsOnly && !( item is Static ) ) )
return DesignInsertResult.InvalidItem;
break;
}
case DesignInsertResult.InvalidItem:
{
from.SendMessage("That cannot be inserted. Try again.");
break;
}
case DesignInsertResult.NotInHouse:
case DesignInsertResult.OutsideHouseBounds:
{
from.SendMessage("That item is not inside a customizable house. Try again.");
break;
}
}
house = BaseHouse.FindHouseAt( item ) as HouseFoundation;
from.Target = new DesignInsertTarget(m_Foundations, m_StaticsOnly);
}
}
if ( house == null )
return DesignInsertResult.NotInHouse;
#endregion
int x = item.X - house.X;
int y = item.Y - house.Y;
int z = item.Z - house.Z;
#region Area targeting mode
if ( !TryInsertIntoState( house.CurrentState, item.ItemID, x, y, z ) )
return DesignInsertResult.OutsideHouseBounds;
public override void ExecuteList(CommandEventArgs e, ArrayList list)
{
e.Mobile.SendGump(new WarningGump(1060637, 30720,
$"You are about to insert {list.Count} objects. This cannot be undone without a full server revert.<br><br>Continue?",
0xFFC000, 420, 280, OnConfirmCallback, new object[] { e, list, e.Length < 1 || !e.GetBoolean(0) }));
AddResponse("Awaiting confirmation...");
}
TryInsertIntoState( house.DesignState, item.ItemID, x, y, z );
item.Delete();
private void OnConfirmCallback(Mobile from, bool okay, object state)
{
object[] states = (object[])state;
CommandEventArgs e = (CommandEventArgs)states[0];
ArrayList list = (ArrayList)states[1];
bool staticsOnly = (bool)states[2];
return DesignInsertResult.Valid;
}
bool flushToLog = false;
private static bool TryInsertIntoState( DesignState state, int itemID, int x, int y, int z )
{
MultiComponentList mcl = state.Components;
if (okay)
{
List<HouseFoundation> foundations = new List<HouseFoundation>();
flushToLog = list.Count > 20;
if ( x < mcl.Min.X || y < mcl.Min.Y || x > mcl.Max.X || y > mcl.Max.Y )
return false;
for (int i = 0; i < list.Count; ++i)
{
HouseFoundation house;
DesignInsertResult result = ProcessInsert(list[i] as Item, staticsOnly, out house);
mcl.Add( itemID, x, y, z );
state.OnRevised();
switch (result)
{
case DesignInsertResult.Valid:
{
AddResponse("The item has been inserted into the house design.");
return true;
}
}
}
if (!foundations.Contains(house))
foundations.Add(house);
break;
}
case DesignInsertResult.InvalidItem:
{
LogFailure("That cannot be inserted.");
break;
}
case DesignInsertResult.NotInHouse:
case DesignInsertResult.OutsideHouseBounds:
{
LogFailure("That item is not inside a customizable house.");
break;
}
}
}
foreach (HouseFoundation house in foundations)
house.Delta(ItemDelta.Update);
}
else
{
AddResponse("Command aborted.");
}
Flush(from, flushToLog);
}
#endregion
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,182 +1,134 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace Server.Commands.Generic
{
public delegate BaseExtension ExtensionConstructor();
public delegate BaseExtension ExtensionConstructor();
public sealed class ExtensionInfo
{
private static Dictionary<string, ExtensionInfo> m_Table = new Dictionary<string, ExtensionInfo>( StringComparer.InvariantCultureIgnoreCase );
public sealed class ExtensionInfo
{
public ExtensionInfo(int order, string name, int size, ExtensionConstructor constructor)
{
Name = name;
Size = size;
public static Dictionary<string, ExtensionInfo> Table
{
get { return m_Table; }
}
Order = order;
public static void Register( ExtensionInfo ext )
{
m_Table[ext.m_Name] = ext;
}
Constructor = constructor;
}
private int m_Order;
public static Dictionary<string, ExtensionInfo> Table{ get; } =
new Dictionary<string, ExtensionInfo>(StringComparer.InvariantCultureIgnoreCase);
private string m_Name;
private int m_Size;
public int Order{ get; }
private ExtensionConstructor m_Constructor;
public string Name{ get; }
public int Order
{
get { return m_Order; }
}
public int Size{ get; }
public string Name
{
get { return m_Name; }
}
public bool IsFixedSize => Size >= 0;
public int Size
{
get { return m_Size; }
}
public ExtensionConstructor Constructor{ get; }
public bool IsFixedSize
{
get { return ( m_Size >= 0 ); }
}
public static void Register(ExtensionInfo ext)
{
Table[ext.Name] = ext;
}
}
public ExtensionConstructor Constructor
{
get { return m_Constructor; }
}
public sealed class Extensions : List<BaseExtension>
{
public bool IsValid(object obj)
{
for (int i = 0; i < Count; ++i)
if (!this[i].IsValid(obj))
return false;
public ExtensionInfo( int order, string name, int size, ExtensionConstructor constructor )
{
m_Name = name;
m_Size = size;
return true;
}
m_Order = order;
public void Filter(ArrayList list)
{
for (int i = 0; i < Count; ++i)
this[i].Filter(list);
}
m_Constructor = constructor;
}
}
public static Extensions Parse(Mobile from, ref string[] args)
{
Extensions parsed = new Extensions();
public sealed class Extensions : List<BaseExtension>
{
public Extensions()
{
}
int size = args.Length;
public bool IsValid( object obj )
{
for ( int i = 0; i < this.Count; ++i )
{
if ( !this[i].IsValid( obj ) )
return false;
}
Type baseType = null;
return true;
}
for (int i = args.Length - 1; i >= 0; --i)
{
if (!ExtensionInfo.Table.TryGetValue(args[i], out ExtensionInfo extInfo))
continue;
public void Filter( ArrayList list )
{
for ( int i = 0; i < this.Count; ++i )
this[i].Filter( list );
}
if (extInfo.IsFixedSize && i != size - extInfo.Size - 1)
throw new Exception("Invalid extended argument count.");
public static Extensions Parse( Mobile from, ref string[] args )
{
Extensions parsed = new Extensions();
BaseExtension ext = extInfo.Constructor();
int size = args.Length;
ext.Parse(from, args, i + 1, size - i - 1);
Type baseType = null;
if (ext is WhereExtension extension)
baseType = extension.Conditional.Type;
for ( int i = args.Length - 1; i >= 0; --i )
{
if ( !ExtensionInfo.Table.TryGetValue( args[i], out ExtensionInfo extInfo ) )
continue;
parsed.Add(ext);
if ( extInfo.IsFixedSize && i != ( size - extInfo.Size - 1 ) )
throw new Exception( "Invalid extended argument count." );
size = i;
}
BaseExtension ext = extInfo.Constructor();
parsed.Sort((a, b) => a.Order - b.Order);
ext.Parse( from, args, i + 1, size - i - 1 );
AssemblyEmitter emitter = null;
if ( ext is WhereExtension )
baseType = ( ext as WhereExtension ).Conditional.Type;
foreach (BaseExtension update in parsed)
update.Optimize(from, baseType, ref emitter);
parsed.Add( ext );
if (size != args.Length)
{
string[] old = args;
args = new string[size];
size = i;
}
for (int i = 0; i < args.Length; ++i)
args[i] = old[i];
}
parsed.Sort( delegate( BaseExtension a, BaseExtension b )
{
return ( a.Order - b.Order );
} );
return parsed;
}
}
AssemblyEmitter emitter = null;
public abstract class BaseExtension
{
public abstract ExtensionInfo Info{ get; }
foreach ( BaseExtension update in parsed )
update.Optimize( from, baseType, ref emitter );
public string Name => Info.Name;
if ( size != args.Length )
{
string[] old = args;
args = new string[size];
public int Size => Info.Size;
for ( int i = 0; i < args.Length; ++i )
args[i] = old[i];
}
public bool IsFixedSize => Info.IsFixedSize;
return parsed;
}
}
public int Order => Info.Order;
public abstract class BaseExtension
{
public abstract ExtensionInfo Info { get; }
public virtual void Optimize(Mobile from, Type baseType, ref AssemblyEmitter assembly)
{
}
public string Name
{
get { return Info.Name; }
}
public virtual void Parse(Mobile from, string[] arguments, int offset, int size)
{
}
public int Size
{
get { return Info.Size; }
}
public virtual bool IsValid(object obj)
{
return true;
}
public bool IsFixedSize
{
get { return Info.IsFixedSize; }
}
public int Order
{
get { return Info.Order; }
}
public virtual void Optimize( Mobile from, Type baseType, ref AssemblyEmitter assembly )
{
}
public virtual void Parse( Mobile from, string[] arguments, int offset, int size )
{
}
public virtual bool IsValid( object obj )
{
return true;
}
public virtual void Filter( ArrayList list )
{
}
}
}
public virtual void Filter(ArrayList list)
{
}
}
}

View file

@ -3,247 +3,257 @@ using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using Server;
namespace Server.Commands.Generic
{
public static class DistinctCompiler
{
public static IComparer Compile( AssemblyEmitter assembly, Type objectType, Property[] props )
{
TypeBuilder typeBuilder = assembly.DefineType(
"__distinct",
TypeAttributes.Public,
typeof( object )
);
public static class DistinctCompiler
{
public static IComparer Compile(AssemblyEmitter assembly, Type objectType, Property[] props)
{
TypeBuilder typeBuilder = assembly.DefineType(
"__distinct",
TypeAttributes.Public,
typeof(object)
);
#region Constructor
{
ConstructorBuilder ctor = typeBuilder.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
Type.EmptyTypes
);
#region Constructor
ILGenerator il = ctor.GetILGenerator();
{
ConstructorBuilder ctor = typeBuilder.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
Type.EmptyTypes
);
// : base()
il.Emit( OpCodes.Ldarg_0 );
il.Emit( OpCodes.Call, typeof( object ).GetConstructor( Type.EmptyTypes ) );
ILGenerator il = ctor.GetILGenerator();
// return;
il.Emit( OpCodes.Ret );
}
#endregion
// : base()
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
#region IComparer
typeBuilder.AddInterfaceImplementation( typeof( IComparer ) );
// return;
il.Emit(OpCodes.Ret);
}
MethodBuilder compareMethod;
#endregion
#region Compare
{
MethodEmitter emitter = new MethodEmitter( typeBuilder );
#region IComparer
emitter.Define(
/* name */ "Compare",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof( int ),
/* params */ new Type[] { typeof( object ), typeof( object ) } );
typeBuilder.AddInterfaceImplementation(typeof(IComparer));
LocalBuilder a = emitter.CreateLocal( objectType );
LocalBuilder b = emitter.CreateLocal( objectType );
MethodBuilder compareMethod;
LocalBuilder v = emitter.CreateLocal( typeof( int ) );
#region Compare
emitter.LoadArgument( 1 );
emitter.CastAs( objectType );
emitter.StoreLocal( a );
{
MethodEmitter emitter = new MethodEmitter(typeBuilder);
emitter.LoadArgument( 2 );
emitter.CastAs( objectType );
emitter.StoreLocal( b );
emitter.Define(
/* name */ "Compare",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof(int),
/* params */ new[] { typeof(object), typeof(object) });
emitter.Load( 0 );
emitter.StoreLocal( v );
LocalBuilder a = emitter.CreateLocal(objectType);
LocalBuilder b = emitter.CreateLocal(objectType);
Label end = emitter.CreateLabel();
LocalBuilder v = emitter.CreateLocal(typeof(int));
for ( int i = 0; i < props.Length; ++i )
{
if ( i > 0 )
{
emitter.LoadLocal( v );
emitter.BranchIfTrue( end ); // if ( v != 0 ) return v;
}
emitter.LoadArgument(1);
emitter.CastAs(objectType);
emitter.StoreLocal(a);
Property prop = props[i];
emitter.LoadArgument(2);
emitter.CastAs(objectType);
emitter.StoreLocal(b);
emitter.LoadLocal( a );
emitter.Chain( prop );
emitter.Load(0);
emitter.StoreLocal(v);
bool couldCompare =
emitter.CompareTo( 1, delegate()
{
emitter.LoadLocal( b );
emitter.Chain( prop );
} );
Label end = emitter.CreateLabel();
if ( !couldCompare )
throw new InvalidOperationException( "Property is not comparable." );
for (int i = 0; i < props.Length; ++i)
{
if (i > 0)
{
emitter.LoadLocal(v);
emitter.BranchIfTrue(end); // if ( v != 0 ) return v;
}
emitter.StoreLocal( v );
}
Property prop = props[i];
emitter.MarkLabel( end );
emitter.LoadLocal(a);
emitter.Chain(prop);
emitter.LoadLocal( v );
emitter.Return();
bool couldCompare =
emitter.CompareTo(1, delegate
{
emitter.LoadLocal(b);
emitter.Chain(prop);
});
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof( IComparer ).GetMethod(
"Compare",
new Type[]
{
typeof( object ),
typeof( object )
}
)
);
if (!couldCompare)
throw new InvalidOperationException("Property is not comparable.");
compareMethod = emitter.Method;
}
#endregion
#endregion
emitter.StoreLocal(v);
}
#region IEqualityComparer
typeBuilder.AddInterfaceImplementation( typeof( IEqualityComparer<object> ) );
emitter.MarkLabel(end);
#region Equals
{
MethodEmitter emitter = new MethodEmitter( typeBuilder );
emitter.LoadLocal(v);
emitter.Return();
emitter.Define(
/* name */ "Equals",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof( bool ),
/* params */ new Type[] { typeof( object ), typeof( object ) } );
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof(IComparer).GetMethod(
"Compare",
new[]
{
typeof(object),
typeof(object)
}
)
);
emitter.Generator.Emit( OpCodes.Ldarg_0 );
emitter.Generator.Emit( OpCodes.Ldarg_1 );
emitter.Generator.Emit( OpCodes.Ldarg_2 );
compareMethod = emitter.Method;
}
emitter.Generator.Emit( OpCodes.Call, compareMethod );
#endregion
emitter.Generator.Emit( OpCodes.Ldc_I4_0 );
#endregion
emitter.Generator.Emit( OpCodes.Ceq );
#region IEqualityComparer
emitter.Generator.Emit( OpCodes.Ret );
typeBuilder.AddInterfaceImplementation(typeof(IEqualityComparer<object>));
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof( IEqualityComparer<object> ).GetMethod(
"Equals",
new Type[]
{
typeof( object ),
typeof( object )
}
)
);
}
#endregion
#region Equals
#region GetHashCode
{
MethodEmitter emitter = new MethodEmitter( typeBuilder );
{
MethodEmitter emitter = new MethodEmitter(typeBuilder);
emitter.Define(
/* name */ "GetHashCode",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof( int ),
/* params */ new Type[] { typeof( object ) } );
emitter.Define(
/* name */ "Equals",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof(bool),
/* params */ new[] { typeof(object), typeof(object) });
LocalBuilder obj = emitter.CreateLocal( objectType );
emitter.Generator.Emit(OpCodes.Ldarg_0);
emitter.Generator.Emit(OpCodes.Ldarg_1);
emitter.Generator.Emit(OpCodes.Ldarg_2);
emitter.LoadArgument( 1 );
emitter.CastAs( objectType );
emitter.StoreLocal( obj );
emitter.Generator.Emit(OpCodes.Call, compareMethod);
for ( int i = 0; i < props.Length; ++i )
{
Property prop = props[i];
emitter.Generator.Emit(OpCodes.Ldc_I4_0);
emitter.LoadLocal( obj );
emitter.Chain( prop );
emitter.Generator.Emit(OpCodes.Ceq);
Type active = emitter.Active;
emitter.Generator.Emit(OpCodes.Ret);
MethodInfo getHashCode = active.GetMethod( "GetHashCode", Type.EmptyTypes );
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof(IEqualityComparer<object>).GetMethod(
"Equals",
new[]
{
typeof(object),
typeof(object)
}
)
);
}
if ( getHashCode == null )
getHashCode = typeof( object ).GetMethod( "GetHashCode", Type.EmptyTypes );
#endregion
if ( active != typeof( int ) )
{
if ( !active.IsValueType )
{
LocalBuilder value = emitter.AcquireTemp( active );
#region GetHashCode
Label valueNotNull = emitter.CreateLabel();
Label done = emitter.CreateLabel();
{
MethodEmitter emitter = new MethodEmitter(typeBuilder);
emitter.StoreLocal( value );
emitter.LoadLocal( value );
emitter.Define(
/* name */ "GetHashCode",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof(int),
/* params */ new[] { typeof(object) });
emitter.BranchIfTrue( valueNotNull );
LocalBuilder obj = emitter.CreateLocal(objectType);
emitter.Load( 0 );
emitter.Pop( typeof( int ) );
emitter.LoadArgument(1);
emitter.CastAs(objectType);
emitter.StoreLocal(obj);
emitter.Branch( done );
for (int i = 0; i < props.Length; ++i)
{
Property prop = props[i];
emitter.MarkLabel( valueNotNull );
emitter.LoadLocal(obj);
emitter.Chain(prop);
emitter.LoadLocal( value );
emitter.Call( getHashCode );
Type active = emitter.Active;
emitter.ReleaseTemp( value );
MethodInfo getHashCode = active.GetMethod("GetHashCode", Type.EmptyTypes);
emitter.MarkLabel( done );
}
else
{
emitter.Call( getHashCode );
}
}
if (getHashCode == null)
getHashCode = typeof(object).GetMethod("GetHashCode", Type.EmptyTypes);
if ( i > 0 )
emitter.Xor();
}
if (active != typeof(int))
{
if (!active.IsValueType)
{
LocalBuilder value = emitter.AcquireTemp(active);
emitter.Return();
Label valueNotNull = emitter.CreateLabel();
Label done = emitter.CreateLabel();
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof( IEqualityComparer<object> ).GetMethod(
"GetHashCode",
new Type[]
{
typeof( object )
}
)
);
}
#endregion
#endregion
emitter.StoreLocal(value);
emitter.LoadLocal(value);
Type comparerType = typeBuilder.CreateType();
emitter.BranchIfTrue(valueNotNull);
return (IComparer) Activator.CreateInstance( comparerType );
}
}
}
emitter.Load(0);
emitter.Pop(typeof(int));
emitter.Branch(done);
emitter.MarkLabel(valueNotNull);
emitter.LoadLocal(value);
emitter.Call(getHashCode);
emitter.ReleaseTemp(value);
emitter.MarkLabel(done);
}
else
{
emitter.Call(getHashCode);
}
}
if (i > 0)
emitter.Xor();
}
emitter.Return();
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof(IEqualityComparer<object>).GetMethod(
"GetHashCode",
new[]
{
typeof(object)
}
)
);
}
#endregion
#endregion
Type comparerType = typeBuilder.CreateType();
return (IComparer)Activator.CreateInstance(comparerType);
}
}
}

View file

@ -1,172 +1,170 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using Server;
namespace Server.Commands.Generic
{
public sealed class OrderInfo
{
private Property m_Property;
private int m_Order;
public sealed class OrderInfo
{
private int m_Order;
public Property Property
{
get { return m_Property; }
set { m_Property = value; }
}
public OrderInfo(Property property, bool isAscending)
{
Property = property;
public bool IsAscending
{
get { return ( m_Order > 0 ); }
set { m_Order = ( value ? +1 : -1 ); }
}
IsAscending = isAscending;
}
public bool IsDescending
{
get { return ( m_Order < 0 ); }
set { m_Order = ( value ? -1 : +1 ); }
}
public Property Property{ get; set; }
public int Sign
{
get { return Math.Sign( m_Order ); }
set
{
m_Order = Math.Sign( value );
public bool IsAscending
{
get => m_Order > 0;
set => m_Order = value ? +1 : -1;
}
if ( m_Order == 0 )
throw new InvalidOperationException( "Sign cannot be zero." );
}
}
public bool IsDescending
{
get => m_Order < 0;
set => m_Order = value ? -1 : +1;
}
public OrderInfo( Property property, bool isAscending )
{
m_Property = property;
public int Sign
{
get => Math.Sign(m_Order);
set
{
m_Order = Math.Sign(value);
this.IsAscending = isAscending;
}
}
if (m_Order == 0)
throw new InvalidOperationException("Sign cannot be zero.");
}
}
}
public static class SortCompiler
{
public static IComparer Compile( AssemblyEmitter assembly, Type objectType, OrderInfo[] orders )
{
TypeBuilder typeBuilder = assembly.DefineType(
"__sort",
TypeAttributes.Public,
typeof( object )
);
public static class SortCompiler
{
public static IComparer Compile(AssemblyEmitter assembly, Type objectType, OrderInfo[] orders)
{
TypeBuilder typeBuilder = assembly.DefineType(
"__sort",
TypeAttributes.Public,
typeof(object)
);
#region Constructor
{
ConstructorBuilder ctor = typeBuilder.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
Type.EmptyTypes
);
#region Constructor
ILGenerator il = ctor.GetILGenerator();
{
ConstructorBuilder ctor = typeBuilder.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
Type.EmptyTypes
);
// : base()
il.Emit( OpCodes.Ldarg_0 );
il.Emit( OpCodes.Call, typeof( object ).GetConstructor( Type.EmptyTypes ) );
ILGenerator il = ctor.GetILGenerator();
// return;
il.Emit( OpCodes.Ret );
}
#endregion
// : base()
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
#region IComparer
typeBuilder.AddInterfaceImplementation( typeof( IComparer ) );
// return;
il.Emit(OpCodes.Ret);
}
MethodBuilder compareMethod;
#endregion
#region Compare
{
MethodEmitter emitter = new MethodEmitter( typeBuilder );
#region IComparer
emitter.Define(
/* name */ "Compare",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof( int ),
/* params */ new Type[] { typeof( object ), typeof( object ) } );
typeBuilder.AddInterfaceImplementation(typeof(IComparer));
LocalBuilder a = emitter.CreateLocal( objectType );
LocalBuilder b = emitter.CreateLocal( objectType );
MethodBuilder compareMethod;
LocalBuilder v = emitter.CreateLocal( typeof( int ) );
#region Compare
emitter.LoadArgument( 1 );
emitter.CastAs( objectType );
emitter.StoreLocal( a );
{
MethodEmitter emitter = new MethodEmitter(typeBuilder);
emitter.LoadArgument( 2 );
emitter.CastAs( objectType );
emitter.StoreLocal( b );
emitter.Define(
/* name */ "Compare",
/* attr */ MethodAttributes.Public | MethodAttributes.Virtual,
/* return */ typeof(int),
/* params */ new[] { typeof(object), typeof(object) });
emitter.Load( 0 );
emitter.StoreLocal( v );
LocalBuilder a = emitter.CreateLocal(objectType);
LocalBuilder b = emitter.CreateLocal(objectType);
Label end = emitter.CreateLabel();
LocalBuilder v = emitter.CreateLocal(typeof(int));
for ( int i = 0; i < orders.Length; ++i )
{
if ( i > 0 )
{
emitter.LoadLocal( v );
emitter.BranchIfTrue( end ); // if ( v != 0 ) return v;
}
emitter.LoadArgument(1);
emitter.CastAs(objectType);
emitter.StoreLocal(a);
OrderInfo orderInfo = orders[i];
emitter.LoadArgument(2);
emitter.CastAs(objectType);
emitter.StoreLocal(b);
Property prop = orderInfo.Property;
int sign = orderInfo.Sign;
emitter.Load(0);
emitter.StoreLocal(v);
emitter.LoadLocal( a );
emitter.Chain( prop );
Label end = emitter.CreateLabel();
bool couldCompare =
emitter.CompareTo( sign, delegate()
{
emitter.LoadLocal( b );
emitter.Chain( prop );
} );
for (int i = 0; i < orders.Length; ++i)
{
if (i > 0)
{
emitter.LoadLocal(v);
emitter.BranchIfTrue(end); // if ( v != 0 ) return v;
}
if ( !couldCompare )
throw new InvalidOperationException( "Property is not comparable." );
OrderInfo orderInfo = orders[i];
emitter.StoreLocal( v );
}
Property prop = orderInfo.Property;
int sign = orderInfo.Sign;
emitter.MarkLabel( end );
emitter.LoadLocal(a);
emitter.Chain(prop);
emitter.LoadLocal( v );
emitter.Return();
bool couldCompare =
emitter.CompareTo(sign, delegate
{
emitter.LoadLocal(b);
emitter.Chain(prop);
});
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof( IComparer ).GetMethod(
"Compare",
new Type[]
{
typeof( object ),
typeof( object )
}
)
);
if (!couldCompare)
throw new InvalidOperationException("Property is not comparable.");
compareMethod = emitter.Method;
}
#endregion
#endregion
emitter.StoreLocal(v);
}
Type comparerType = typeBuilder.CreateType();
emitter.MarkLabel(end);
return (IComparer) Activator.CreateInstance( comparerType );
}
}
}
emitter.LoadLocal(v);
emitter.Return();
typeBuilder.DefineMethodOverride(
emitter.Method,
typeof(IComparer).GetMethod(
"Compare",
new[]
{
typeof(object),
typeof(object)
}
)
);
compareMethod = emitter.Method;
}
#endregion
#endregion
Type comparerType = typeBuilder.CreateType();
return (IComparer)Activator.CreateInstance(comparerType);
}
}
}

View file

@ -1,89 +1,85 @@
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace Server.Commands.Generic
{
public sealed class DistinctExtension : BaseExtension
{
public static ExtensionInfo ExtInfo = new ExtensionInfo( 30, "Distinct", -1, delegate() { return new DistinctExtension(); } );
public sealed class DistinctExtension : BaseExtension
{
public static ExtensionInfo ExtInfo =
new ExtensionInfo(30, "Distinct", -1, delegate { return new DistinctExtension(); });
public static void Initialize()
{
ExtensionInfo.Register( ExtInfo );
}
private IComparer m_Comparer;
public override ExtensionInfo Info
{
get { return ExtInfo; }
}
private List<Property> m_Properties;
private List<Property> m_Properties;
public DistinctExtension()
{
m_Properties = new List<Property>();
}
private IComparer m_Comparer;
public override ExtensionInfo Info => ExtInfo;
public DistinctExtension()
{
m_Properties = new List<Property>();
}
public static void Initialize()
{
ExtensionInfo.Register(ExtInfo);
}
public override void Optimize( Mobile from, Type baseType, ref AssemblyEmitter assembly )
{
if ( baseType == null )
throw new Exception( "Distinct extension may only be used in combination with an object conditional." );
public override void Optimize(Mobile from, Type baseType, ref AssemblyEmitter assembly)
{
if (baseType == null)
throw new Exception("Distinct extension may only be used in combination with an object conditional.");
foreach ( Property prop in m_Properties )
{
prop.BindTo( baseType, PropertyAccess.Read );
prop.CheckAccess( from );
}
foreach (Property prop in m_Properties)
{
prop.BindTo(baseType, PropertyAccess.Read);
prop.CheckAccess(from);
}
if ( assembly == null )
assembly = new AssemblyEmitter( "__dynamic", false );
if (assembly == null)
assembly = new AssemblyEmitter("__dynamic", false);
m_Comparer = DistinctCompiler.Compile( assembly, baseType, m_Properties.ToArray() );
}
m_Comparer = DistinctCompiler.Compile(assembly, baseType, m_Properties.ToArray());
}
public override void Parse( Mobile from, string[] arguments, int offset, int size )
{
if ( size < 1 )
throw new Exception( "Invalid distinction syntax." );
public override void Parse(Mobile from, string[] arguments, int offset, int size)
{
if (size < 1)
throw new Exception("Invalid distinction syntax.");
int end = offset + size;
int end = offset + size;
while ( offset < end )
{
string binding = arguments[offset++];
while (offset < end)
{
string binding = arguments[offset++];
m_Properties.Add( new Property( binding ) );
}
}
m_Properties.Add(new Property(binding));
}
}
public override void Filter( ArrayList list )
{
if ( m_Comparer == null )
throw new InvalidOperationException( "The extension must first be optimized." );
public override void Filter(ArrayList list)
{
if (m_Comparer == null)
throw new InvalidOperationException("The extension must first be optimized.");
ArrayList copy = new ArrayList( list );
ArrayList copy = new ArrayList(list);
copy.Sort( m_Comparer );
copy.Sort(m_Comparer);
list.Clear();
list.Clear();
object last = null;
object last = null;
for ( int i = 0; i < copy.Count; ++i )
{
object obj = copy[i];
for (int i = 0; i < copy.Count; ++i)
{
object obj = copy[i];
if ( last == null || m_Comparer.Compare( obj, last ) != 0 )
{
list.Add( obj );
last = obj;
}
}
}
}
}
if (last == null || m_Comparer.Compare(obj, last) != 0)
{
list.Add(obj);
last = obj;
}
}
}
}
}

View file

@ -1,46 +1,33 @@
using System;
using System.Collections;
using System.Text;
namespace Server.Commands.Generic
{
public sealed class LimitExtension : BaseExtension
{
public static ExtensionInfo ExtInfo = new ExtensionInfo( 80, "Limit", 1, delegate() { return new LimitExtension(); } );
public sealed class LimitExtension : BaseExtension
{
public static ExtensionInfo ExtInfo = new ExtensionInfo(80, "Limit", 1, () => new LimitExtension());
public static void Initialize()
{
ExtensionInfo.Register( ExtInfo );
}
public override ExtensionInfo Info => ExtInfo;
public override ExtensionInfo Info
{
get { return ExtInfo; }
}
public int Limit{ get; private set; }
private int m_Limit;
public static void Initialize()
{
ExtensionInfo.Register(ExtInfo);
}
public int Limit
{
get { return m_Limit; }
}
public override void Parse(Mobile from, string[] arguments, int offset, int size)
{
Limit = Utility.ToInt32(arguments[offset]);
public LimitExtension()
{
}
if (Limit < 0)
throw new Exception("Limit cannot be less than zero.");
}
public override void Parse( Mobile from, string[] arguments, int offset, int size )
{
m_Limit = Utility.ToInt32( arguments[offset] );
if ( m_Limit < 0 )
throw new Exception( "Limit cannot be less than zero." );
}
public override void Filter( ArrayList list )
{
if ( list.Count > m_Limit )
list.RemoveRange( m_Limit, list.Count - m_Limit );
}
}
}
public override void Filter(ArrayList list)
{
if (list.Count > Limit)
list.RemoveRange(Limit, list.Count - Limit);
}
}
}

View file

@ -1,109 +1,104 @@
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace Server.Commands.Generic
{
public sealed class SortExtension : BaseExtension
{
public static ExtensionInfo ExtInfo = new ExtensionInfo( 40, "Order", -1, delegate() { return new SortExtension(); } );
public sealed class SortExtension : BaseExtension
{
public static ExtensionInfo ExtInfo = new ExtensionInfo(40, "Order", -1, () => new SortExtension());
public static void Initialize()
{
ExtensionInfo.Register( ExtInfo );
}
private IComparer m_Comparer;
public override ExtensionInfo Info
{
get { return ExtInfo; }
}
private List<OrderInfo> m_Orders;
private List<OrderInfo> m_Orders;
public SortExtension()
{
m_Orders = new List<OrderInfo>();
}
private IComparer m_Comparer;
public override ExtensionInfo Info => ExtInfo;
public SortExtension()
{
m_Orders = new List<OrderInfo>();
}
public static void Initialize()
{
ExtensionInfo.Register(ExtInfo);
}
public override void Optimize( Mobile from, Type baseType, ref AssemblyEmitter assembly )
{
if ( baseType == null )
throw new Exception( "The ordering extension may only be used in combination with an object conditional." );
public override void Optimize(Mobile from, Type baseType, ref AssemblyEmitter assembly)
{
if (baseType == null)
throw new Exception("The ordering extension may only be used in combination with an object conditional.");
foreach ( OrderInfo order in m_Orders )
{
order.Property.BindTo( baseType, PropertyAccess.Read );
order.Property.CheckAccess( from );
}
foreach (OrderInfo order in m_Orders)
{
order.Property.BindTo(baseType, PropertyAccess.Read);
order.Property.CheckAccess(from);
}
if ( assembly == null )
assembly = new AssemblyEmitter( "__dynamic", false );
if (assembly == null)
assembly = new AssemblyEmitter("__dynamic", false);
m_Comparer = SortCompiler.Compile( assembly, baseType, m_Orders.ToArray() );
}
m_Comparer = SortCompiler.Compile(assembly, baseType, m_Orders.ToArray());
}
public override void Parse( Mobile from, string[] arguments, int offset, int size )
{
if ( size < 1 )
throw new Exception( "Invalid ordering syntax." );
public override void Parse(Mobile from, string[] arguments, int offset, int size)
{
if (size < 1)
throw new Exception("Invalid ordering syntax.");
if ( Insensitive.Equals( arguments[offset], "by" ) )
{
++offset;
--size;
if (Insensitive.Equals(arguments[offset], "by"))
{
++offset;
--size;
if ( size < 1 )
throw new Exception( "Invalid ordering syntax." );
}
if (size < 1)
throw new Exception("Invalid ordering syntax.");
}
int end = offset + size;
int end = offset + size;
while ( offset < end )
{
string binding = arguments[offset++];
while (offset < end)
{
string binding = arguments[offset++];
bool isAscending = true;
bool isAscending = true;
if ( offset < end )
{
string next = arguments[offset];
if (offset < end)
{
string next = arguments[offset];
switch ( next.ToLower() )
{
case "+":
case "up":
case "asc":
case "ascending":
isAscending = true;
++offset;
break;
switch (next.ToLower())
{
case "+":
case "up":
case "asc":
case "ascending":
isAscending = true;
++offset;
break;
case "-":
case "down":
case "desc":
case "descending":
isAscending = false;
++offset;
break;
}
}
case "-":
case "down":
case "desc":
case "descending":
isAscending = false;
++offset;
break;
}
}
Property property = new Property( binding );
Property property = new Property(binding);
m_Orders.Add( new OrderInfo( property, isAscending ) );
}
}
m_Orders.Add(new OrderInfo(property, isAscending));
}
}
public override void Filter( ArrayList list )
{
if ( m_Comparer == null )
throw new InvalidOperationException( "The extension must first be optimized." );
public override void Filter(ArrayList list)
{
if (m_Comparer == null)
throw new InvalidOperationException("The extension must first be optimized.");
list.Sort( m_Comparer );
}
}
}
list.Sort(m_Comparer);
}
}
}

View file

@ -1,55 +1,39 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Server.Commands;
namespace Server.Commands.Generic
{
public sealed class WhereExtension : BaseExtension
{
public static ExtensionInfo ExtInfo = new ExtensionInfo( 20, "Where", -1, delegate() { return new WhereExtension(); } );
public sealed class WhereExtension : BaseExtension
{
public static ExtensionInfo ExtInfo = new ExtensionInfo(20, "Where", -1, () => new WhereExtension());
public static void Initialize()
{
ExtensionInfo.Register( ExtInfo );
}
public override ExtensionInfo Info => ExtInfo;
public override ExtensionInfo Info
{
get { return ExtInfo; }
}
public ObjectConditional Conditional{ get; private set; }
private ObjectConditional m_Conditional;
public static void Initialize()
{
ExtensionInfo.Register(ExtInfo);
}
public ObjectConditional Conditional
{
get { return m_Conditional; }
}
public override void Optimize(Mobile from, Type baseType, ref AssemblyEmitter assembly)
{
if (baseType == null)
throw new InvalidOperationException("Insanity.");
public WhereExtension()
{
}
Conditional.Compile(ref assembly);
}
public override void Optimize( Mobile from, Type baseType, ref AssemblyEmitter assembly )
{
if ( baseType == null )
throw new InvalidOperationException( "Insanity." );
public override void Parse(Mobile from, string[] arguments, int offset, int size)
{
if (size < 1)
throw new Exception("Invalid condition syntax.");
m_Conditional.Compile( ref assembly );
}
Conditional = ObjectConditional.ParseDirect(from, arguments, offset, size);
}
public override void Parse( Mobile from, string[] arguments, int offset, int size )
{
if ( size < 1 )
throw new Exception( "Invalid condition syntax." );
m_Conditional = ObjectConditional.ParseDirect( from, arguments, offset, size );
}
public override bool IsValid( object obj )
{
return m_Conditional.CheckCondition( obj );
}
}
}
public override bool IsValid(object obj)
{
return Conditional.CheckCondition(obj);
}
}
}

View file

@ -1,81 +1,75 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
namespace Server.Commands.Generic
{
public class AreaCommandImplementor : BaseCommandImplementor
{
private static AreaCommandImplementor m_Instance;
public class AreaCommandImplementor : BaseCommandImplementor
{
public AreaCommandImplementor()
{
Accessors = new[] { "Area", "Group" };
SupportRequirement = CommandSupport.Area;
SupportsConditionals = true;
AccessLevel = AccessLevel.GameMaster;
Usage = "Area <command> [condition]";
Description =
"Invokes the command on all appropriate objects in a targeted area. Optional condition arguments can further restrict the set of objects.";
public static AreaCommandImplementor Instance
{
get { return m_Instance; }
}
Instance = this;
}
public AreaCommandImplementor()
{
Accessors = new string[]{ "Area", "Group" };
SupportRequirement = CommandSupport.Area;
SupportsConditionals = true;
AccessLevel = AccessLevel.GameMaster;
Usage = "Area <command> [condition]";
Description = "Invokes the command on all appropriate objects in a targeted area. Optional condition arguments can further restrict the set of objects.";
public static AreaCommandImplementor Instance{ get; private set; }
m_Instance = this;
}
public override void Process(Mobile from, BaseCommand command, string[] args)
{
BoundingBoxPicker.Begin(from, OnTarget, new object[] { command, args });
}
public override void Process( Mobile from, BaseCommand command, string[] args )
{
BoundingBoxPicker.Begin( from, new BoundingBoxCallback( OnTarget ), new object[]{ command, args } );
}
public void OnTarget(Mobile from, Map map, Point3D start, Point3D end, object state)
{
try
{
object[] states = (object[])state;
BaseCommand command = (BaseCommand)states[0];
string[] args = (string[])states[1];
public void OnTarget( Mobile from, Map map, Point3D start, Point3D end, object state )
{
try
{
object[] states = (object[])state;
BaseCommand command = (BaseCommand)states[0];
string[] args = (string[])states[1];
Rectangle2D rect = new Rectangle2D(start.X, start.Y, end.X - start.X + 1, end.Y - start.Y + 1);
Rectangle2D rect = new Rectangle2D( start.X, start.Y, end.X - start.X + 1, end.Y - start.Y + 1 );
Extensions ext = Extensions.Parse(from, ref args);
Extensions ext = Extensions.Parse( from, ref args );
bool items, mobiles;
bool items, mobiles;
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
return;
if ( !CheckObjectTypes( from, command, ext, out items, out mobiles ) )
return;
IPooledEnumerable<IEntity> eable;
IPooledEnumerable<IEntity> eable;
if (items || mobiles)
eable = map.GetObjectsInBounds(rect, items, mobiles);
else
return;
if (items || mobiles)
eable = map.GetObjectsInBounds(rect, items, mobiles);
else
return;
ArrayList objs = new ArrayList();
ArrayList objs = new ArrayList();
foreach (IEntity obj in eable)
{
if (mobiles && obj is Mobile && !BaseCommand.IsAccessible(from, obj))
continue;
foreach ( IEntity obj in eable )
{
if ( mobiles && obj is Mobile && !BaseCommand.IsAccessible( from, obj ) )
continue;
if (ext.IsValid(obj))
objs.Add(obj);
}
if ( ext.IsValid( obj ) )
objs.Add( obj );
}
eable.Free();
eable.Free();
ext.Filter(objs);
ext.Filter( objs );
RunCommand( from, objs, command, args );
}
catch ( Exception ex )
{
from.SendMessage( ex.Message );
}
}
}
}
RunCommand(from, objs, command, args);
}
catch (Exception ex)
{
from.SendMessage(ex.Message);
}
}
}
}

View file

@ -2,342 +2,297 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Server;
namespace Server.Commands.Generic
{
[Flags]
public enum CommandSupport
{
Single = 0x0001,
Global = 0x0002,
Online = 0x0004,
Multi = 0x0008,
Area = 0x0010,
Self = 0x0020,
Region = 0x0040,
Contained = 0x0080,
IPAddress = 0x0100,
[Flags]
public enum CommandSupport
{
Single = 0x0001,
Global = 0x0002,
Online = 0x0004,
Multi = 0x0008,
Area = 0x0010,
Self = 0x0020,
Region = 0x0040,
Contained = 0x0080,
IPAddress = 0x0100,
All = Single | Global | Online | Multi | Area | Self | Region | Contained | IPAddress,
AllMobiles = All & ~Contained,
AllNPCs = All & ~(IPAddress | Online | Self | Contained),
AllItems = All & ~(IPAddress | Online | Self | Region),
All = Single | Global | Online | Multi | Area | Self | Region | Contained | IPAddress,
AllMobiles = All & ~Contained,
AllNPCs = All & ~(IPAddress | Online | Self | Contained),
AllItems = All & ~(IPAddress | Online | Self | Region),
Simple = Single | Multi,
Complex = Global | Online | Area | Region | Contained | IPAddress
}
Simple = Single | Multi,
Complex = Global | Online | Area | Region | Contained | IPAddress
}
public abstract class BaseCommandImplementor
{
public static void RegisterImplementors()
{
Register( new RegionCommandImplementor() );
Register( new GlobalCommandImplementor() );
Register( new OnlineCommandImplementor() );
Register( new SingleCommandImplementor() );
Register( new SerialCommandImplementor() );
Register( new MultiCommandImplementor() );
Register( new AreaCommandImplementor() );
Register( new SelfCommandImplementor() );
Register( new ContainedCommandImplementor() );
Register( new IPAddressCommandImplementor() );
public abstract class BaseCommandImplementor
{
private static List<BaseCommandImplementor> m_Implementors;
Register( new RangeCommandImplementor() );
Register( new ScreenCommandImplementor() );
Register( new FacetCommandImplementor() );
}
public BaseCommandImplementor()
{
Commands = new Dictionary<string, BaseCommand>(StringComparer.OrdinalIgnoreCase);
}
private string[] m_Accessors;
private AccessLevel m_AccessLevel;
private CommandSupport m_SupportRequirement;
private Dictionary<string, BaseCommand> m_Commands;
private string m_Usage;
private string m_Description;
private bool m_SupportsConditionals;
public bool SupportsConditionals{ get; set; }
public bool SupportsConditionals
{
get{ return m_SupportsConditionals; }
set{ m_SupportsConditionals = value; }
}
public string[] Accessors{ get; set; }
public string[] Accessors
{
get{ return m_Accessors; }
set{ m_Accessors = value; }
}
public string Usage{ get; set; }
public string Usage
{
get{ return m_Usage; }
set{ m_Usage = value; }
}
public string Description{ get; set; }
public string Description
{
get{ return m_Description; }
set{ m_Description = value; }
}
public AccessLevel AccessLevel{ get; set; }
public AccessLevel AccessLevel
{
get{ return m_AccessLevel; }
set{ m_AccessLevel = value; }
}
public CommandSupport SupportRequirement{ get; set; }
public CommandSupport SupportRequirement
{
get{ return m_SupportRequirement; }
set{ m_SupportRequirement = value; }
}
public Dictionary<string, BaseCommand> Commands{ get; }
public Dictionary<string, BaseCommand> Commands
{
get{ return m_Commands; }
}
public static List<BaseCommandImplementor> Implementors
{
get
{
if (m_Implementors == null)
{
m_Implementors = new List<BaseCommandImplementor>();
RegisterImplementors();
}
public BaseCommandImplementor()
{
m_Commands = new Dictionary<string, BaseCommand>( StringComparer.OrdinalIgnoreCase );
}
return m_Implementors;
}
}
public virtual void Compile( Mobile from, BaseCommand command, ref string[] args, ref object obj )
{
obj = null;
}
public static void RegisterImplementors()
{
Register(new RegionCommandImplementor());
Register(new GlobalCommandImplementor());
Register(new OnlineCommandImplementor());
Register(new SingleCommandImplementor());
Register(new SerialCommandImplementor());
Register(new MultiCommandImplementor());
Register(new AreaCommandImplementor());
Register(new SelfCommandImplementor());
Register(new ContainedCommandImplementor());
Register(new IPAddressCommandImplementor());
public virtual void Register( BaseCommand command )
{
for ( int i = 0; i < command.Commands.Length; ++i )
m_Commands[command.Commands[i]] = command;
}
Register(new RangeCommandImplementor());
Register(new ScreenCommandImplementor());
Register(new FacetCommandImplementor());
}
public bool CheckObjectTypes( Mobile from, BaseCommand command, Extensions ext, out bool items, out bool mobiles )
{
items = mobiles = false;
public virtual void Compile(Mobile from, BaseCommand command, ref string[] args, ref object obj)
{
obj = null;
}
ObjectConditional cond = ObjectConditional.Empty;
public virtual void Register(BaseCommand command)
{
for (int i = 0; i < command.Commands.Length; ++i)
Commands[command.Commands[i]] = command;
}
foreach ( BaseExtension check in ext )
{
if ( check is WhereExtension )
{
cond = ( check as WhereExtension ).Conditional;
public bool CheckObjectTypes(Mobile from, BaseCommand command, Extensions ext, out bool items, out bool mobiles)
{
items = mobiles = false;
break;
}
}
ObjectConditional cond = ObjectConditional.Empty;
bool condIsItem = cond.IsItem;
bool condIsMobile = cond.IsMobile;
foreach (BaseExtension check in ext)
if (check is WhereExtension extension)
{
cond = extension.Conditional;
switch ( command.ObjectTypes )
{
case ObjectTypes.All:
case ObjectTypes.Both:
{
if ( condIsItem )
items = true;
break;
}
if ( condIsMobile )
mobiles = true;
bool condIsItem = cond.IsItem;
bool condIsMobile = cond.IsMobile;
break;
}
case ObjectTypes.Items:
{
if ( condIsItem )
{
items = true;
}
else if ( condIsMobile )
{
from.SendMessage( "You may not use a mobile type condition for this command." );
return false;
}
switch (command.ObjectTypes)
{
case ObjectTypes.All:
case ObjectTypes.Both:
{
if (condIsItem)
items = true;
break;
}
case ObjectTypes.Mobiles:
{
if ( condIsMobile )
{
mobiles = true;
}
else if ( condIsItem )
{
from.SendMessage( "You may not use an item type condition for this command." );
return false;
}
if (condIsMobile)
mobiles = true;
break;
}
}
break;
}
case ObjectTypes.Items:
{
if (condIsItem)
{
items = true;
}
else if (condIsMobile)
{
from.SendMessage("You may not use a mobile type condition for this command.");
return false;
}
return true;
}
break;
}
case ObjectTypes.Mobiles:
{
if (condIsMobile)
{
mobiles = true;
}
else if (condIsItem)
{
from.SendMessage("You may not use an item type condition for this command.");
return false;
}
public void RunCommand( Mobile from, BaseCommand command, string[] args )
{
try
{
object obj = null;
break;
}
}
Compile( from, command, ref args, ref obj );
return true;
}
RunCommand( from, obj, command, args );
}
catch ( Exception ex )
{
from.SendMessage( ex.Message );
}
}
public void RunCommand(Mobile from, BaseCommand command, string[] args)
{
try
{
object obj = null;
public string GenerateArgString( string[] args )
{
if ( args.Length == 0 )
return "";
Compile(from, command, ref args, ref obj);
// NOTE: this does not preserve the case where quotation marks are used on a single word
RunCommand(from, obj, command, args);
}
catch (Exception ex)
{
from.SendMessage(ex.Message);
}
}
StringBuilder sb = new StringBuilder();
public string GenerateArgString(string[] args)
{
if (args.Length == 0)
return "";
for ( int i = 0; i < args.Length; ++i )
{
if ( i > 0 )
sb.Append( ' ' );
// NOTE: this does not preserve the case where quotation marks are used on a single word
if ( args[i].IndexOf( ' ' ) >= 0 )
{
sb.Append( '"' );
sb.Append( args[i] );
sb.Append( '"' );
}
else
{
sb.Append( args[i] );
}
}
StringBuilder sb = new StringBuilder();
return sb.ToString();
}
for (int i = 0; i < args.Length; ++i)
{
if (i > 0)
sb.Append(' ');
public void RunCommand( Mobile from, object obj, BaseCommand command, string[] args )
{
// try
// {
CommandEventArgs e = new CommandEventArgs( from, command.Commands[0], GenerateArgString( args ), args );
if (args[i].IndexOf(' ') >= 0)
{
sb.Append('"');
sb.Append(args[i]);
sb.Append('"');
}
else
{
sb.Append(args[i]);
}
}
if ( !command.ValidateArgs( this, e ) )
return;
return sb.ToString();
}
bool flushToLog = false;
public void RunCommand(Mobile from, object obj, BaseCommand command, string[] args)
{
// try
// {
CommandEventArgs e = new CommandEventArgs(from, command.Commands[0], GenerateArgString(args), args);
if ( obj is ArrayList )
{
ArrayList list = (ArrayList)obj;
if (!command.ValidateArgs(this, e))
return;
if ( list.Count > 20 )
CommandLogging.Enabled = false;
else if ( list.Count == 0 )
command.LogFailure( "Nothing was found to use this command on." );
bool flushToLog = false;
command.ExecuteList( e, list );
if (obj is ArrayList list)
{
if (list.Count > 20)
CommandLogging.Enabled = false;
else if (list.Count == 0)
command.LogFailure("Nothing was found to use this command on.");
if ( list.Count > 20 )
{
flushToLog = true;
CommandLogging.Enabled = true;
}
}
else if ( obj != null )
{
if ( command.ListOptimized )
{
ArrayList list = new ArrayList();
list.Add( obj );
command.ExecuteList( e, list );
}
else
{
command.Execute( e, obj );
}
}
command.ExecuteList(e, list);
command.Flush( from, flushToLog );
// }
// catch ( Exception ex )
// {
// from.SendMessage( ex.Message );
// }
}
if (list.Count > 20)
{
flushToLog = true;
CommandLogging.Enabled = true;
}
}
else if (obj != null)
{
if (command.ListOptimized)
command.ExecuteList(e, new ArrayList { obj });
else
command.Execute(e, obj);
}
public virtual void Process( Mobile from, BaseCommand command, string[] args )
{
RunCommand( from, command, args );
}
command.Flush(from, flushToLog);
// }
// catch ( Exception ex )
// {
// from.SendMessage( ex.Message );
// }
}
public virtual void Execute( CommandEventArgs e )
{
if ( e.Length >= 1 )
{
m_Commands.TryGetValue( e.GetString( 0 ), out BaseCommand command );
public virtual void Process(Mobile from, BaseCommand command, string[] args)
{
RunCommand(from, command, args);
}
if ( command == null )
{
e.Mobile.SendMessage( "That is either an invalid command name or one that does not support this modifier." );
}
else if ( e.Mobile.AccessLevel < command.AccessLevel )
{
e.Mobile.SendMessage( "You do not have access to that command." );
}
else
{
string[] oldArgs = e.Arguments;
string[] args = new string[oldArgs.Length - 1];
public virtual void Execute(CommandEventArgs e)
{
if (e.Length >= 1)
{
Commands.TryGetValue(e.GetString(0), out BaseCommand command);
for ( int i = 0; i < args.Length; ++i )
args[i] = oldArgs[i + 1];
if (command == null)
{
e.Mobile.SendMessage(
"That is either an invalid command name or one that does not support this modifier.");
}
else if (e.Mobile.AccessLevel < command.AccessLevel)
{
e.Mobile.SendMessage("You do not have access to that command.");
}
else
{
string[] oldArgs = e.Arguments;
string[] args = new string[oldArgs.Length - 1];
Process( e.Mobile, command, args );
}
}
else
{
e.Mobile.SendMessage( "You must supply a command name." );
}
}
for (int i = 0; i < args.Length; ++i)
args[i] = oldArgs[i + 1];
public void Register()
{
if ( m_Accessors == null )
return;
Process(e.Mobile, command, args);
}
}
else
{
e.Mobile.SendMessage("You must supply a command name.");
}
}
for ( int i = 0; i < m_Accessors.Length; ++i )
CommandSystem.Register( m_Accessors[i], m_AccessLevel, new CommandEventHandler( Execute ) );
}
public void Register()
{
if (Accessors == null)
return;
public static void Register( BaseCommandImplementor impl )
{
m_Implementors.Add( impl );
impl.Register();
}
for (int i = 0; i < Accessors.Length; ++i)
CommandSystem.Register(Accessors[i], AccessLevel, Execute);
}
private static List<BaseCommandImplementor> m_Implementors;
public static List<BaseCommandImplementor> Implementors
{
get
{
if ( m_Implementors == null )
{
m_Implementors = new List<BaseCommandImplementor>();
RegisterImplementors();
}
return m_Implementors;
}
}
}
}
public static void Register(BaseCommandImplementor impl)
{
m_Implementors.Add(impl);
impl.Register();
}
}
}

View file

@ -1,85 +1,76 @@
using System;
using System.Collections;
using Server;
using System.Collections.Generic;
using System.Linq;
using Server.Items;
using Server.Targeting;
namespace Server.Commands.Generic
{
public class ContainedCommandImplementor : BaseCommandImplementor
{
public ContainedCommandImplementor()
{
Accessors = new string[]{ "Contained" };
SupportRequirement = CommandSupport.Contained;
AccessLevel = AccessLevel.GameMaster;
Usage = "Contained <command> [condition]";
Description = "Invokes the command on all child items in a targeted container. Optional condition arguments can further restrict the set of objects.";
}
public class ContainedCommandImplementor : BaseCommandImplementor
{
public ContainedCommandImplementor()
{
Accessors = new[] { "Contained" };
SupportRequirement = CommandSupport.Contained;
AccessLevel = AccessLevel.GameMaster;
Usage = "Contained <command> [condition]";
Description =
"Invokes the command on all child items in a targeted container. Optional condition arguments can further restrict the set of objects.";
}
public override void Process( Mobile from, BaseCommand command, string[] args )
{
if ( command.ValidateArgs( this, new CommandEventArgs( from, command.Commands[0], GenerateArgString( args ), args ) ) )
from.BeginTarget( -1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback( OnTarget ), new object[]{ command, args } );
}
public override void Process(Mobile from, BaseCommand command, string[] args)
{
if (command.ValidateArgs(this, new CommandEventArgs(from, command.Commands[0], GenerateArgString(args), args)))
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None,
new TargetStateCallback(OnTarget), new object[] { command, args });
}
public void OnTarget( Mobile from, object targeted, object state )
{
if ( !BaseCommand.IsAccessible( from, targeted ) )
{
from.SendMessage( "That is not accessible." );
return;
}
public void OnTarget(Mobile from, object targeted, object state)
{
if (!BaseCommand.IsAccessible(from, targeted))
{
from.SendMessage("That is not accessible.");
return;
}
object[] states = (object[])state;
BaseCommand command = (BaseCommand)states[0];
string[] args = (string[])states[1];
object[] states = (object[])state;
BaseCommand command = (BaseCommand)states[0];
string[] args = (string[])states[1];
if ( command.ObjectTypes == ObjectTypes.Mobiles )
return; // sanity check
if (command.ObjectTypes == ObjectTypes.Mobiles)
return; // sanity check
if ( !(targeted is Container) )
{
from.SendMessage( "That is not a container." );
}
else
{
try
{
Extensions ext = Extensions.Parse( from, ref args );
if (!(targeted is Container cont))
{
from.SendMessage("That is not a container.");
return;
}
try
{
Extensions ext = Extensions.Parse(from, ref args);
bool items, mobiles;
if (!CheckObjectTypes(from, command, ext, out bool items, out bool _))
return;
if ( !CheckObjectTypes( from, command, ext, out items, out mobiles ) )
return;
if (!items)
{
from.SendMessage("This command only works on items.");
return;
}
if ( !items )
{
from.SendMessage( "This command only works on items." );
return;
}
List<Item> list = cont.FindItemsByType<Item>().Where(item => ext.IsValid(item)).ToList();
Container cont = (Container)targeted;
// TODO: Is there a way to avoid using ArrayList?
ext.Filter(new ArrayList(list));
Item[] found = cont.FindItemsByType( typeof( Item ), true );
ArrayList list = new ArrayList();
for ( int i = 0; i < found.Length; ++i )
{
if ( ext.IsValid( found[i] ) )
list.Add( found[i] );
}
ext.Filter( list );
RunCommand( from, list, command, args );
}
catch ( Exception e )
{
from.SendMessage( e.Message );
}
}
}
}
RunCommand(from, list, command, args);
}
catch (Exception e)
{
from.SendMessage(e.Message);
}
}
}
}

View file

@ -1,33 +1,32 @@
using System;
using Server;
namespace Server.Commands.Generic
{
public class FacetCommandImplementor : BaseCommandImplementor
{
public FacetCommandImplementor()
{
Accessors = new string[]{ "Facet" };
SupportRequirement = CommandSupport.Area;
SupportsConditionals = true;
AccessLevel = AccessLevel.GameMaster;
Usage = "Facet <command> [condition]";
Description = "Invokes the command on all appropriate objects within your facet's map bounds. Optional condition arguments can further restrict the set of objects.";
}
public class FacetCommandImplementor : BaseCommandImplementor
{
public FacetCommandImplementor()
{
Accessors = new[] { "Facet" };
SupportRequirement = CommandSupport.Area;
SupportsConditionals = true;
AccessLevel = AccessLevel.GameMaster;
Usage = "Facet <command> [condition]";
Description =
"Invokes the command on all appropriate objects within your facet's map bounds. Optional condition arguments can further restrict the set of objects.";
}
public override void Process( Mobile from, BaseCommand command, string[] args )
{
AreaCommandImplementor impl = AreaCommandImplementor.Instance;
public override void Process(Mobile from, BaseCommand command, string[] args)
{
AreaCommandImplementor impl = AreaCommandImplementor.Instance;
if ( impl == null )
return;
if (impl == null)
return;
Map map = from.Map;
Map map = from.Map;
if ( map == null || map == Map.Internal )
return;
if (map == null || map == Map.Internal)
return;
impl.OnTarget( from, map, Point3D.Zero, new Point3D( map.Width - 1, map.Height - 1, 0 ), new object[] { command, args } );
}
}
}
impl.OnTarget(from, map, Point3D.Zero, new Point3D(map.Width - 1, map.Height - 1, 0),
new object[] { command, args });
}
}
}

View file

@ -1,60 +1,52 @@
using System;
using System.Collections;
using Server;
namespace Server.Commands.Generic
{
public class GlobalCommandImplementor : BaseCommandImplementor
{
public GlobalCommandImplementor()
{
Accessors = new string[]{ "Global" };
SupportRequirement = CommandSupport.Global;
SupportsConditionals = true;
AccessLevel = AccessLevel.Administrator;
Usage = "Global <command> [condition]";
Description = "Invokes the command on all appropriate objects in the world. Optional condition arguments can further restrict the set of objects.";
}
public class GlobalCommandImplementor : BaseCommandImplementor
{
public GlobalCommandImplementor()
{
Accessors = new[] { "Global" };
SupportRequirement = CommandSupport.Global;
SupportsConditionals = true;
AccessLevel = AccessLevel.Administrator;
Usage = "Global <command> [condition]";
Description =
"Invokes the command on all appropriate objects in the world. Optional condition arguments can further restrict the set of objects.";
}
public override void Compile( Mobile from, BaseCommand command, ref string[] args, ref object obj )
{
try
{
Extensions ext = Extensions.Parse( from, ref args );
public override void Compile(Mobile from, BaseCommand command, ref string[] args, ref object obj)
{
try
{
Extensions ext = Extensions.Parse(from, ref args);
bool items, mobiles;
bool items, mobiles;
if ( !CheckObjectTypes( from, command, ext, out items, out mobiles ) )
return;
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
return;
ArrayList list = new ArrayList();
ArrayList list = new ArrayList();
if ( items )
{
foreach ( Item item in World.Items.Values )
{
if ( ext.IsValid( item ) )
list.Add( item );
}
}
if (items)
foreach (Item item in World.Items.Values)
if (ext.IsValid(item))
list.Add(item);
if ( mobiles )
{
foreach ( Mobile mob in World.Mobiles.Values )
{
if ( ext.IsValid( mob ) )
list.Add( mob );
}
}
if (mobiles)
foreach (Mobile mob in World.Mobiles.Values)
if (ext.IsValid(mob))
list.Add(mob);
ext.Filter( list );
ext.Filter(list);
obj = list;
}
catch ( Exception ex )
{
from.SendMessage( ex.Message );
}
}
}
obj = list;
}
catch (Exception ex)
{
from.SendMessage(ex.Message);
}
}
}
}

View file

@ -1,64 +1,65 @@
using System;
using System.Collections;
using Server;
using System.Collections.Generic;
using Server.Network;
namespace Server.Commands.Generic
{
public class IPAddressCommandImplementor : BaseCommandImplementor
{
public IPAddressCommandImplementor()
{
Accessors = new string[]{ "IPAddress" };
SupportRequirement = CommandSupport.IPAddress;
SupportsConditionals = true;
AccessLevel = AccessLevel.Administrator;
Usage = "IPAddress <command> [condition]";
Description = "Invokes the command on one mobile from each IP address that is logged in. Optional condition arguments can further restrict the set of objects.";
}
public class IPAddressCommandImplementor : BaseCommandImplementor
{
public IPAddressCommandImplementor()
{
Accessors = new[] { "IPAddress" };
SupportRequirement = CommandSupport.IPAddress;
SupportsConditionals = true;
AccessLevel = AccessLevel.Administrator;
Usage = "IPAddress <command> [condition]";
Description =
"Invokes the command on one mobile from each IP address that is logged in. Optional condition arguments can further restrict the set of objects.";
}
public override void Compile( Mobile from, BaseCommand command, ref string[] args, ref object obj )
{
try
{
Extensions ext = Extensions.Parse( from, ref args );
public override void Compile(Mobile from, BaseCommand command, ref string[] args, ref object obj)
{
try
{
Extensions ext = Extensions.Parse(from, ref args);
bool items, mobiles;
bool items, mobiles;
if ( !CheckObjectTypes( from, command, ext, out items, out mobiles ) )
return;
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
return;
if ( !mobiles ) // sanity check
{
command.LogFailure( "This command does not support items." );
return;
}
if (!mobiles) // sanity check
{
command.LogFailure("This command does not support items.");
return;
}
ArrayList list = new ArrayList();
ArrayList addresses = new ArrayList();
ArrayList list = new ArrayList();
ArrayList addresses = new ArrayList();
System.Collections.Generic.List<NetState> states = NetState.Instances;
List<NetState> states = NetState.Instances;
for ( int i = 0; i < states.Count; ++i )
{
NetState ns = (NetState)states[i];
Mobile mob = ns.Mobile;
for (int i = 0; i < states.Count; ++i)
{
NetState ns = states[i];
Mobile mob = ns.Mobile;
if ( mob != null && !addresses.Contains( ns.Address ) && ext.IsValid( mob ) )
{
list.Add( mob );
addresses.Add( ns.Address );
}
}
if (mob != null && !addresses.Contains(ns.Address) && ext.IsValid(mob))
{
list.Add(mob);
addresses.Add(ns.Address);
}
}
ext.Filter( list );
ext.Filter(list);
obj = list;
}
catch ( Exception ex )
{
from.SendMessage( ex.Message );
}
}
}
obj = list;
}
catch (Exception ex)
{
from.SendMessage(ex.Message);
}
}
}
}

View file

@ -1,77 +1,77 @@
using System;
using System.Collections;
using Server;
using Server.Targeting;
namespace Server.Commands.Generic
{
public class MultiCommandImplementor : BaseCommandImplementor
{
public MultiCommandImplementor()
{
Accessors = new string[]{ "Multi", "m" };
SupportRequirement = CommandSupport.Multi;
AccessLevel = AccessLevel.Counselor;
Usage = "Multi <command>";
Description = "Invokes the command on multiple targeted objects.";
}
public class MultiCommandImplementor : BaseCommandImplementor
{
public MultiCommandImplementor()
{
Accessors = new[] { "Multi", "m" };
SupportRequirement = CommandSupport.Multi;
AccessLevel = AccessLevel.Counselor;
Usage = "Multi <command>";
Description = "Invokes the command on multiple targeted objects.";
}
public override void Process( Mobile from, BaseCommand command, string[] args )
{
if ( command.ValidateArgs( this, new CommandEventArgs( from, command.Commands[0], GenerateArgString( args ), args ) ) )
from.BeginTarget( -1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback( OnTarget ), new object[]{ command, args } );
}
public override void Process(Mobile from, BaseCommand command, string[] args)
{
if (command.ValidateArgs(this, new CommandEventArgs(from, command.Commands[0], GenerateArgString(args), args)))
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None,
new TargetStateCallback(OnTarget), new object[] { command, args });
}
public void OnTarget( Mobile from, object targeted, object state )
{
object[] states = (object[])state;
BaseCommand command = (BaseCommand)states[0];
string[] args = (string[])states[1];
public void OnTarget(Mobile from, object targeted, object state)
{
object[] states = (object[])state;
BaseCommand command = (BaseCommand)states[0];
string[] args = (string[])states[1];
if ( !BaseCommand.IsAccessible( from, targeted ) )
{
from.SendMessage( "That is not accessible." );
from.BeginTarget( -1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback( OnTarget ), new object[]{ command, args } );
return;
}
if (!BaseCommand.IsAccessible(from, targeted))
{
from.SendMessage("That is not accessible.");
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None,
new TargetStateCallback(OnTarget), new object[] { command, args });
return;
}
switch ( command.ObjectTypes )
{
case ObjectTypes.Both:
{
if ( !(targeted is Item) && !(targeted is Mobile) )
{
from.SendMessage( "This command does not work on that." );
return;
}
switch (command.ObjectTypes)
{
case ObjectTypes.Both:
{
if (!(targeted is Item) && !(targeted is Mobile))
{
from.SendMessage("This command does not work on that.");
return;
}
break;
}
case ObjectTypes.Items:
{
if ( !(targeted is Item) )
{
from.SendMessage( "This command only works on items." );
return;
}
break;
}
case ObjectTypes.Items:
{
if (!(targeted is Item))
{
from.SendMessage("This command only works on items.");
return;
}
break;
}
case ObjectTypes.Mobiles:
{
if ( !(targeted is Mobile) )
{
from.SendMessage( "This command only works on mobiles." );
return;
}
break;
}
case ObjectTypes.Mobiles:
{
if (!(targeted is Mobile))
{
from.SendMessage("This command only works on mobiles.");
return;
}
break;
}
}
break;
}
}
RunCommand( from, targeted, command, args );
RunCommand(from, targeted, command, args);
from.BeginTarget( -1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback( OnTarget ), new object[]{ command, args } );
}
}
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback(OnTarget),
new object[] { command, args });
}
}
}

View file

@ -1,266 +1,250 @@
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Targeting;
using CPA = Server.CommandPropertyAttribute;
namespace Server.Commands.Generic
{
public sealed class ObjectConditional
{
private static readonly Type typeofItem = typeof( Item );
private static readonly Type typeofMobile = typeof( Mobile );
public sealed class ObjectConditional
{
private static readonly Type typeofItem = typeof(Item);
private static readonly Type typeofMobile = typeof(Mobile);
private Type m_ObjectType;
public static readonly ObjectConditional Empty = new ObjectConditional(null, null);
private ICondition[][] m_Conditions;
private IConditional[] m_Conditionals;
private IConditional[] m_Conditionals;
private ICondition[][] m_Conditions;
public Type Type
{
get { return m_ObjectType; }
}
public ObjectConditional(Type objectType, ICondition[][] conditions)
{
Type = objectType;
m_Conditions = conditions;
}
public bool IsItem
{
get { return ( m_ObjectType == null || m_ObjectType == typeofItem || m_ObjectType.IsSubclassOf( typeofItem ) ); }
}
public Type Type{ get; }
public bool IsMobile
{
get { return ( m_ObjectType == null || m_ObjectType == typeofMobile || m_ObjectType.IsSubclassOf( typeofMobile ) ); }
}
public bool IsItem => Type == null || Type == typeofItem || Type.IsSubclassOf(typeofItem);
public static readonly ObjectConditional Empty = new ObjectConditional( null, null );
public bool IsMobile => Type == null || Type == typeofMobile || Type.IsSubclassOf(typeofMobile);
public bool HasCompiled
{
get { return ( m_Conditionals != null ); }
}
public bool HasCompiled => m_Conditionals != null;
public void Compile( ref AssemblyEmitter emitter )
{
if ( emitter == null )
emitter = new AssemblyEmitter( "__dynamic", false );
public void Compile(ref AssemblyEmitter emitter)
{
if (emitter == null)
emitter = new AssemblyEmitter("__dynamic", false);
m_Conditionals = new IConditional[m_Conditions.Length];
m_Conditionals = new IConditional[m_Conditions.Length];
for ( int i = 0; i < m_Conditionals.Length; ++i )
m_Conditionals[i] = ConditionalCompiler.Compile( emitter, m_ObjectType, m_Conditions[i], i );
}
for (int i = 0; i < m_Conditionals.Length; ++i)
m_Conditionals[i] = ConditionalCompiler.Compile(emitter, Type, m_Conditions[i], i);
}
public bool CheckCondition( object obj )
{
if ( m_ObjectType == null )
return true; // null type means no condition
public bool CheckCondition(object obj)
{
if (Type == null)
return true; // null type means no condition
if ( !HasCompiled )
{
AssemblyEmitter emitter = null;
if (!HasCompiled)
{
AssemblyEmitter emitter = null;
Compile( ref emitter );
}
Compile(ref emitter);
}
for ( int i = 0; i < m_Conditionals.Length; ++i )
{
if ( m_Conditionals[i].Verify( obj ) )
return true;
}
for (int i = 0; i < m_Conditionals.Length; ++i)
if (m_Conditionals[i].Verify(obj))
return true;
return false; // all conditions false
}
return false; // all conditions false
}
public static ObjectConditional Parse( Mobile from, ref string[] args )
{
string[] conditionArgs = null;
public static ObjectConditional Parse(Mobile from, ref string[] args)
{
string[] conditionArgs = null;
for ( int i = 0; i < args.Length; ++i )
{
if ( Insensitive.Equals( args[i], "where" ) )
{
string[] origArgs = args;
for (int i = 0; i < args.Length; ++i)
if (Insensitive.Equals(args[i], "where"))
{
string[] origArgs = args;
args = new string[i];
args = new string[i];
for ( int j = 0; j < args.Length; ++j )
args[j] = origArgs[j];
for (int j = 0; j < args.Length; ++j)
args[j] = origArgs[j];
conditionArgs = new string[origArgs.Length - i - 1];
conditionArgs = new string[origArgs.Length - i - 1];
for ( int j = 0; j < conditionArgs.Length; ++j )
conditionArgs[j] = origArgs[i + j + 1];
for (int j = 0; j < conditionArgs.Length; ++j)
conditionArgs[j] = origArgs[i + j + 1];
break;
}
}
break;
}
return ParseDirect( from, conditionArgs, 0, conditionArgs.Length );
}
return ParseDirect(from, conditionArgs, 0, conditionArgs.Length);
}
public static ObjectConditional ParseDirect( Mobile from, string[] args, int offset, int size )
{
if ( args == null || size == 0 )
return ObjectConditional.Empty;
public static ObjectConditional ParseDirect(Mobile from, string[] args, int offset, int size)
{
if (args == null || size == 0)
return Empty;
int index = 0;
int index = 0;
Type objectType = ScriptCompiler.FindTypeByName( args[offset + index], true );
Type objectType = ScriptCompiler.FindTypeByName(args[offset + index], true);
if ( objectType == null )
throw new Exception( String.Format( "No type with that name ({0}) was found.", args[offset + index] ) );
if (objectType == null)
throw new Exception($"No type with that name ({args[offset + index]}) was found.");
++index;
++index;
List<ICondition[]> conditions = new List<ICondition[]>();
List<ICondition> current = new List<ICondition>();
List<ICondition[]> conditions = new List<ICondition[]>();
List<ICondition> current = new List<ICondition>();
current.Add( TypeCondition.Default );
current.Add(TypeCondition.Default);
while ( index < size )
{
string cur = args[offset + index];
while (index < size)
{
string cur = args[offset + index];
bool inverse = false;
bool inverse = false;
if ( Insensitive.Equals( cur, "not" ) || cur == "!" )
{
inverse = true;
++index;
if (Insensitive.Equals(cur, "not") || cur == "!")
{
inverse = true;
++index;
if ( index >= size )
throw new Exception( "Improperly formatted object conditional." );
}
else if ( Insensitive.Equals( cur, "or" ) || cur == "||" )
{
if ( current.Count > 1 )
{
conditions.Add( current.ToArray() );
if (index >= size)
throw new Exception("Improperly formatted object conditional.");
}
else if (Insensitive.Equals(cur, "or") || cur == "||")
{
if (current.Count > 1)
{
conditions.Add(current.ToArray());
current.Clear();
current.Add( TypeCondition.Default );
}
current.Clear();
current.Add(TypeCondition.Default);
}
++index;
++index;
continue;
}
continue;
}
string binding = args[offset + index];
index++;
string binding = args[offset + index];
index++;
if ( index >= size )
throw new Exception( "Improperly formatted object conditional." );
if (index >= size)
throw new Exception("Improperly formatted object conditional.");
string oper = args[offset + index];
index++;
string oper = args[offset + index];
index++;
if ( index >= size )
throw new Exception( "Improperly formatted object conditional." );
if (index >= size)
throw new Exception("Improperly formatted object conditional.");
string val = args[offset + index];
index++;
string val = args[offset + index];
index++;
Property prop = new Property( binding );
Property prop = new Property(binding);
prop.BindTo( objectType, PropertyAccess.Read );
prop.CheckAccess( from );
prop.BindTo(objectType, PropertyAccess.Read);
prop.CheckAccess(from);
ICondition condition = null;
ICondition condition = null;
switch ( oper )
{
#region Equality
case "=":
case "==":
case "is":
condition = new ComparisonCondition( prop, inverse, ComparisonOperator.Equal, val );
break;
switch (oper)
{
#region Equality
case "!=":
condition = new ComparisonCondition( prop, inverse, ComparisonOperator.NotEqual, val );
break;
#endregion
case "=":
case "==":
case "is":
condition = new ComparisonCondition(prop, inverse, ComparisonOperator.Equal, val);
break;
#region Relational
case ">":
condition = new ComparisonCondition( prop, inverse, ComparisonOperator.Greater, val );
break;
case "!=":
condition = new ComparisonCondition(prop, inverse, ComparisonOperator.NotEqual, val);
break;
case "<":
condition = new ComparisonCondition( prop, inverse, ComparisonOperator.Lesser, val );
break;
#endregion
case ">=":
condition = new ComparisonCondition( prop, inverse, ComparisonOperator.GreaterEqual, val );
break;
#region Relational
case "<=":
condition = new ComparisonCondition( prop, inverse, ComparisonOperator.LesserEqual, val );
break;
#endregion
case ">":
condition = new ComparisonCondition(prop, inverse, ComparisonOperator.Greater, val);
break;
#region Strings
case "==~":
case "~==":
case "=~":
case "~=":
case "is~":
case "~is":
condition = new StringCondition( prop, inverse, StringOperator.Equal, val, true );
break;
case "!=~":
case "~!=":
condition = new StringCondition( prop, inverse, StringOperator.NotEqual, val, true );
break;
case "starts":
condition = new StringCondition( prop, inverse, StringOperator.StartsWith, val, false );
break;
case "starts~":
case "~starts":
condition = new StringCondition( prop, inverse, StringOperator.StartsWith, val, true );
break;
case "ends":
condition = new StringCondition( prop, inverse, StringOperator.EndsWith, val, false );
break;
case "ends~":
case "~ends":
condition = new StringCondition( prop, inverse, StringOperator.EndsWith, val, true );
break;
case "contains":
condition = new StringCondition( prop, inverse, StringOperator.Contains, val, false );
break;
case "contains~":
case "~contains":
condition = new StringCondition( prop, inverse, StringOperator.Contains, val, true );
break;
#endregion
}
if ( condition == null )
throw new InvalidOperationException( String.Format( "Unrecognized operator (\"{0}\").", oper ) );
current.Add( condition );
}
conditions.Add( current.ToArray() );
return new ObjectConditional( objectType, conditions.ToArray() );
}
public ObjectConditional( Type objectType, ICondition[][] conditions )
{
m_ObjectType = objectType;
m_Conditions = conditions;
}
}
case "<":
condition = new ComparisonCondition(prop, inverse, ComparisonOperator.Lesser, val);
break;
case ">=":
condition = new ComparisonCondition(prop, inverse, ComparisonOperator.GreaterEqual, val);
break;
case "<=":
condition = new ComparisonCondition(prop, inverse, ComparisonOperator.LesserEqual, val);
break;
#endregion
#region Strings
case "==~":
case "~==":
case "=~":
case "~=":
case "is~":
case "~is":
condition = new StringCondition(prop, inverse, StringOperator.Equal, val, true);
break;
case "!=~":
case "~!=":
condition = new StringCondition(prop, inverse, StringOperator.NotEqual, val, true);
break;
case "starts":
condition = new StringCondition(prop, inverse, StringOperator.StartsWith, val, false);
break;
case "starts~":
case "~starts":
condition = new StringCondition(prop, inverse, StringOperator.StartsWith, val, true);
break;
case "ends":
condition = new StringCondition(prop, inverse, StringOperator.EndsWith, val, false);
break;
case "ends~":
case "~ends":
condition = new StringCondition(prop, inverse, StringOperator.EndsWith, val, true);
break;
case "contains":
condition = new StringCondition(prop, inverse, StringOperator.Contains, val, false);
break;
case "contains~":
case "~contains":
condition = new StringCondition(prop, inverse, StringOperator.Contains, val, true);
break;
#endregion
}
if (condition == null)
throw new InvalidOperationException($"Unrecognized operator (\"{oper}\").");
current.Add(condition);
}
conditions.Add(current.ToArray());
return new ObjectConditional(objectType, conditions.ToArray());
}
}
}

View file

@ -1,67 +1,67 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Network;
namespace Server.Commands.Generic
{
public class OnlineCommandImplementor : BaseCommandImplementor
{
public OnlineCommandImplementor()
{
Accessors = new string[]{ "Online" };
SupportRequirement = CommandSupport.Online;
SupportsConditionals = true;
AccessLevel = AccessLevel.GameMaster;
Usage = "Online <command> [condition]";
Description = "Invokes the command on all mobiles that are currently logged in. Optional condition arguments can further restrict the set of objects.";
}
public class OnlineCommandImplementor : BaseCommandImplementor
{
public OnlineCommandImplementor()
{
Accessors = new[] { "Online" };
SupportRequirement = CommandSupport.Online;
SupportsConditionals = true;
AccessLevel = AccessLevel.GameMaster;
Usage = "Online <command> [condition]";
Description =
"Invokes the command on all mobiles that are currently logged in. Optional condition arguments can further restrict the set of objects.";
}
public override void Compile( Mobile from, BaseCommand command, ref string[] args, ref object obj )
{
try
{
Extensions ext = Extensions.Parse( from, ref args );
public override void Compile(Mobile from, BaseCommand command, ref string[] args, ref object obj)
{
try
{
Extensions ext = Extensions.Parse(from, ref args);
bool items, mobiles;
bool items, mobiles;
if ( !CheckObjectTypes( from, command, ext, out items, out mobiles ) )
return;
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
return;
if ( !mobiles ) // sanity check
{
command.LogFailure( "This command does not support items." );
return;
}
if (!mobiles) // sanity check
{
command.LogFailure("This command does not support items.");
return;
}
ArrayList list = new ArrayList();
ArrayList list = new ArrayList();
List<NetState> states = NetState.Instances;
List<NetState> states = NetState.Instances;
for ( int i = 0; i < states.Count; ++i )
{
NetState ns = states[i];
Mobile mob = ns.Mobile;
for (int i = 0; i < states.Count; ++i)
{
NetState ns = states[i];
Mobile mob = ns.Mobile;
if ( mob == null )
continue;
if (mob == null)
continue;
if( !BaseCommand.IsAccessible( from, mob ) )
continue;
if (!BaseCommand.IsAccessible(from, mob))
continue;
if ( ext.IsValid( mob ) )
list.Add( mob );
}
if (ext.IsValid(mob))
list.Add(mob);
}
ext.Filter( list );
ext.Filter(list);
obj = list;
}
catch ( Exception ex )
{
from.SendMessage( ex.Message );
}
}
}
obj = list;
}
catch (Exception ex)
{
from.SendMessage(ex.Message);
}
}
}
}

View file

@ -1,85 +1,79 @@
using System;
using Server;
namespace Server.Commands.Generic
{
public class RangeCommandImplementor : BaseCommandImplementor
{
private static RangeCommandImplementor m_Instance;
public class RangeCommandImplementor : BaseCommandImplementor
{
public RangeCommandImplementor()
{
Accessors = new[] { "Range" };
SupportRequirement = CommandSupport.Area;
SupportsConditionals = true;
AccessLevel = AccessLevel.GameMaster;
Usage = "Range <range> <command> [condition]";
Description =
"Invokes the command on all appropriate objects within a specified range of you. Optional condition arguments can further restrict the set of objects.";
public static RangeCommandImplementor Instance
{
get { return m_Instance; }
}
Instance = this;
}
public RangeCommandImplementor()
{
Accessors = new string[]{ "Range" };
SupportRequirement = CommandSupport.Area;
SupportsConditionals = true;
AccessLevel = AccessLevel.GameMaster;
Usage = "Range <range> <command> [condition]";
Description = "Invokes the command on all appropriate objects within a specified range of you. Optional condition arguments can further restrict the set of objects.";
public static RangeCommandImplementor Instance{ get; private set; }
m_Instance = this;
}
public override void Execute(CommandEventArgs e)
{
if (e.Length >= 2)
{
int range = e.GetInt32(0);
public override void Execute( CommandEventArgs e )
{
if ( e.Length >= 2 )
{
int range = e.GetInt32( 0 );
if (range < 0)
{
e.Mobile.SendMessage("The range must not be negative.");
}
else
{
Commands.TryGetValue(e.GetString(1), out BaseCommand command);
if ( range < 0 )
{
e.Mobile.SendMessage( "The range must not be negative." );
}
else
{
Commands.TryGetValue( e.GetString( 1 ), out BaseCommand command );
if (command == null)
{
e.Mobile.SendMessage(
"That is either an invalid command name or one that does not support this modifier.");
}
else if (e.Mobile.AccessLevel < command.AccessLevel)
{
e.Mobile.SendMessage("You do not have access to that command.");
}
else
{
string[] oldArgs = e.Arguments;
string[] args = new string[oldArgs.Length - 2];
if ( command == null )
{
e.Mobile.SendMessage( "That is either an invalid command name or one that does not support this modifier." );
}
else if ( e.Mobile.AccessLevel < command.AccessLevel )
{
e.Mobile.SendMessage( "You do not have access to that command." );
}
else
{
string[] oldArgs = e.Arguments;
string[] args = new string[oldArgs.Length - 2];
for (int i = 0; i < args.Length; ++i)
args[i] = oldArgs[i + 2];
for ( int i = 0; i < args.Length; ++i )
args[i] = oldArgs[i + 2];
Process(range, e.Mobile, command, args);
}
}
}
else
{
e.Mobile.SendMessage("You must supply a range and a command name.");
}
}
Process( range, e.Mobile, command, args );
}
}
}
else
{
e.Mobile.SendMessage( "You must supply a range and a command name." );
}
}
public void Process(int range, Mobile from, BaseCommand command, string[] args)
{
AreaCommandImplementor impl = AreaCommandImplementor.Instance;
public void Process( int range, Mobile from, BaseCommand command, string[] args )
{
AreaCommandImplementor impl = AreaCommandImplementor.Instance;
if (impl == null)
return;
if ( impl == null )
return;
Map map = from.Map;
Map map = from.Map;
if (map == null || map == Map.Internal)
return;
if ( map == null || map == Map.Internal )
return;
Point3D start = new Point3D(from.X - range, from.Y - range, from.Z);
Point3D end = new Point3D(from.X + range, from.Y + range, from.Z);
Point3D start = new Point3D( from.X - range, from.Y - range, from.Z );
Point3D end = new Point3D( from.X + range, from.Y + range, from.Z );
impl.OnTarget( from, map, start, end, new object[] { command, args } );
}
}
}
impl.OnTarget(from, map, start, end, new object[] { command, args });
}
}
}

View file

@ -1,61 +1,61 @@
using System;
using System.Collections;
using Server;
namespace Server.Commands.Generic
{
public class RegionCommandImplementor : BaseCommandImplementor
{
public RegionCommandImplementor()
{
Accessors = new string[]{ "Region" };
SupportRequirement = CommandSupport.Region;
SupportsConditionals = true;
AccessLevel = AccessLevel.GameMaster;
Usage = "Region <command> [condition]";
Description = "Invokes the command on all appropriate mobiles in your current region. Optional condition arguments can further restrict the set of objects.";
}
public class RegionCommandImplementor : BaseCommandImplementor
{
public RegionCommandImplementor()
{
Accessors = new[] { "Region" };
SupportRequirement = CommandSupport.Region;
SupportsConditionals = true;
AccessLevel = AccessLevel.GameMaster;
Usage = "Region <command> [condition]";
Description =
"Invokes the command on all appropriate mobiles in your current region. Optional condition arguments can further restrict the set of objects.";
}
public override void Compile( Mobile from, BaseCommand command, ref string[] args, ref object obj )
{
try
{
Extensions ext = Extensions.Parse( from, ref args );
public override void Compile(Mobile from, BaseCommand command, ref string[] args, ref object obj)
{
try
{
Extensions ext = Extensions.Parse(from, ref args);
bool items, mobiles;
bool items, mobiles;
if ( !CheckObjectTypes( from, command, ext, out items, out mobiles ) )
return;
if (!CheckObjectTypes(from, command, ext, out items, out mobiles))
return;
Region reg = from.Region;
Region reg = from.Region;
ArrayList list = new ArrayList();
ArrayList list = new ArrayList();
if ( mobiles )
{
foreach ( Mobile mob in reg.GetMobiles() )
{
if( !BaseCommand.IsAccessible( from, mob ) )
continue;
if (mobiles)
{
foreach (Mobile mob in reg.GetMobiles())
{
if (!BaseCommand.IsAccessible(from, mob))
continue;
if ( ext.IsValid( mob ) )
list.Add( mob );
}
}
else
{
command.LogFailure( "This command does not support items." );
return;
}
if (ext.IsValid(mob))
list.Add(mob);
}
}
else
{
command.LogFailure("This command does not support items.");
return;
}
ext.Filter( list );
ext.Filter(list);
obj = list;
}
catch ( Exception ex )
{
from.SendMessage( ex.Message );
}
}
}
obj = list;
}
catch (Exception ex)
{
from.SendMessage(ex.Message);
}
}
}
}

View file

@ -1,28 +1,23 @@
using System;
using Server;
namespace Server.Commands.Generic
{
public class ScreenCommandImplementor : BaseCommandImplementor
{
public ScreenCommandImplementor()
{
Accessors = new string[]{ "Screen" };
SupportRequirement = CommandSupport.Area;
SupportsConditionals = true;
AccessLevel = AccessLevel.GameMaster;
Usage = "Screen <command> [condition]";
Description = "Invokes the command on all appropriate objects in your screen. Optional condition arguments can further restrict the set of objects.";
}
public class ScreenCommandImplementor : BaseCommandImplementor
{
public ScreenCommandImplementor()
{
Accessors = new[] { "Screen" };
SupportRequirement = CommandSupport.Area;
SupportsConditionals = true;
AccessLevel = AccessLevel.GameMaster;
Usage = "Screen <command> [condition]";
Description =
"Invokes the command on all appropriate objects in your screen. Optional condition arguments can further restrict the set of objects.";
}
public override void Process( Mobile from, BaseCommand command, string[] args )
{
RangeCommandImplementor impl = RangeCommandImplementor.Instance;
public override void Process(Mobile from, BaseCommand command, string[] args)
{
RangeCommandImplementor impl = RangeCommandImplementor.Instance;
if ( impl == null )
return;
impl.Process( 18, from, command, args );
}
}
}
impl?.Process(18, from, command, args);
}
}
}

View file

@ -1,27 +1,22 @@
using System;
using System.Collections;
using Server;
using Server.Targeting;
namespace Server.Commands.Generic
{
public class SelfCommandImplementor : BaseCommandImplementor
{
public SelfCommandImplementor()
{
Accessors = new string[]{ "Self" };
SupportRequirement = CommandSupport.Self;
AccessLevel = AccessLevel.Counselor;
Usage = "Self <command>";
Description = "Invokes the command on the commanding player.";
}
public class SelfCommandImplementor : BaseCommandImplementor
{
public SelfCommandImplementor()
{
Accessors = new[] { "Self" };
SupportRequirement = CommandSupport.Self;
AccessLevel = AccessLevel.Counselor;
Usage = "Self <command>";
Description = "Invokes the command on the commanding player.";
}
public override void Compile( Mobile from, BaseCommand command, ref string[] args, ref object obj )
{
if ( command.ObjectTypes == ObjectTypes.Items )
return; // sanity check
public override void Compile(Mobile from, BaseCommand command, ref string[] args, ref object obj)
{
if (command.ObjectTypes == ObjectTypes.Items)
return; // sanity check
obj = from;
}
}
obj = from;
}
}
}

View file

@ -1,100 +1,96 @@
using System;
using System.Collections;
using Server;
using Server.Targeting;
namespace Server.Commands.Generic
{
public class SerialCommandImplementor : BaseCommandImplementor
{
public SerialCommandImplementor()
{
Accessors = new string[]{ "Serial" };
SupportRequirement = CommandSupport.Single;
AccessLevel = AccessLevel.Counselor;
Usage = "Serial <serial> <command>";
Description = "Invokes the command on a single object by serial.";
}
public class SerialCommandImplementor : BaseCommandImplementor
{
public SerialCommandImplementor()
{
Accessors = new[] { "Serial" };
SupportRequirement = CommandSupport.Single;
AccessLevel = AccessLevel.Counselor;
Usage = "Serial <serial> <command>";
Description = "Invokes the command on a single object by serial.";
}
public override void Execute( CommandEventArgs e )
{
if ( e.Length >= 2 )
{
Serial serial = e.GetInt32( 0 );
public override void Execute(CommandEventArgs e)
{
if (e.Length >= 2)
{
Serial serial = e.GetInt32(0);
object obj = null;
object obj = null;
if ( serial.IsItem )
obj = World.FindItem( serial );
else if ( serial.IsMobile )
obj = World.FindMobile( serial );
if (serial.IsItem)
obj = World.FindItem(serial);
else if (serial.IsMobile)
obj = World.FindMobile(serial);
if ( obj == null )
{
e.Mobile.SendMessage( "That is not a valid serial." );
}
else
{
Commands.TryGetValue( e.GetString( 1 ), out BaseCommand command );
if (obj == null)
{
e.Mobile.SendMessage("That is not a valid serial.");
}
else
{
Commands.TryGetValue(e.GetString(1), out BaseCommand command);
if ( command == null )
{
e.Mobile.SendMessage( "That is either an invalid command name or one that does not support this modifier." );
}
else if ( e.Mobile.AccessLevel < command.AccessLevel )
{
e.Mobile.SendMessage( "You do not have access to that command." );
}
else
{
switch ( command.ObjectTypes )
{
case ObjectTypes.Both:
{
if ( !(obj is Item) && !(obj is Mobile) )
{
e.Mobile.SendMessage( "This command does not work on that." );
return;
}
if (command == null)
{
e.Mobile.SendMessage(
"That is either an invalid command name or one that does not support this modifier.");
}
else if (e.Mobile.AccessLevel < command.AccessLevel)
{
e.Mobile.SendMessage("You do not have access to that command.");
}
else
{
switch (command.ObjectTypes)
{
// case ObjectTypes.Both:
// {
// if (!(obj is Item) && !(obj is Mobile))
// {
// e.Mobile.SendMessage("This command does not work on that.");
// return;
// }
//
// break;
// }
case ObjectTypes.Items:
{
if (!(obj is Item))
{
e.Mobile.SendMessage("This command only works on items.");
return;
}
break;
}
case ObjectTypes.Items:
{
if ( !(obj is Item) )
{
e.Mobile.SendMessage( "This command only works on items." );
return;
}
break;
}
case ObjectTypes.Mobiles:
{
if (!(obj is Mobile))
{
e.Mobile.SendMessage("This command only works on mobiles.");
return;
}
break;
}
case ObjectTypes.Mobiles:
{
if ( !(obj is Mobile) )
{
e.Mobile.SendMessage( "This command only works on mobiles." );
return;
}
break;
}
}
break;
}
}
string[] oldArgs = e.Arguments;
string[] args = new string[oldArgs.Length - 2];
string[] oldArgs = e.Arguments;
string[] args = new string[oldArgs.Length - 2];
for (int i = 0; i < args.Length; ++i)
args[i] = oldArgs[i + 2];
for ( int i = 0; i < args.Length; ++i )
args[i] = oldArgs[i + 2];
RunCommand( e.Mobile, obj, command, args );
}
}
}
else
{
e.Mobile.SendMessage( "You must supply an object serial and a command name." );
}
}
}
}
RunCommand(e.Mobile, obj, command, args);
}
}
}
else
{
e.Mobile.SendMessage("You must supply an object serial and a command name.");
}
}
}
}

View file

@ -1,94 +1,93 @@
using System;
using System.Collections;
using Server;
using Server.Targeting;
namespace Server.Commands.Generic
{
public class SingleCommandImplementor : BaseCommandImplementor
{
public SingleCommandImplementor()
{
Accessors = new string[]{ "Single" };
SupportRequirement = CommandSupport.Single;
AccessLevel = AccessLevel.Counselor;
Usage = "Single <command>";
Description = "Invokes the command on a single targeted object. This is the same as just invoking the command directly.";
}
public class SingleCommandImplementor : BaseCommandImplementor
{
public SingleCommandImplementor()
{
Accessors = new[] { "Single" };
SupportRequirement = CommandSupport.Single;
AccessLevel = AccessLevel.Counselor;
Usage = "Single <command>";
Description =
"Invokes the command on a single targeted object. This is the same as just invoking the command directly.";
}
public override void Register( BaseCommand command )
{
base.Register( command );
public override void Register(BaseCommand command)
{
base.Register(command);
for ( int i = 0; i < command.Commands.Length; ++i )
CommandSystem.Register( command.Commands[i], command.AccessLevel, new CommandEventHandler( Redirect ) );
}
for (int i = 0; i < command.Commands.Length; ++i)
CommandSystem.Register(command.Commands[i], command.AccessLevel, Redirect);
}
public void Redirect( CommandEventArgs e )
{
Commands.TryGetValue( e.Command, out BaseCommand command );
public void Redirect(CommandEventArgs e)
{
Commands.TryGetValue(e.Command, out BaseCommand command);
if ( command == null )
e.Mobile.SendMessage( "That is either an invalid command name or one that does not support this modifier." );
else if ( e.Mobile.AccessLevel < command.AccessLevel )
e.Mobile.SendMessage( "You do not have access to that command." );
else if ( command.ValidateArgs( this, e ) )
Process( e.Mobile, command, e.Arguments );
}
if (command == null)
e.Mobile.SendMessage("That is either an invalid command name or one that does not support this modifier.");
else if (e.Mobile.AccessLevel < command.AccessLevel)
e.Mobile.SendMessage("You do not have access to that command.");
else if (command.ValidateArgs(this, e))
Process(e.Mobile, command, e.Arguments);
}
public override void Process( Mobile from, BaseCommand command, string[] args )
{
if ( command.ValidateArgs( this, new CommandEventArgs( from, command.Commands[0], GenerateArgString( args ), args ) ) )
from.BeginTarget( -1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None, new TargetStateCallback( OnTarget ), new object[]{ command, args } );
}
public override void Process(Mobile from, BaseCommand command, string[] args)
{
if (command.ValidateArgs(this, new CommandEventArgs(from, command.Commands[0], GenerateArgString(args), args)))
from.BeginTarget(-1, command.ObjectTypes == ObjectTypes.All, TargetFlags.None,
new TargetStateCallback(OnTarget), new object[] { command, args });
}
public void OnTarget( Mobile from, object targeted, object state )
{
if ( !BaseCommand.IsAccessible( from, targeted ) )
{
from.SendMessage( "That is not accessible." );
return;
}
public void OnTarget(Mobile from, object targeted, object state)
{
if (!BaseCommand.IsAccessible(from, targeted))
{
from.SendMessage("That is not accessible.");
return;
}
object[] states = (object[])state;
BaseCommand command = (BaseCommand)states[0];
string[] args = (string[])states[1];
object[] states = (object[])state;
BaseCommand command = (BaseCommand)states[0];
string[] args = (string[])states[1];
switch ( command.ObjectTypes )
{
case ObjectTypes.Both:
{
if ( !(targeted is Item) && !(targeted is Mobile) )
{
from.SendMessage( "This command does not work on that." );
return;
}
switch (command.ObjectTypes)
{
case ObjectTypes.Both:
{
if (!(targeted is Item) && !(targeted is Mobile))
{
from.SendMessage("This command does not work on that.");
return;
}
break;
}
case ObjectTypes.Items:
{
if ( !(targeted is Item) )
{
from.SendMessage( "This command only works on items." );
return;
}
break;
}
case ObjectTypes.Items:
{
if (!(targeted is Item))
{
from.SendMessage("This command only works on items.");
return;
}
break;
}
case ObjectTypes.Mobiles:
{
if ( !(targeted is Mobile) )
{
from.SendMessage( "This command only works on mobiles." );
return;
}
break;
}
case ObjectTypes.Mobiles:
{
if (!(targeted is Mobile))
{
from.SendMessage("This command only works on mobiles.");
return;
}
break;
}
}
break;
}
}
RunCommand( from, targeted, command, args );
}
}
}
RunCommand(from, targeted, command, args);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,420 +1,411 @@
using System;
using Server;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Text;
using Server.Commands.Generic;
using Server.Gumps;
using Server.Network;
using Server.Commands;
using Server.Commands.Generic;
using CommandInfo=Server.Commands.Docs.DocCommandEntry;
using CommandInfoSorter=Server.Commands.Docs.CommandEntrySorter;
using CommandInfo = Server.Commands.Docs.DocCommandEntry;
using CommandInfoSorter = Server.Commands.Docs.CommandEntrySorter;
namespace Server.Commands
{
public class HelpInfo
{
public class HelpInfo
{
public static Dictionary<string, CommandInfo> HelpInfos{ get; } = new Dictionary<string, CommandInfo>();
private static Dictionary<string, CommandInfo> m_HelpInfos = new Dictionary<string, CommandInfo>();
private static List<CommandInfo> m_SortedHelpInfo = new List<CommandInfo>(); //No need for SortedList cause it's only sorted once at creation...
public static List<CommandInfo> SortedHelpInfo{ get; private set; } = new List<CommandInfo>();
public static Dictionary<string, CommandInfo> HelpInfos => m_HelpInfos;
public static List<CommandInfo> SortedHelpInfo => m_SortedHelpInfo;
[CallPriority(100)]
public static void Initialize()
{
CommandSystem.Register("HelpInfo", AccessLevel.Player, HelpInfo_OnCommand);
[CallPriority( 100 )]
public static void Initialize()
{
CommandSystem.Register( "HelpInfo", AccessLevel.Player, new CommandEventHandler( HelpInfo_OnCommand ) );
FillTable();
}
FillTable();
}
[Usage("HelpInfo [<command>]")]
[Description(
"Gives information on a specified command, or when no argument specified, displays a gump containing all commands")]
private static void HelpInfo_OnCommand(CommandEventArgs e)
{
if (e.Length > 0)
{
string arg = e.GetString(0).ToLower();
if (HelpInfos.TryGetValue(arg, out CommandInfo c))
{
Mobile m = e.Mobile;
[Usage( "HelpInfo [<command>]" )]
[Description( "Gives information on a specified command, or when no argument specified, displays a gump containing all commands" )]
private static void HelpInfo_OnCommand( CommandEventArgs e )
{
if( e.Length > 0 )
{
string arg = e.GetString( 0 ).ToLower();
if (m_HelpInfos.TryGetValue( arg, out CommandInfo c ))
{
Mobile m = e.Mobile;
if (m.AccessLevel >= c.AccessLevel)
m.SendGump(new CommandInfoGump(c));
else
m.SendMessage("You don't have access to that command.");
if( m.AccessLevel >= c.AccessLevel )
m.SendGump( new CommandInfoGump( c ) );
else
m.SendMessage( "You don't have access to that command." );
return;
}
return;
}
else
e.Mobile.SendMessage( String.Format( "Command '{0}' not found!", arg ) );
}
e.Mobile.SendMessage($"Command '{arg}' not found!");
}
e.Mobile.SendGump( new CommandListGump( 0, e.Mobile, null ) );
e.Mobile.SendGump(new CommandListGump(0, e.Mobile, null));
}
}
public static void FillTable()
{
List<CommandEntry> commands = new List<CommandEntry>(CommandSystem.Entries.Values);
List<CommandInfo> list = new List<CommandInfo>();
public static void FillTable()
{
List<CommandEntry> commands = new List<CommandEntry>( CommandSystem.Entries.Values );
List<CommandInfo> list = new List<CommandInfo>();
commands.Sort();
commands.Reverse();
Docs.Clean(commands);
commands.Sort();
commands.Reverse();
Docs.Clean( commands );
for (int i = 0; i < commands.Count; ++i)
{
CommandEntry e = commands[i];
for( int i = 0; i < commands.Count; ++i )
{
CommandEntry e =commands[i];
MethodInfo mi = e.Handler.Method;
MethodInfo mi = e.Handler.Method;
object[] attrs = mi.GetCustomAttributes(typeof(UsageAttribute), false);
object[] attrs = mi.GetCustomAttributes( typeof( UsageAttribute ), false );
if (attrs.Length == 0)
continue;
if( attrs.Length == 0 )
continue;
UsageAttribute usage = attrs[0] as UsageAttribute;
UsageAttribute usage = attrs[0] as UsageAttribute;
attrs = mi.GetCustomAttributes(typeof(DescriptionAttribute), false);
attrs = mi.GetCustomAttributes( typeof( DescriptionAttribute ), false );
if (attrs.Length == 0)
continue;
if( attrs.Length == 0 )
continue;
if (usage == null || !(attrs[0] is DescriptionAttribute desc))
continue;
DescriptionAttribute desc = attrs[0] as DescriptionAttribute;
attrs = mi.GetCustomAttributes(typeof(AliasesAttribute), false);
if( usage == null || desc == null )
continue;
AliasesAttribute aliases = attrs.Length == 0 ? null : attrs[0] as AliasesAttribute;
attrs = mi.GetCustomAttributes( typeof( AliasesAttribute ), false );
string descString = desc.Description.Replace("<", "(").Replace(">", ")");
AliasesAttribute aliases = (attrs.Length == 0 ? null : attrs[0] as AliasesAttribute);
if (aliases == null)
{
list.Add(new CommandInfo(e.AccessLevel, e.Command, null, usage.Usage, descString));
}
else
{
list.Add(new CommandInfo(e.AccessLevel, e.Command, aliases.Aliases, usage.Usage, descString));
string descString = desc.Description.Replace( "<", "(" ).Replace( ">", ")" );
for (int j = 0; j < aliases.Aliases.Length; j++)
{
string[] newAliases = new string[aliases.Aliases.Length];
if( aliases == null )
list.Add( new CommandInfo( e.AccessLevel, e.Command, null, usage.Usage, descString ) );
else
{
list.Add( new CommandInfo( e.AccessLevel, e.Command, aliases.Aliases, usage.Usage, descString ) );
aliases.Aliases.CopyTo(newAliases, 0);
for( int j = 0; j < aliases.Aliases.Length; j++ )
{
string[] newAliases = new string[aliases.Aliases.Length];
newAliases[j] = e.Command;
aliases.Aliases.CopyTo( newAliases, 0 );
list.Add(new CommandInfo(e.AccessLevel, aliases.Aliases[j], newAliases, usage.Usage, descString));
}
}
}
newAliases[j] = e.Command;
list.Add( new CommandInfo( e.AccessLevel, aliases.Aliases[j], newAliases, usage.Usage, descString ) );
}
}
}
for (int i = 0; i < TargetCommands.AllCommands.Count; ++i)
{
BaseCommand command = TargetCommands.AllCommands[i];
string usage = command.Usage;
string desc = command.Description;
for( int i = 0; i < TargetCommands.AllCommands.Count; ++i )
{
BaseCommand command = TargetCommands.AllCommands[i];
if (usage == null || desc == null)
continue;
string usage = command.Usage;
string desc = command.Description;
string[] cmds = command.Commands;
string cmd = cmds[0];
string[] aliases = new string[cmds.Length - 1];
if( usage == null || desc == null )
continue;
for (int j = 0; j < aliases.Length; ++j)
aliases[j] = cmds[j + 1];
string[] cmds = command.Commands;
string cmd = cmds[0];
string[] aliases = new string[cmds.Length - 1];
desc = desc.Replace("<", "(").Replace(">", ")");
for( int j = 0; j < aliases.Length; ++j )
aliases[j] = cmds[j + 1];
if (command.Supports != CommandSupport.Single)
{
StringBuilder sb = new StringBuilder(50 + desc.Length);
desc = desc.Replace( "<", "(" ).Replace( ">", ")" );
sb.Append("Modifiers: ");
if( command.Supports != CommandSupport.Single )
{
StringBuilder sb = new StringBuilder( 50 + desc.Length );
if ((command.Supports & CommandSupport.Global) != 0)
sb.Append("<i>Global</i>, ");
sb.Append( "Modifiers: " );
if ((command.Supports & CommandSupport.Online) != 0)
sb.Append("<i>Online</i>, ");
if( (command.Supports & CommandSupport.Global) != 0 )
sb.Append( "<i>Global</i>, " );
if ((command.Supports & CommandSupport.Region) != 0)
sb.Append("<i>Region</i>, ");
if( (command.Supports & CommandSupport.Online) != 0 )
sb.Append( "<i>Online</i>, " );
if ((command.Supports & CommandSupport.Contained) != 0)
sb.Append("<i>Contained</i>, ");
if( (command.Supports & CommandSupport.Region) != 0 )
sb.Append( "<i>Region</i>, " );
if ((command.Supports & CommandSupport.Multi) != 0)
sb.Append("<i>Multi</i>, ");
if( (command.Supports & CommandSupport.Contained) != 0 )
sb.Append( "<i>Contained</i>, " );
if ((command.Supports & CommandSupport.Area) != 0)
sb.Append("<i>Area</i>, ");
if( (command.Supports & CommandSupport.Multi) != 0 )
sb.Append( "<i>Multi</i>, " );
if ((command.Supports & CommandSupport.Self) != 0)
sb.Append("<i>Self</i>, ");
if( (command.Supports & CommandSupport.Area) != 0 )
sb.Append( "<i>Area</i>, " );
sb.Remove(sb.Length - 2, 2);
sb.Append("<br>");
sb.Append(desc);
if( (command.Supports & CommandSupport.Self) != 0 )
sb.Append( "<i>Self</i>, " );
desc = sb.ToString();
}
sb.Remove( sb.Length - 2, 2 );
sb.Append( "<br>" );
sb.Append( desc );
list.Add(new CommandInfo(command.AccessLevel, cmd, aliases, usage, desc));
desc = sb.ToString();
}
for (int j = 0; j < aliases.Length; j++)
{
string[] newAliases = new string[aliases.Length];
list.Add( new CommandInfo( command.AccessLevel, cmd, aliases, usage, desc ) );
aliases.CopyTo(newAliases, 0);
for( int j = 0; j < aliases.Length; j++ )
{
string[] newAliases = new string[aliases.Length];
newAliases[j] = cmd;
aliases.CopyTo( newAliases, 0 );
list.Add(new CommandInfo(command.AccessLevel, aliases[j], newAliases, usage, desc));
}
}
newAliases[j] = cmd;
List<BaseCommandImplementor> commandImpls = BaseCommandImplementor.Implementors;
list.Add( new CommandInfo( command.AccessLevel, aliases[j], newAliases, usage, desc ) );
}
}
for (int i = 0; i < commandImpls.Count; ++i)
{
BaseCommandImplementor command = commandImpls[i];
List<BaseCommandImplementor> commandImpls = BaseCommandImplementor.Implementors;
string usage = command.Usage;
string desc = command.Description;
for( int i = 0; i < commandImpls.Count; ++i )
{
BaseCommandImplementor command = commandImpls[i];
if (usage == null || desc == null)
continue;
string usage = command.Usage;
string desc = command.Description;
string[] cmds = command.Accessors;
string cmd = cmds[0];
string[] aliases = new string[cmds.Length - 1];
if( usage == null || desc == null )
continue;
for (int j = 0; j < aliases.Length; ++j)
aliases[j] = cmds[j + 1];
string[] cmds = command.Accessors;
string cmd = cmds[0];
string[] aliases = new string[cmds.Length - 1];
desc = desc.Replace("<", ")").Replace(">", ")");
for( int j = 0; j < aliases.Length; ++j )
aliases[j] = cmds[j + 1];
list.Add(new CommandInfo(command.AccessLevel, cmd, aliases, usage, desc));
desc = desc.Replace( "<", ")" ).Replace( ">", ")" );
for (int j = 0; j < aliases.Length; j++)
{
string[] newAliases = new string[aliases.Length];
list.Add( new CommandInfo( command.AccessLevel, cmd, aliases, usage, desc ) );
aliases.CopyTo(newAliases, 0);
for( int j = 0; j < aliases.Length; j++ )
{
string[] newAliases = new string[aliases.Length];
newAliases[j] = cmd;
aliases.CopyTo( newAliases, 0 );
list.Add(new CommandInfo(command.AccessLevel, aliases[j], newAliases, usage, desc));
}
}
newAliases[j] = cmd;
list.Sort(new CommandInfoSorter());
list.Add( new CommandInfo( command.AccessLevel, aliases[j], newAliases, usage, desc ) );
}
}
SortedHelpInfo = list;
list.Sort( new CommandInfoSorter() );
foreach (CommandInfo c in SortedHelpInfo)
if (!HelpInfos.ContainsKey(c.Name.ToLower()))
HelpInfos.Add(c.Name.ToLower(), c);
}
m_SortedHelpInfo = list;
public class CommandListGump : BaseGridGump
{
private const int EntriesPerPage = 15;
private List<CommandInfo> m_List;
foreach( CommandInfo c in m_SortedHelpInfo )
{
if( !m_HelpInfos.ContainsKey( c.Name.ToLower() ) )
m_HelpInfos.Add( c.Name.ToLower(), c );
}
}
private int m_Page;
public class CommandListGump : BaseGridGump
{
private const int EntriesPerPage = 15;
public CommandListGump(int page, Mobile from, List<CommandInfo> list)
: base(30, 30)
{
m_Page = page;
int m_Page;
List<CommandInfo> m_List;
if (list == null)
{
m_List = new List<CommandInfo>();
public CommandListGump( int page, Mobile from, List<CommandInfo> list )
: base( 30, 30 )
{
m_Page = page;
foreach (CommandInfo c in SortedHelpInfo)
if (from.AccessLevel >= c.AccessLevel)
m_List.Add(c);
}
else
{
m_List = list;
}
if( list == null )
{
m_List = new List<CommandInfo>();
foreach( CommandInfo c in m_SortedHelpInfo )
{
if( from.AccessLevel >= c.AccessLevel )
m_List.Add( c );
}
}
else
m_List = list;
AddNewPage();
if (m_Page > 0)
AddEntryButton(20, ArrowLeftID1, ArrowLeftID2, 1, ArrowLeftWidth, ArrowLeftHeight);
else
AddEntryHeader(20);
AddNewPage();
AddEntryHtml(160, Center(
$"Page {m_Page + 1} of {(m_List.Count + EntriesPerPage - 1) / EntriesPerPage}"));
if( m_Page > 0 )
AddEntryButton( 20, ArrowLeftID1, ArrowLeftID2, 1, ArrowLeftWidth, ArrowLeftHeight );
else
AddEntryHeader( 20 );
if ((m_Page + 1) * EntriesPerPage < m_List.Count)
AddEntryButton(20, ArrowRightID1, ArrowRightID2, 2, ArrowRightWidth, ArrowRightHeight);
else
AddEntryHeader(20);
AddEntryHtml( 160, Center( String.Format( "Page {0} of {1}", m_Page+1, (m_List.Count + EntriesPerPage - 1) / EntriesPerPage ) ) );
if( (m_Page + 1) * EntriesPerPage < m_List.Count )
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, 2, ArrowRightWidth, ArrowRightHeight );
else
AddEntryHeader( 20 );
int last = (int)AccessLevel.Player - 1;
for( int i = m_Page * EntriesPerPage, line = 0; line < EntriesPerPage && i < m_List.Count; ++i, ++line )
{
CommandInfo c = m_List[i];
if( from.AccessLevel >= c.AccessLevel )
{
if( (int)c.AccessLevel != last )
{
AddNewLine();
AddEntryHtml( 20 + OffsetSize + 160, Color( c.AccessLevel.ToString(), 0xFF0000 ) );
AddEntryHeader( 20 );
line++;
}
last = (int)c.AccessLevel;
AddNewLine();
AddEntryHtml( 20 + OffsetSize + 160, c.Name );
AddEntryButton( 20, ArrowRightID1, ArrowRightID2, 3 + i, ArrowRightWidth, ArrowRightHeight );
}
}
FinishPage();
}
public override void OnResponse( NetState sender, RelayInfo info )
{
Mobile m = sender.Mobile;
switch( info.ButtonID )
{
case 0:
{
m.CloseGump( typeof( CommandInfoGump ) );
break;
}
case 1:
{
if( m_Page > 0 )
m.SendGump( new CommandListGump( m_Page - 1, m, m_List ) );
break;
}
case 2:
{
if( (m_Page + 1) * EntriesPerPage < m_SortedHelpInfo.Count )
m.SendGump( new CommandListGump( m_Page + 1, m, m_List ) );
break;
}
default:
{
int v = info.ButtonID - 3;
if( v >= 0 && v < m_List.Count )
{
CommandInfo c = m_List[v];
if( m.AccessLevel >= c.AccessLevel )
{
m.SendGump( new CommandInfoGump( c ) );
m.SendGump( new CommandListGump( m_Page, m, m_List ) );
}
else
{
m.SendMessage( "You no longer have access to that command." );
m.SendGump( new CommandListGump( m_Page, m, null ) );
}
}
break;
}
}
}
}
public class CommandInfoGump : Gump
{
public string Color( string text, int color )
{
return String.Format( "<BASEFONT COLOR=#{0:X6}>{1}</BASEFONT>", color, text );
}
public string Center( string text )
{
return String.Format( "<CENTER>{0}</CENTER>", text );
}
public CommandInfoGump( CommandInfo info )
: this( info, 320, 200 )
{
}
public CommandInfoGump( CommandInfo info, int width, int height )
: base( 300, 50 )
{
AddPage( 0 );
AddBackground( 0, 0, width, height, 5054 );
//AddImageTiled( 10, 10, width - 20, 20, 2624 );
//AddAlphaRegion( 10, 10, width - 20, 20 );
//AddHtmlLocalized( 10, 10, width - 20, 20, header, headerColor, false, false );
AddHtml( 10, 10, width - 20, 20, Color( Center( info.Name ), 0xFF0000 ), false, false );
//AddImageTiled( 10, 40, width - 20, height - 80, 2624 );
//AddAlphaRegion( 10, 40, width - 20, height - 80 );
StringBuilder sb = new StringBuilder();
sb.Append( "Usage: " );
sb.Append( info.Usage.Replace( "<", "(" ).Replace( ">", ")" ) );
sb.Append( "<BR>" );
string[] aliases = info.Aliases;
if( aliases != null && aliases.Length != 0 )
{
sb.Append( String.Format( "Alias{0}: ", aliases.Length == 1 ? "" : "es" ) );
for( int i = 0; i < aliases.Length; ++i )
{
if( i != 0 )
sb.Append( ", " );
sb.Append( aliases[i] );
}
sb.Append( "<BR>" );
}
sb.Append( "AccessLevel: " );
sb.Append( info.AccessLevel.ToString() );
sb.Append( "<BR>" );
sb.Append( "<BR>" );
sb.Append( info.Description );
AddHtml( 10, 40, width - 20, height - 80, sb.ToString(), false, true );
//AddImageTiled( 10, height - 30, width - 20, 20, 2624 );
//AddAlphaRegion( 10, height - 30, width - 20, 20 );
}
}
}
}
int last = (int)AccessLevel.Player - 1;
for (int i = m_Page * EntriesPerPage, line = 0; line < EntriesPerPage && i < m_List.Count; ++i, ++line)
{
CommandInfo c = m_List[i];
if (from.AccessLevel >= c.AccessLevel)
{
if ((int)c.AccessLevel != last)
{
AddNewLine();
AddEntryHtml(20 + OffsetSize + 160, Color(c.AccessLevel.ToString(), 0xFF0000));
AddEntryHeader(20);
line++;
}
last = (int)c.AccessLevel;
AddNewLine();
AddEntryHtml(20 + OffsetSize + 160, c.Name);
AddEntryButton(20, ArrowRightID1, ArrowRightID2, 3 + i, ArrowRightWidth, ArrowRightHeight);
}
}
FinishPage();
}
public override void OnResponse(NetState sender, RelayInfo info)
{
Mobile m = sender.Mobile;
switch (info.ButtonID)
{
case 0:
{
m.CloseGump(typeof(CommandInfoGump));
break;
}
case 1:
{
if (m_Page > 0)
m.SendGump(new CommandListGump(m_Page - 1, m, m_List));
break;
}
case 2:
{
if ((m_Page + 1) * EntriesPerPage < SortedHelpInfo.Count)
m.SendGump(new CommandListGump(m_Page + 1, m, m_List));
break;
}
default:
{
int v = info.ButtonID - 3;
if (v >= 0 && v < m_List.Count)
{
CommandInfo c = m_List[v];
if (m.AccessLevel >= c.AccessLevel)
{
m.SendGump(new CommandInfoGump(c));
m.SendGump(new CommandListGump(m_Page, m, m_List));
}
else
{
m.SendMessage("You no longer have access to that command.");
m.SendGump(new CommandListGump(m_Page, m, null));
}
}
break;
}
}
}
}
public class CommandInfoGump : Gump
{
public CommandInfoGump(CommandInfo info)
: this(info, 320, 200)
{
}
public CommandInfoGump(CommandInfo info, int width, int height)
: base(300, 50)
{
AddPage(0);
AddBackground(0, 0, width, height, 5054);
//AddImageTiled( 10, 10, width - 20, 20, 2624 );
//AddAlphaRegion( 10, 10, width - 20, 20 );
//AddHtmlLocalized( 10, 10, width - 20, 20, header, headerColor, false, false );
AddHtml(10, 10, width - 20, 20, Color(Center(info.Name), 0xFF0000), false, false);
//AddImageTiled( 10, 40, width - 20, height - 80, 2624 );
//AddAlphaRegion( 10, 40, width - 20, height - 80 );
StringBuilder sb = new StringBuilder();
sb.Append("Usage: ");
sb.Append(info.Usage.Replace("<", "(").Replace(">", ")"));
sb.Append("<BR>");
string[] aliases = info.Aliases;
if (aliases != null && aliases.Length != 0)
{
sb.Append($"Alias{(aliases.Length == 1 ? "" : "es")}: ");
for (int i = 0; i < aliases.Length; ++i)
{
if (i != 0)
sb.Append(", ");
sb.Append(aliases[i]);
}
sb.Append("<BR>");
}
sb.Append("AccessLevel: ");
sb.Append(info.AccessLevel.ToString());
sb.Append("<BR>");
sb.Append("<BR>");
sb.Append(info.Description);
AddHtml(10, 40, width - 20, height - 80, sb.ToString(), false, true);
//AddImageTiled( 10, height - 30, width - 20, 20, 2624 );
//AddAlphaRegion( 10, height - 30, width - 20, 20 );
}
public string Color(string text, int color)
{
return $"<BASEFONT COLOR=#{color:X6}>{text}</BASEFONT>";
}
public string Center(string text)
{
return $"<CENTER>{text}</CENTER>";
}
}
}
}

View file

@ -1,147 +1,139 @@
using System;
using System.IO;
using Server;
using System.Text;
using Server.Accounting;
namespace Server.Commands
{
public class CommandLogging
{
private static StreamWriter m_Output;
private static bool m_Enabled = true;
public class CommandLogging
{
private static char[] m_NotSafe = { '\\', '/', ':', '*', '?', '"', '<', '>', '|' };
public static bool Enabled{ get; set; } = true;
public static bool Enabled{ get{ return m_Enabled; } set{ m_Enabled = value; } }
public static StreamWriter Output{ get; private set; }
public static StreamWriter Output{ get{ return m_Output; } }
public static void Initialize()
{
EventSink.Command += EventSink_Command;
public static void Initialize()
{
EventSink.Command += new CommandEventHandler( EventSink_Command );
if (!Directory.Exists("Logs"))
Directory.CreateDirectory("Logs");
if ( !Directory.Exists( "Logs" ) )
Directory.CreateDirectory( "Logs" );
string directory = "Logs/Commands";
string directory = "Logs/Commands";
if (!Directory.Exists(directory))
Directory.CreateDirectory(directory);
if ( !Directory.Exists( directory ) )
Directory.CreateDirectory( directory );
try
{
Output = new StreamWriter(Path.Combine(directory, $"{DateTime.UtcNow.ToLongDateString()}.log"), true);
try
{
m_Output = new StreamWriter( Path.Combine( directory, String.Format( "{0}.log", DateTime.UtcNow.ToLongDateString() ) ), true );
Output.AutoFlush = true;
m_Output.AutoFlush = true;
Output.WriteLine("##############################");
Output.WriteLine("Log started on {0}", DateTime.UtcNow);
Output.WriteLine();
}
catch
{
}
}
m_Output.WriteLine( "##############################" );
m_Output.WriteLine( "Log started on {0}", DateTime.UtcNow );
m_Output.WriteLine();
}
catch
{
}
}
public static object Format(object o)
{
if (o is Mobile m)
{
if (m.Account == null)
return $"{m} (no account)";
public static object Format( object o )
{
if ( o is Mobile )
{
Mobile m = (Mobile)o;
return $"{m} ('{m.Account.Username}')";
}
if ( m.Account == null )
return String.Format( "{0} (no account)", m );
else
return String.Format( "{0} ('{1}')", m, m.Account.Username );
}
else if ( o is Item )
{
Item item = (Item)o;
if (o is Item item) return $"0x{item.Serial.Value:X} ({item.GetType().Name})";
return String.Format( "0x{0:X} ({1})", item.Serial.Value, item.GetType().Name );
}
return o;
}
return o;
}
public static void WriteLine(Mobile from, string format, params object[] args)
{
if (!Enabled)
return;
public static void WriteLine( Mobile from, string format, params object[] args )
{
if ( !m_Enabled )
return;
WriteLine(from, string.Format(format, args));
}
WriteLine( from, String.Format( format, args ) );
}
public static void WriteLine(Mobile from, string text)
{
if (!Enabled)
return;
public static void WriteLine( Mobile from, string text )
{
if ( !m_Enabled )
return;
try
{
Output.WriteLine("{0}: {1}: {2}", DateTime.UtcNow, from.NetState, text);
try
{
m_Output.WriteLine( "{0}: {1}: {2}", DateTime.UtcNow, from.NetState, text );
string path = Core.BaseDirectory;
string path = Core.BaseDirectory;
string name = !(from.Account is Account acct) ? from.Name : acct.Username;
Account acct = from.Account as Account;
AppendPath(ref path, "Logs");
AppendPath(ref path, "Commands");
AppendPath(ref path, from.AccessLevel.ToString());
path = Path.Combine(path, $"{name}.log");
string name = ( acct == null ? from.Name : acct.Username );
using (StreamWriter sw = new StreamWriter(path, true))
{
sw.WriteLine("{0}: {1}: {2}", DateTime.UtcNow, from.NetState, text);
}
}
catch
{
}
}
AppendPath( ref path, "Logs" );
AppendPath( ref path, "Commands" );
AppendPath( ref path, from.AccessLevel.ToString() );
path = Path.Combine( path, String.Format( "{0}.log", name ) );
public static void AppendPath(ref string path, string toAppend)
{
path = Path.Combine(path, toAppend);
using ( StreamWriter sw = new StreamWriter( path, true ) )
sw.WriteLine( "{0}: {1}: {2}", DateTime.UtcNow, from.NetState, text );
}
catch
{
}
}
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
}
private static char[] m_NotSafe = new char[]{ '\\', '/', ':', '*', '?', '"', '<', '>', '|' };
public static string Safe(string ip)
{
if (ip == null)
return "null";
public static void AppendPath( ref string path, string toAppend )
{
path = Path.Combine( path, toAppend );
ip = ip.Trim();
if ( !Directory.Exists( path ) )
Directory.CreateDirectory( path );
}
if (ip.Length == 0)
return "empty";
public static string Safe( string ip )
{
if ( ip == null )
return "null";
bool isSafe = true;
ip = ip.Trim();
for (int i = 0; isSafe && i < m_NotSafe.Length; ++i)
isSafe = ip.IndexOf(m_NotSafe[i]) == -1;
if ( ip.Length == 0 )
return "empty";
if (isSafe)
return ip;
bool isSafe = true;
StringBuilder sb = new StringBuilder(ip);
for ( int i = 0; isSafe && i < m_NotSafe.Length; ++i )
isSafe = ( ip.IndexOf( m_NotSafe[i] ) == -1 );
for (int i = 0; i < m_NotSafe.Length; ++i)
sb.Replace(m_NotSafe[i], '_');
if ( isSafe )
return ip;
return sb.ToString();
}
System.Text.StringBuilder sb = new System.Text.StringBuilder( ip );
public static void EventSink_Command(CommandEventArgs e)
{
WriteLine(e.Mobile, "{0} {1} used command '{2} {3}'", e.Mobile.AccessLevel, Format(e.Mobile), e.Command,
e.ArgString);
}
for ( int i = 0; i < m_NotSafe.Length; ++i )
sb.Replace( m_NotSafe[i], '_' );
return sb.ToString();
}
public static void EventSink_Command( CommandEventArgs e )
{
WriteLine( e.Mobile, "{0} {1} used command '{2} {3}'", e.Mobile.AccessLevel, Format( e.Mobile ), e.Command, e.ArgString );
}
public static void LogChangeProperty( Mobile from, object o, string name, string value )
{
WriteLine( from, "{0} {1} set property '{2}' of {3} to '{4}'", from.AccessLevel, Format( from ), name, Format( o ), value );
}
}
public static void LogChangeProperty(Mobile from, object o, string name, string value)
{
WriteLine(from, "{0} {1} set property '{2}' of {3} to '{4}'", from.AccessLevel, Format(from), name, Format(o),
value);
}
}
}

View file

@ -1,404 +1,399 @@
using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using Server;
using System.IO;
using Server.Diagnostics;
namespace Server.Commands
{
public class Profiling
{
public static void Initialize()
{
CommandSystem.Register( "DumpTimers", AccessLevel.Administrator, new CommandEventHandler( DumpTimers_OnCommand ) );
CommandSystem.Register( "CountObjects", AccessLevel.Administrator, new CommandEventHandler( CountObjects_OnCommand ) );
CommandSystem.Register( "ProfileWorld", AccessLevel.Administrator, new CommandEventHandler( ProfileWorld_OnCommand ) );
CommandSystem.Register( "TraceInternal", AccessLevel.Administrator, new CommandEventHandler( TraceInternal_OnCommand ) );
CommandSystem.Register( "TraceExpanded", AccessLevel.Administrator, new CommandEventHandler( TraceExpanded_OnCommand ) );
CommandSystem.Register( "WriteProfiles", AccessLevel.Administrator, new CommandEventHandler( WriteProfiles_OnCommand ) );
CommandSystem.Register( "SetProfiles", AccessLevel.Administrator, new CommandEventHandler( SetProfiles_OnCommand ) );
}
[Usage( "WriteProfiles" )]
[Description( "Generates a log files containing performance diagnostic information." )]
public static void WriteProfiles_OnCommand( CommandEventArgs e )
{
try
{
using ( StreamWriter sw = new StreamWriter( "profiles.log", true ) )
{
sw.WriteLine( "# Dump on {0:f}", DateTime.UtcNow );
sw.WriteLine( "# Core profiling for " + Core.ProfileTime );
sw.WriteLine( "# Packet send" );
BaseProfile.WriteAll( sw, PacketSendProfile.Profiles );
sw.WriteLine();
sw.WriteLine( "# Packet receive" );
BaseProfile.WriteAll( sw, PacketReceiveProfile.Profiles );
sw.WriteLine();
sw.WriteLine( "# Timer" );
BaseProfile.WriteAll( sw, TimerProfile.Profiles );
sw.WriteLine();
sw.WriteLine( "# Gump response" );
BaseProfile.WriteAll( sw, GumpProfile.Profiles );
sw.WriteLine();
sw.WriteLine( "# Target response" );
BaseProfile.WriteAll( sw, TargetProfile.Profiles );
sw.WriteLine();
}
}
catch
{
}
}
[Usage( "SetProfiles [true | false]" )]
[Description( "Enables, disables, or toggles the state of core packet and timer profiling." )]
public static void SetProfiles_OnCommand( CommandEventArgs e )
{
if ( e.Length == 1 )
Core.Profiling = e.GetBoolean( 0 );
else
Core.Profiling = !Core.Profiling;
e.Mobile.SendMessage( "Profiling has been {0}.", Core.Profiling ? "enabled" : "disabled" );
}
[Usage( "DumpTimers" )]
[Description( "Generates a log file of all currently executing timers. Used for tracing timer leaks." )]
public static void DumpTimers_OnCommand( CommandEventArgs e )
{
try
{
using ( StreamWriter sw = new StreamWriter( "timerdump.log", true ) )
Timer.DumpInfo( sw );
}
catch
{
}
}
private class CountSorter : IComparer
{
public int Compare( object x, object y )
{
DictionaryEntry a = (DictionaryEntry)x;
DictionaryEntry b = (DictionaryEntry)y;
int aCount = GetCount( a.Value );
int bCount = GetCount( b.Value );
int v = -aCount.CompareTo( bCount );
if ( v == 0 )
{
Type aType = (Type)a.Key;
Type bType = (Type)b.Key;
v = aType.FullName.CompareTo( bType.FullName );
}
return v;
}
private int GetCount( object obj )
{
if ( obj is int )
return (int) obj;
if ( obj is int[] )
{
int[] list = (int[]) obj;
int total = 0;
for ( int i = 0; i < list.Length; ++i )
total += list[i];
return total;
}
return 0;
}
}
public class Profiling
{
public static void Initialize()
{
CommandSystem.Register("DumpTimers", AccessLevel.Administrator, DumpTimers_OnCommand);
CommandSystem.Register("CountObjects", AccessLevel.Administrator, CountObjects_OnCommand);
CommandSystem.Register("ProfileWorld", AccessLevel.Administrator, ProfileWorld_OnCommand);
CommandSystem.Register("TraceInternal", AccessLevel.Administrator, TraceInternal_OnCommand);
CommandSystem.Register("TraceExpanded", AccessLevel.Administrator, TraceExpanded_OnCommand);
CommandSystem.Register("WriteProfiles", AccessLevel.Administrator, WriteProfiles_OnCommand);
CommandSystem.Register("SetProfiles", AccessLevel.Administrator, SetProfiles_OnCommand);
}
[Usage("WriteProfiles")]
[Description("Generates a log files containing performance diagnostic information.")]
public static void WriteProfiles_OnCommand(CommandEventArgs e)
{
try
{
using (StreamWriter sw = new StreamWriter("profiles.log", true))
{
sw.WriteLine("# Dump on {0:f}", DateTime.UtcNow);
sw.WriteLine("# Core profiling for " + Core.ProfileTime);
sw.WriteLine("# Packet send");
BaseProfile.WriteAll(sw, PacketSendProfile.Profiles);
sw.WriteLine();
sw.WriteLine("# Packet receive");
BaseProfile.WriteAll(sw, PacketReceiveProfile.Profiles);
sw.WriteLine();
sw.WriteLine("# Timer");
BaseProfile.WriteAll(sw, TimerProfile.Profiles);
sw.WriteLine();
sw.WriteLine("# Gump response");
BaseProfile.WriteAll(sw, GumpProfile.Profiles);
sw.WriteLine();
sw.WriteLine("# Target response");
BaseProfile.WriteAll(sw, TargetProfile.Profiles);
sw.WriteLine();
}
}
catch
{
}
}
[Usage("SetProfiles [true | false]")]
[Description("Enables, disables, or toggles the state of core packet and timer profiling.")]
public static void SetProfiles_OnCommand(CommandEventArgs e)
{
if (e.Length == 1)
Core.Profiling = e.GetBoolean(0);
else
Core.Profiling = !Core.Profiling;
e.Mobile.SendMessage("Profiling has been {0}.", Core.Profiling ? "enabled" : "disabled");
}
[Usage("DumpTimers")]
[Description("Generates a log file of all currently executing timers. Used for tracing timer leaks.")]
public static void DumpTimers_OnCommand(CommandEventArgs e)
{
try
{
using (StreamWriter sw = new StreamWriter("timerdump.log", true))
{
Timer.DumpInfo(sw);
}
}
catch
{
}
}
[Usage("CountObjects")]
[Description("Generates a log file detailing all item and mobile types in the world.")]
public static void CountObjects_OnCommand(CommandEventArgs e)
{
using (StreamWriter op = new StreamWriter("objects.log"))
{
Hashtable table = new Hashtable();
foreach (Item item in World.Items.Values)
{
Type type = item.GetType();
object o = table[type];
if (o == null)
table[type] = 1;
else
table[type] = 1 + (int)o;
}
ArrayList items = new ArrayList(table);
table.Clear();
foreach (Mobile m in World.Mobiles.Values)
{
Type type = m.GetType();
object o = table[type];
if (o == null)
table[type] = 1;
else
table[type] = 1 + (int)o;
}
ArrayList mobiles = new ArrayList(table);
items.Sort(new CountSorter());
mobiles.Sort(new CountSorter());
op.WriteLine("# Object count table generated on {0}", DateTime.UtcNow);
op.WriteLine();
op.WriteLine();
op.WriteLine("# Items:");
foreach (DictionaryEntry de in items)
op.WriteLine("{0}\t{1:F2}%\t{2}", de.Value, 100 * (int)de.Value / (double)World.Items.Count, de.Key);
op.WriteLine();
op.WriteLine();
op.WriteLine("#Mobiles:");
foreach (DictionaryEntry de in mobiles)
op.WriteLine("{0}\t{1:F2}%\t{2}", de.Value, 100 * (int)de.Value / (double)World.Mobiles.Count, de.Key);
}
e.Mobile.SendMessage("Object table has been generated. See the file : <runuo root>/objects.log");
}
[Usage("TraceExpanded")]
[Description("Generates a log file describing all items using expanded memory.")]
public static void TraceExpanded_OnCommand(CommandEventArgs e)
{
Hashtable typeTable = new Hashtable();
foreach (Item item in World.Items.Values)
{
ExpandFlag flags = item.GetExpandFlags();
if ((flags & ~(ExpandFlag.TempFlag | ExpandFlag.SaveFlag)) == 0)
continue;
Type itemType = item.GetType();
do
{
if (!(typeTable[itemType] is int[] countTable))
typeTable[itemType] = countTable = new int[9];
if ((flags & ExpandFlag.Name) != 0)
++countTable[0];
if ((flags & ExpandFlag.Items) != 0)
++countTable[1];
if ((flags & ExpandFlag.Bounce) != 0)
++countTable[2];
if ((flags & ExpandFlag.Holder) != 0)
++countTable[3];
if ((flags & ExpandFlag.Blessed) != 0)
++countTable[4];
[Usage( "CountObjects" )]
[Description( "Generates a log file detailing all item and mobile types in the world." )]
public static void CountObjects_OnCommand( CommandEventArgs e )
{
using ( StreamWriter op = new StreamWriter( "objects.log" ) )
{
Hashtable table = new Hashtable();
/*if ( ( flags & ExpandFlag.TempFlag ) != 0 )
++countTable[5];
foreach ( Item item in World.Items.Values )
{
Type type = item.GetType();
if ( ( flags & ExpandFlag.SaveFlag ) != 0 )
++countTable[6];*/
if ((flags & ExpandFlag.Weight) != 0)
++countTable[7];
object o = (object)table[type];
if ( o == null )
table[type] = 1;
else
table[type] = 1 + (int)o;
}
ArrayList items = new ArrayList( table );
table.Clear();
foreach ( Mobile m in World.Mobiles.Values )
{
Type type = m.GetType();
object o = (object)table[type];
if ( o == null )
table[type] = 1;
else
table[type] = 1 + (int)o;
}
ArrayList mobiles = new ArrayList( table );
items.Sort( new CountSorter() );
mobiles.Sort( new CountSorter() );
op.WriteLine( "# Object count table generated on {0}", DateTime.UtcNow );
op.WriteLine();
op.WriteLine();
op.WriteLine( "# Items:" );
foreach ( DictionaryEntry de in items )
op.WriteLine( "{0}\t{1:F2}%\t{2}", de.Value, (100 * (int)de.Value) / (double)World.Items.Count, de.Key );
op.WriteLine();
op.WriteLine();
op.WriteLine( "#Mobiles:" );
foreach ( DictionaryEntry de in mobiles )
op.WriteLine( "{0}\t{1:F2}%\t{2}", de.Value, (100 * (int)de.Value) / (double)World.Mobiles.Count, de.Key );
}
e.Mobile.SendMessage( "Object table has been generated. See the file : <runuo root>/objects.log" );
}
[Usage( "TraceExpanded" )]
[Description( "Generates a log file describing all items using expanded memory." )]
public static void TraceExpanded_OnCommand( CommandEventArgs e )
{
Hashtable typeTable = new Hashtable();
foreach ( Item item in World.Items.Values )
{
ExpandFlag flags = item.GetExpandFlags();
if ( ( flags & ~(ExpandFlag.TempFlag | ExpandFlag.SaveFlag) ) == 0 )
continue;
Type itemType = item.GetType();
do
{
int[] countTable = typeTable[itemType] as int[];
if ( countTable == null )
typeTable[itemType] = countTable = new int[9];
if ( ( flags & ExpandFlag.Name ) != 0 )
++countTable[0];
if ( ( flags & ExpandFlag.Items ) != 0 )
++countTable[1];
if ( ( flags & ExpandFlag.Bounce ) != 0 )
++countTable[2];
if ( ( flags & ExpandFlag.Holder ) != 0 )
++countTable[3];
if ( ( flags & ExpandFlag.Blessed ) != 0 )
++countTable[4];
/*if ( ( flags & ExpandFlag.TempFlag ) != 0 )
++countTable[5];
if ( ( flags & ExpandFlag.SaveFlag ) != 0 )
++countTable[6];*/
if ( ( flags & ExpandFlag.Weight ) != 0 )
++countTable[7];
if ((flags & ExpandFlag.Spawner) != 0)
++countTable[8];
itemType = itemType.BaseType;
} while ( itemType != typeof( object ) );
}
try
{
using ( StreamWriter op = new StreamWriter( "expandedItems.log", true ) )
{
string[] names = new string[]
{
"Name",
"Items",
"Bounce",
"Holder",
"Blessed",
"TempFlag",
"SaveFlag",
"Weight",
"Spawner"
};
ArrayList list = new ArrayList( typeTable );
list.Sort( new CountSorter() );
foreach ( DictionaryEntry de in list )
{
Type itemType = de.Key as Type;
int[] countTable = de.Value as int[];
op.WriteLine( "# {0}", itemType.FullName );
for ( int i = 0; i < countTable.Length; ++i )
{
if ( countTable[i] > 0 )
op.WriteLine( "{0}\t{1:N0}", names[i], countTable[i] );
}
op.WriteLine();
}
}
}
catch
{
}
}
[Usage( "TraceInternal" )]
[Description( "Generates a log file describing all items in the 'internal' map." )]
public static void TraceInternal_OnCommand( CommandEventArgs e )
{
int totalCount = 0;
Hashtable table = new Hashtable();
foreach ( Item item in World.Items.Values )
{
if ( item.Parent != null || item.Map != Map.Internal )
continue;
++totalCount;
Type type = item.GetType();
int[] parms = (int[])table[type];
if ( parms == null )
table[type] = parms = new int[]{ 0, 0 };
parms[0]++;
parms[1] += item.Amount;
}
using ( StreamWriter op = new StreamWriter( "internal.log" ) )
{
op.WriteLine( "# {0} items found", totalCount );
op.WriteLine( "# {0} different types", table.Count );
op.WriteLine();
op.WriteLine();
op.WriteLine( "Type\t\tCount\t\tAmount\t\tAvg. Amount" );
foreach ( DictionaryEntry de in table )
{
Type type = (Type)de.Key;
int[] parms = (int[])de.Value;
op.WriteLine( "{0}\t\t{1}\t\t{2}\t\t{3:F2}", type.Name, parms[0], parms[1], (double)parms[1] / parms[0] );
}
}
}
[Usage( "ProfileWorld" )]
[Description( "Prints the amount of data serialized for every object type in your world file." )]
public static void ProfileWorld_OnCommand( CommandEventArgs e )
{
ProfileWorld( "items", "worldprofile_items.log" );
ProfileWorld( "mobiles", "worldprofile_mobiles.log" );
}
public static void ProfileWorld( string type, string opFile )
{
try
{
ArrayList types = new ArrayList();
using ( BinaryReader bin = new BinaryReader( new FileStream( String.Format( "Saves/{0}/{0}.tdb", type ), FileMode.Open, FileAccess.Read, FileShare.Read ) ) )
{
int count = bin.ReadInt32();
for ( int i = 0; i < count; ++i )
types.Add( ScriptCompiler.FindTypeByFullName( bin.ReadString() ) );
}
long total = 0;
Hashtable table = new Hashtable();
using ( BinaryReader bin = new BinaryReader( new FileStream( String.Format( "Saves/{0}/{0}.idx", type ), FileMode.Open, FileAccess.Read, FileShare.Read ) ) )
{
int count = bin.ReadInt32();
for ( int i = 0; i < count; ++i )
{
int typeID = bin.ReadInt32();
int serial = bin.ReadInt32();
long pos = bin.ReadInt64();
int length = bin.ReadInt32();
Type objType = (Type)types[typeID];
while ( objType != null && objType != typeof( object ) )
{
object obj = table[objType];
if ( obj == null )
table[objType] = length;
else
table[objType] = length + (int)obj;
objType = objType.BaseType;
total += length;
}
}
}
ArrayList list = new ArrayList( table );
list.Sort( new CountSorter() );
using ( StreamWriter op = new StreamWriter( opFile ) )
{
op.WriteLine( "# Profile of world {0}", type );
op.WriteLine( "# Generated on {0}", DateTime.UtcNow );
op.WriteLine();
op.WriteLine();
foreach ( DictionaryEntry de in list )
op.WriteLine( "{0}\t{1:F2}%\t{2}", de.Value, (100 * (int)de.Value) / (double)total, de.Key );
}
}
catch
{
}
}
}
if ((flags & ExpandFlag.Spawner) != 0)
++countTable[8];
itemType = itemType.BaseType;
} while (itemType != typeof(object));
}
try
{
using (StreamWriter op = new StreamWriter("expandedItems.log", true))
{
string[] names =
{
"Name",
"Items",
"Bounce",
"Holder",
"Blessed",
"TempFlag",
"SaveFlag",
"Weight",
"Spawner"
};
ArrayList list = new ArrayList(typeTable);
list.Sort(new CountSorter());
foreach (DictionaryEntry de in list)
{
Type itemType = de.Key as Type;
int[] countTable = de.Value as int[];
op.WriteLine("# {0}", itemType.FullName);
for (int i = 0; i < countTable.Length; ++i)
if (countTable[i] > 0)
op.WriteLine("{0}\t{1:N0}", names[i], countTable[i]);
op.WriteLine();
}
}
}
catch
{
}
}
[Usage("TraceInternal")]
[Description("Generates a log file describing all items in the 'internal' map.")]
public static void TraceInternal_OnCommand(CommandEventArgs e)
{
int totalCount = 0;
Hashtable table = new Hashtable();
foreach (Item item in World.Items.Values)
{
if (item.Parent != null || item.Map != Map.Internal)
continue;
++totalCount;
Type type = item.GetType();
int[] parms = (int[])table[type];
if (parms == null)
table[type] = parms = new[] { 0, 0 };
parms[0]++;
parms[1] += item.Amount;
}
using (StreamWriter op = new StreamWriter("internal.log"))
{
op.WriteLine("# {0} items found", totalCount);
op.WriteLine("# {0} different types", table.Count);
op.WriteLine();
op.WriteLine();
op.WriteLine("Type\t\tCount\t\tAmount\t\tAvg. Amount");
foreach (DictionaryEntry de in table)
{
Type type = (Type)de.Key;
int[] parms = (int[])de.Value;
op.WriteLine("{0}\t\t{1}\t\t{2}\t\t{3:F2}", type.Name, parms[0], parms[1], (double)parms[1] / parms[0]);
}
}
}
[Usage("ProfileWorld")]
[Description("Prints the amount of data serialized for every object type in your world file.")]
public static void ProfileWorld_OnCommand(CommandEventArgs e)
{
ProfileWorld("items", "worldprofile_items.log");
ProfileWorld("mobiles", "worldprofile_mobiles.log");
}
public static void ProfileWorld(string type, string opFile)
{
try
{
ArrayList types = new ArrayList();
using (BinaryReader bin = new BinaryReader(new FileStream(string.Format("Saves/{0}/{0}.tdb", type),
FileMode.Open, FileAccess.Read, FileShare.Read)))
{
int count = bin.ReadInt32();
for (int i = 0; i < count; ++i)
types.Add(ScriptCompiler.FindTypeByFullName(bin.ReadString()));
}
long total = 0;
Hashtable table = new Hashtable();
using (BinaryReader bin = new BinaryReader(new FileStream(string.Format("Saves/{0}/{0}.idx", type),
FileMode.Open, FileAccess.Read, FileShare.Read)))
{
int count = bin.ReadInt32();
for (int i = 0; i < count; ++i)
{
int typeID = bin.ReadInt32();
int serial = bin.ReadInt32();
long pos = bin.ReadInt64();
int length = bin.ReadInt32();
Type objType = (Type)types[typeID];
while (objType != null && objType != typeof(object))
{
object obj = table[objType];
if (obj == null)
table[objType] = length;
else
table[objType] = length + (int)obj;
objType = objType.BaseType;
total += length;
}
}
}
ArrayList list = new ArrayList(table);
list.Sort(new CountSorter());
using (StreamWriter op = new StreamWriter(opFile))
{
op.WriteLine("# Profile of world {0}", type);
op.WriteLine("# Generated on {0}", DateTime.UtcNow);
op.WriteLine();
op.WriteLine();
foreach (DictionaryEntry de in list)
op.WriteLine("{0}\t{1:F2}%\t{2}", de.Value, 100 * (int)de.Value / (double)total, de.Key);
}
}
catch
{
}
}
private class CountSorter : IComparer
{
public int Compare(object x, object y)
{
DictionaryEntry a = (DictionaryEntry)x;
DictionaryEntry b = (DictionaryEntry)y;
int aCount = GetCount(a.Value);
int bCount = GetCount(b.Value);
int v = -aCount.CompareTo(bCount);
if (v == 0)
{
Type aType = (Type)a.Key;
Type bType = (Type)b.Key;
v = aType.FullName.CompareTo(bType.FullName);
}
return v;
}
private int GetCount(object obj)
{
if (obj is int intObj)
return intObj;
if (obj is int[] list)
{
int total = 0;
for (int i = 0; i < list.Length; ++i)
total += list[i];
return total;
}
return 0;
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -2,18 +2,18 @@
namespace Server.Commands
{
public class ShardTime
{
public static void Initialize()
{
CommandSystem.Register( "Time", AccessLevel.Player, new CommandEventHandler( Time_OnCommand ) );
}
public class ShardTime
{
public static void Initialize()
{
CommandSystem.Register("Time", AccessLevel.Player, Time_OnCommand);
}
[Usage( "Time" )]
[Description( "Returns the server's local time." )]
private static void Time_OnCommand( CommandEventArgs e )
{
e.Mobile.SendMessage( DateTime.UtcNow.ToString() );
}
}
[Usage("Time")]
[Description("Returns the server's local time.")]
private static void Time_OnCommand(CommandEventArgs e)
{
e.Mobile.SendMessage(DateTime.UtcNow.ToString());
}
}
}

View file

@ -1,139 +1,148 @@
using System;
using System.Collections.Generic;
using System.IO;
using Server;
using Server.Items;
namespace Server.Commands
{
public class SignParser
{
private class SignEntry
{
public string m_Text;
public Point3D m_Location;
public int m_ItemID;
public int m_Map;
public class SignParser
{
private static Queue<Item> m_ToDelete = new Queue<Item>();
public SignEntry( string text, Point3D pt, int itemID, int mapLoc )
{
m_Text = text;
m_Location = pt;
m_ItemID = itemID;
m_Map = mapLoc;
}
}
public static void Initialize()
{
CommandSystem.Register("SignGen", AccessLevel.Administrator, SignGen_OnCommand);
}
public static void Initialize()
{
CommandSystem.Register( "SignGen", AccessLevel.Administrator, new CommandEventHandler( SignGen_OnCommand ) );
}
[Usage("SignGen")]
[Description("Generates world/shop signs on all facets.")]
public static void SignGen_OnCommand(CommandEventArgs c)
{
Parse(c.Mobile);
}
[Usage( "SignGen" )]
[Description( "Generates world/shop signs on all facets." )]
public static void SignGen_OnCommand( CommandEventArgs c )
{
Parse( c.Mobile );
}
public static void Parse(Mobile from)
{
string cfg = Path.Combine(Core.BaseDirectory, "Data/signs.cfg");
public static void Parse( Mobile from )
{
string cfg = Path.Combine( Core.BaseDirectory, "Data/signs.cfg" );
if (File.Exists(cfg))
{
List<SignEntry> list = new List<SignEntry>();
from.SendMessage("Generating signs, please wait.");
if ( File.Exists( cfg ) )
{
List<SignEntry> list = new List<SignEntry>();
from.SendMessage( "Generating signs, please wait." );
using (StreamReader ip = new StreamReader(cfg))
{
string line;
using ( StreamReader ip = new StreamReader( cfg ) )
{
string line;
while ((line = ip.ReadLine()) != null)
{
string[] split = line.Split(' ');
while ( (line = ip.ReadLine()) != null )
{
string[] split = line.Split( ' ' );
SignEntry e = new SignEntry(
line.Substring(split[0].Length + 1 + split[1].Length + 1 + split[2].Length + 1 +
split[3].Length + 1 + split[4].Length + 1),
new Point3D(Utility.ToInt32(split[2]), Utility.ToInt32(split[3]), Utility.ToInt32(split[4])),
Utility.ToInt32(split[1]), Utility.ToInt32(split[0]));
SignEntry e = new SignEntry(
line.Substring( split[0].Length + 1 + split[1].Length + 1 + split[2].Length + 1 + split[3].Length + 1 + split[4].Length + 1 ),
new Point3D( Utility.ToInt32( split[2] ), Utility.ToInt32( split[3] ), Utility.ToInt32( split[4] ) ),
Utility.ToInt32( split[1] ), Utility.ToInt32( split[0] ) );
list.Add(e);
}
}
list.Add( e );
}
}
Map[] brit = { Map.Felucca, Map.Trammel };
Map[] fel = { Map.Felucca };
Map[] tram = { Map.Trammel };
Map[] ilsh = { Map.Ilshenar };
Map[] malas = { Map.Malas };
Map[] tokuno = { Map.Tokuno };
Map[] brit = new Map[]{ Map.Felucca, Map.Trammel };
Map[] fel = new Map[]{ Map.Felucca };
Map[] tram = new Map[]{ Map.Trammel };
Map[] ilsh = new Map[]{ Map.Ilshenar };
Map[] malas = new Map[]{ Map.Malas };
Map[] tokuno = new Map[]{ Map.Tokuno };
for (int i = 0; i < list.Count; ++i)
{
SignEntry e = list[i];
Map[] maps = null;
for ( int i = 0; i < list.Count; ++i )
{
SignEntry e = list[i];
Map[] maps = null;
switch (e.m_Map)
{
case 0:
maps = brit;
break; // Trammel and Felucca
case 1:
maps = fel;
break; // Felucca
case 2:
maps = tram;
break; // Trammel
case 3:
maps = ilsh;
break; // Ilshenar
case 4:
maps = malas;
break; // Malas
case 5:
maps = tokuno;
break; // Tokuno Islands
}
switch ( e.m_Map )
{
case 0: maps = brit; break; // Trammel and Felucca
case 1: maps = fel; break; // Felucca
case 2: maps = tram; break; // Trammel
case 3: maps = ilsh; break; // Ilshenar
case 4: maps = malas; break; // Malas
case 5: maps = tokuno; break; // Tokuno Islands
}
for (int j = 0; maps != null && j < maps.Length; ++j)
Add_Static(e.m_ItemID, e.m_Location, maps[j], e.m_Text);
}
for ( int j = 0; maps != null && j < maps.Length; ++j )
Add_Static( e.m_ItemID, e.m_Location, maps[j], e.m_Text );
}
from.SendMessage("Sign generating complete.");
}
else
{
from.SendMessage("{0} not found!", cfg);
}
}
from.SendMessage( "Sign generating complete." );
}
else
{
from.SendMessage( "{0} not found!", cfg );
}
}
public static void Add_Static(int itemID, Point3D location, Map map, string name)
{
IPooledEnumerable<Item> eable = map.GetItemsInRange(location, 0);
private static Queue<Item> m_ToDelete = new Queue<Item>();
foreach (Item item in eable)
if (item is Sign && item.Z == location.Z && item.ItemID == itemID)
m_ToDelete.Enqueue(item);
public static void Add_Static( int itemID, Point3D location, Map map, string name )
{
IPooledEnumerable<Item> eable = map.GetItemsInRange( location, 0 );
eable.Free();
foreach ( Item item in eable )
{
if ( item is Sign && item.Z == location.Z && item.ItemID == itemID )
m_ToDelete.Enqueue( item );
}
while (m_ToDelete.Count > 0)
m_ToDelete.Dequeue().Delete();
eable.Free();
Item sign;
while ( m_ToDelete.Count > 0 )
m_ToDelete.Dequeue().Delete();
if (name.StartsWith("#"))
{
sign = new LocalizedSign(itemID, Utility.ToInt32(name.Substring(1)));
}
else
{
sign = new Sign(itemID);
sign.Name = name;
}
Item sign;
if (map == Map.Malas)
{
if (location.X >= 965 && location.Y >= 502 && location.X <= 1012 && location.Y <= 537)
sign.Hue = 0x47E;
else if (location.X >= 1960 && location.Y >= 1278 && location.X < 2106 && location.Y < 1413)
sign.Hue = 0x44E;
}
if ( name.StartsWith( "#" ) )
{
sign = new LocalizedSign( itemID, Utility.ToInt32( name.Substring( 1 ) ) );
}
else
{
sign = new Sign( itemID );
sign.Name = name;
}
sign.MoveToWorld(location, map);
}
if ( map == Map.Malas )
{
if ( location.X >= 965 && location.Y >= 502 && location.X <= 1012 && location.Y <= 537 )
sign.Hue = 0x47E;
else if ( location.X >= 1960 && location.Y >= 1278 && location.X < 2106 && location.Y < 1413 )
sign.Hue = 0x44E;
}
private class SignEntry
{
public int m_ItemID;
public Point3D m_Location;
public int m_Map;
public string m_Text;
sign.MoveToWorld( location, map );
}
}
}
public SignEntry(string text, Point3D pt, int itemID, int mapLoc)
{
m_Text = text;
m_Location = pt;
m_ItemID = itemID;
m_Map = mapLoc;
}
}
}
}

View file

@ -1,147 +1,131 @@
using System;
using System.Collections;
using Server;
using Server.Targeting;
namespace Server.Commands
{
public class SkillsCommand
{
public static void Initialize()
{
CommandSystem.Register( "SetSkill", AccessLevel.GameMaster, new CommandEventHandler( SetSkill_OnCommand ) );
CommandSystem.Register( "GetSkill", AccessLevel.GameMaster, new CommandEventHandler( GetSkill_OnCommand ) );
CommandSystem.Register( "SetAllSkills", AccessLevel.GameMaster, new CommandEventHandler( SetAllSkills_OnCommand ) );
}
public class SkillsCommand
{
public static void Initialize()
{
CommandSystem.Register("SetSkill", AccessLevel.GameMaster, SetSkill_OnCommand);
CommandSystem.Register("GetSkill", AccessLevel.GameMaster, GetSkill_OnCommand);
CommandSystem.Register("SetAllSkills", AccessLevel.GameMaster, SetAllSkills_OnCommand);
}
[Usage( "SetSkill <name> <value>" )]
[Description( "Sets a skill value by name of a targeted mobile." )]
public static void SetSkill_OnCommand( CommandEventArgs arg )
{
if ( arg.Length != 2 )
{
arg.Mobile.SendMessage( "SetSkill <skill name> <value>" );
}
else
{
SkillName skill;
if( Enum.TryParse( arg.GetString( 0 ), true, out skill ) )
{
arg.Mobile.Target = new SkillTarget( skill, arg.GetDouble( 1 ) );
}
else
{
arg.Mobile.SendLocalizedMessage( 1005631 ); // You have specified an invalid skill to set.
}
}
}
[Usage("SetSkill <name> <value>")]
[Description("Sets a skill value by name of a targeted mobile.")]
public static void SetSkill_OnCommand(CommandEventArgs arg)
{
if (arg.Length != 2)
{
arg.Mobile.SendMessage("SetSkill <skill name> <value>");
}
else
{
SkillName skill;
if (Enum.TryParse(arg.GetString(0), true, out skill))
arg.Mobile.Target = new SkillTarget(skill, arg.GetDouble(1));
else
arg.Mobile.SendLocalizedMessage(1005631); // You have specified an invalid skill to set.
}
}
[Usage( "SetAllSkills <name> <value>" )]
[Description( "Sets all skill values of a targeted mobile." )]
public static void SetAllSkills_OnCommand( CommandEventArgs arg )
{
if ( arg.Length != 1 )
{
arg.Mobile.SendMessage( "SetAllSkills <value>" );
}
else
{
arg.Mobile.Target = new AllSkillsTarget( arg.GetDouble( 0 ) );
}
}
[Usage("SetAllSkills <name> <value>")]
[Description("Sets all skill values of a targeted mobile.")]
public static void SetAllSkills_OnCommand(CommandEventArgs arg)
{
if (arg.Length != 1)
arg.Mobile.SendMessage("SetAllSkills <value>");
else
arg.Mobile.Target = new AllSkillsTarget(arg.GetDouble(0));
}
[Usage( "GetSkill <name>" )]
[Description( "Gets a skill value by name of a targeted mobile." )]
public static void GetSkill_OnCommand( CommandEventArgs arg )
{
if ( arg.Length != 1 )
{
arg.Mobile.SendMessage( "GetSkill <skill name>" );
}
else
{
SkillName skill;
if( Enum.TryParse( arg.GetString( 0 ), true, out skill ) )
{
arg.Mobile.Target = new SkillTarget( skill );
}
else
{
arg.Mobile.SendMessage( "You have specified an invalid skill to get." );
}
}
}
[Usage("GetSkill <name>")]
[Description("Gets a skill value by name of a targeted mobile.")]
public static void GetSkill_OnCommand(CommandEventArgs arg)
{
if (arg.Length != 1)
{
arg.Mobile.SendMessage("GetSkill <skill name>");
}
else
{
SkillName skill;
if (Enum.TryParse(arg.GetString(0), true, out skill))
arg.Mobile.Target = new SkillTarget(skill);
else
arg.Mobile.SendMessage("You have specified an invalid skill to get.");
}
}
public class AllSkillsTarget : Target
{
private double m_Value;
public class AllSkillsTarget : Target
{
private double m_Value;
public AllSkillsTarget( double value ) : base( -1, false, TargetFlags.None )
{
m_Value = value;
}
public AllSkillsTarget(double value) : base(-1, false, TargetFlags.None)
{
m_Value = value;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( targeted is Mobile )
{
Mobile targ = (Mobile)targeted;
Server.Skills skills = targ.Skills;
protected override void OnTarget(Mobile from, object targeted)
{
if (targeted is Mobile targ)
{
Server.Skills skills = targ.Skills;
for ( int i = 0; i < skills.Length; ++i )
skills[i].Base = m_Value;
for (int i = 0; i < skills.Length; ++i)
skills[i].Base = m_Value;
CommandLogging.LogChangeProperty( from, targ, "EverySkill.Base", m_Value.ToString() );
}
else
{
from.SendMessage( "That does not have skills!" );
}
}
}
CommandLogging.LogChangeProperty(from, targ, "EverySkill.Base", m_Value.ToString());
}
else
{
from.SendMessage("That does not have skills!");
}
}
}
public class SkillTarget : Target
{
private bool m_Set;
private SkillName m_Skill;
private double m_Value;
public class SkillTarget : Target
{
private bool m_Set;
private SkillName m_Skill;
private double m_Value;
public SkillTarget( SkillName skill, double value ) : base( -1, false, TargetFlags.None )
{
m_Set = true;
m_Skill = skill;
m_Value = value;
}
public SkillTarget(SkillName skill, double value) : base(-1, false, TargetFlags.None)
{
m_Set = true;
m_Skill = skill;
m_Value = value;
}
public SkillTarget( SkillName skill ) : base( -1, false, TargetFlags.None )
{
m_Set = false;
m_Skill = skill;
}
public SkillTarget(SkillName skill) : base(-1, false, TargetFlags.None)
{
m_Set = false;
m_Skill = skill;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( targeted is Mobile )
{
Mobile targ = (Mobile)targeted;
Skill skill = targ.Skills[m_Skill];
protected override void OnTarget(Mobile from, object targeted)
{
if (targeted is Mobile targ)
{
Skill skill = targ.Skills[m_Skill];
if ( skill == null )
return;
if (skill == null)
return;
if ( m_Set )
{
skill.Base = m_Value;
CommandLogging.LogChangeProperty( from, targ, String.Format( "{0}.Base", m_Skill ), m_Value.ToString() );
}
if (m_Set)
{
skill.Base = m_Value;
CommandLogging.LogChangeProperty(from, targ, $"{m_Skill}.Base", m_Value.ToString());
}
from.SendMessage( "{0} : {1} (Base: {2})", m_Skill, skill.Value, skill.Base );
}
else
{
from.SendMessage( "That does not have skills!" );
}
}
}
}
from.SendMessage("{0} : {1} (Base: {2})", m_Skill, skill.Value, skill.Base);
}
else
{
from.SendMessage("That does not have skills!");
}
}
}
}
}

View file

@ -1,40 +1,38 @@
using System;
using Server;
using Server.Targeting;
using Server.Gumps;
using Server.Targeting;
namespace Server.Commands
{
public class Skills
{
public static void Initialize()
{
Register();
}
public class Skills
{
public static void Initialize()
{
Register();
}
public static void Register()
{
CommandSystem.Register( "Skills", AccessLevel.Counselor, new CommandEventHandler( Skills_OnCommand ) );
}
public static void Register()
{
CommandSystem.Register("Skills", AccessLevel.Counselor, Skills_OnCommand);
}
private class SkillsTarget : Target
{
public SkillsTarget( ) : base( -1, true, TargetFlags.None )
{
}
[Usage("Skills")]
[Description("Opens a menu where you can view or edit skills of a targeted mobile.")]
private static void Skills_OnCommand(CommandEventArgs e)
{
e.Mobile.Target = new SkillsTarget();
}
protected override void OnTarget( Mobile from, object o )
{
if ( o is Mobile )
from.SendGump( new SkillsGump( from, (Mobile)o ) );
}
}
private class SkillsTarget : Target
{
public SkillsTarget() : base(-1, true, TargetFlags.None)
{
}
[Usage( "Skills" )]
[Description( "Opens a menu where you can view or edit skills of a targeted mobile." )]
private static void Skills_OnCommand( CommandEventArgs e )
{
e.Mobile.Target = new SkillsTarget();
}
}
protected override void OnTarget(Mobile from, object o)
{
if (o is Mobile mobile)
from.SendGump(new SkillsGump(from, mobile));
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,152 +1,141 @@
using System;
using System.Collections;
using Server;
using Server.Mobiles;
using Server.Targeting;
using Server.Network;
using System.Collections.Generic;
using Server.Mobiles;
using Server.Network;
using Server.Targeting;
namespace Server.Commands
{
public class VisibilityList
{
public static void Initialize()
{
EventSink.Login += new LoginEventHandler( OnLogin );
public class VisibilityList
{
public static void Initialize()
{
EventSink.Login += OnLogin;
CommandSystem.Register( "Vis", AccessLevel.Counselor, new CommandEventHandler( Vis_OnCommand ) );
CommandSystem.Register( "VisList", AccessLevel.Counselor, new CommandEventHandler( VisList_OnCommand ) );
CommandSystem.Register( "VisClear", AccessLevel.Counselor, new CommandEventHandler( VisClear_OnCommand ) );
}
CommandSystem.Register("Vis", AccessLevel.Counselor, Vis_OnCommand);
CommandSystem.Register("VisList", AccessLevel.Counselor, VisList_OnCommand);
CommandSystem.Register("VisClear", AccessLevel.Counselor, VisClear_OnCommand);
}
public static void OnLogin( LoginEventArgs e )
{
if ( e.Mobile is PlayerMobile )
{
PlayerMobile pm = (PlayerMobile)e.Mobile;
public static void OnLogin(LoginEventArgs e)
{
if (e.Mobile is PlayerMobile pm) pm.VisibilityList.Clear();
}
pm.VisibilityList.Clear();
}
}
[Usage("Vis")]
[Description(
"Adds or removes a targeted player from your visibility list. Anyone on your visibility list will be able to see you at all times, even when you're hidden.")]
public static void Vis_OnCommand(CommandEventArgs e)
{
if (e.Mobile is PlayerMobile)
{
e.Mobile.Target = new VisTarget();
e.Mobile.SendMessage("Select person to add or remove from your visibility list.");
}
}
[Usage( "Vis" )]
[Description( "Adds or removes a targeted player from your visibility list. Anyone on your visibility list will be able to see you at all times, even when you're hidden." )]
public static void Vis_OnCommand( CommandEventArgs e )
{
if ( e.Mobile is PlayerMobile )
{
e.Mobile.Target = new VisTarget();
e.Mobile.SendMessage( "Select person to add or remove from your visibility list." );
}
}
[Usage("VisList")]
[Description("Shows the names of everyone in your visibility list.")]
public static void VisList_OnCommand(CommandEventArgs e)
{
if (e.Mobile is PlayerMobile pm)
{
List<Mobile> list = pm.VisibilityList;
[Usage( "VisList" )]
[Description( "Shows the names of everyone in your visibility list." )]
public static void VisList_OnCommand( CommandEventArgs e )
{
if ( e.Mobile is PlayerMobile )
{
PlayerMobile pm = (PlayerMobile)e.Mobile;
List<Mobile> list = pm.VisibilityList;
if (list.Count > 0)
{
pm.SendMessage("You are visible to {0} mobile{1}:", list.Count, list.Count == 1 ? "" : "s");
if ( list.Count > 0 )
{
pm.SendMessage( "You are visible to {0} mobile{1}:", list.Count, list.Count == 1 ? "" : "s" );
for (int i = 0; i < list.Count; ++i)
pm.SendMessage("#{0}: {1}", i + 1, list[i].Name);
}
else
{
pm.SendMessage("Your visibility list is empty.");
}
}
}
for ( int i = 0; i < list.Count; ++i )
pm.SendMessage( "#{0}: {1}", i+1, list[i].Name );
}
else
{
pm.SendMessage( "Your visibility list is empty." );
}
}
}
[Usage("VisClear")]
[Description("Removes everyone from your visibility list.")]
public static void VisClear_OnCommand(CommandEventArgs e)
{
if (e.Mobile is PlayerMobile pm)
{
List<Mobile> list = new List<Mobile>(pm.VisibilityList);
[Usage( "VisClear" )]
[Description( "Removes everyone from your visibility list." )]
public static void VisClear_OnCommand( CommandEventArgs e )
{
if ( e.Mobile is PlayerMobile )
{
PlayerMobile pm = (PlayerMobile)e.Mobile;
List<Mobile> list = new List<Mobile>( pm.VisibilityList );
pm.VisibilityList.Clear();
pm.SendMessage( "Your visibility list has been cleared." );
pm.VisibilityList.Clear();
pm.SendMessage("Your visibility list has been cleared.");
for ( int i = 0; i < list.Count; ++i )
{
Mobile m = list[i];
for (int i = 0; i < list.Count; ++i)
{
Mobile m = list[i];
if ( !m.CanSee( pm ) && Utility.InUpdateRange( m, pm ) )
m.Send( pm.RemovePacket );
}
}
}
if (!m.CanSee(pm) && Utility.InUpdateRange(m, pm))
m.Send(pm.RemovePacket);
}
}
}
private class VisTarget : Target
{
public VisTarget() : base( -1, false, TargetFlags.None )
{
}
private class VisTarget : Target
{
public VisTarget() : base(-1, false, TargetFlags.None)
{
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( from is PlayerMobile && targeted is Mobile )
{
PlayerMobile pm = (PlayerMobile)from;
Mobile targ = (Mobile)targeted;
protected override void OnTarget(Mobile from, object targeted)
{
if (from is PlayerMobile pm && targeted is Mobile targ)
{
if (targ.AccessLevel <= pm.AccessLevel)
{
List<Mobile> list = pm.VisibilityList;
if ( targ.AccessLevel <= from.AccessLevel )
{
List<Mobile> list = pm.VisibilityList;
if (list.Contains(targ))
{
list.Remove(targ);
pm.SendMessage("{0} has been removed from your visibility list.", targ.Name);
}
else
{
list.Add(targ);
pm.SendMessage("{0} has been added to your visibility list.", targ.Name);
}
if ( list.Contains( targ ) )
{
list.Remove( targ );
from.SendMessage( "{0} has been removed from your visibility list.", targ.Name );
}
else
{
list.Add( targ );
from.SendMessage( "{0} has been added to your visibility list.", targ.Name );
}
if (Utility.InUpdateRange(targ, from))
{
NetState ns = targ.NetState;
if ( Utility.InUpdateRange( targ, from ) )
{
NetState ns = targ.NetState;
if (ns != null)
{
if (targ.CanSee(pm))
{
ns.Send(MobileIncoming.Create(ns, targ, pm));
if ( ns != null ) {
if ( targ.CanSee( from ) )
{
ns.Send(MobileIncoming.Create(ns, targ, from));
if (ObjectPropertyList.Enabled)
{
ns.Send(pm.OPLPacket);
if ( ObjectPropertyList.Enabled )
{
ns.Send( from.OPLPacket );
foreach ( Item item in from.Items )
ns.Send( item.OPLPacket );
}
}
else
{
ns.Send( from.RemovePacket );
}
}
}
}
else
{
from.SendMessage( "They can already see you!" );
}
}
else
{
from.SendMessage( "Add only mobiles to your visibility list." );
}
}
}
}
}
foreach (Item item in pm.Items)
ns.Send(item.OPLPacket);
}
}
else
{
ns.Send(pm.RemovePacket);
}
}
}
}
else
{
pm.SendMessage("They can already see you!");
}
}
else
{
from.SendMessage("Add only mobiles to your visibility list.");
}
}
}
}
}

View file

@ -1,102 +1,99 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Multis;
using Server.Targeting;
namespace Server.Commands
{
public class Wipe
{
[Flags]
public enum WipeType
{
Items = 0x01,
Mobiles = 0x02,
Multis = 0x04,
All = Items | Mobiles | Multis
}
public class Wipe
{
[Flags]
public enum WipeType
{
Items = 0x01,
Mobiles = 0x02,
Multis = 0x04,
All = Items | Mobiles | Multis
}
public static void Initialize()
{
CommandSystem.Register( "Wipe", AccessLevel.GameMaster, new CommandEventHandler( WipeAll_OnCommand ) );
CommandSystem.Register( "WipeItems", AccessLevel.GameMaster, new CommandEventHandler( WipeItems_OnCommand ) );
CommandSystem.Register( "WipeNPCs", AccessLevel.GameMaster, new CommandEventHandler( WipeNPCs_OnCommand ) );
CommandSystem.Register( "WipeMultis", AccessLevel.GameMaster, new CommandEventHandler( WipeMultis_OnCommand ) );
}
public static void Initialize()
{
CommandSystem.Register("Wipe", AccessLevel.GameMaster, WipeAll_OnCommand);
CommandSystem.Register("WipeItems", AccessLevel.GameMaster, WipeItems_OnCommand);
CommandSystem.Register("WipeNPCs", AccessLevel.GameMaster, WipeNPCs_OnCommand);
CommandSystem.Register("WipeMultis", AccessLevel.GameMaster, WipeMultis_OnCommand);
}
[Usage( "Wipe" )]
[Description( "Wipes all items and npcs in a targeted bounding box." )]
private static void WipeAll_OnCommand( CommandEventArgs e )
{
BeginWipe( e.Mobile, WipeType.Items | WipeType.Mobiles );
}
[Usage("Wipe")]
[Description("Wipes all items and npcs in a targeted bounding box.")]
private static void WipeAll_OnCommand(CommandEventArgs e)
{
BeginWipe(e.Mobile, WipeType.Items | WipeType.Mobiles);
}
[Usage( "WipeItems" )]
[Description( "Wipes all items in a targeted bounding box." )]
private static void WipeItems_OnCommand( CommandEventArgs e )
{
BeginWipe( e.Mobile, WipeType.Items );
}
[Usage("WipeItems")]
[Description("Wipes all items in a targeted bounding box.")]
private static void WipeItems_OnCommand(CommandEventArgs e)
{
BeginWipe(e.Mobile, WipeType.Items);
}
[Usage( "WipeNPCs" )]
[Description( "Wipes all npcs in a targeted bounding box." )]
private static void WipeNPCs_OnCommand( CommandEventArgs e )
{
BeginWipe( e.Mobile, WipeType.Mobiles );
}
[Usage("WipeNPCs")]
[Description("Wipes all npcs in a targeted bounding box.")]
private static void WipeNPCs_OnCommand(CommandEventArgs e)
{
BeginWipe(e.Mobile, WipeType.Mobiles);
}
[Usage( "WipeMultis" )]
[Description( "Wipes all multis in a targeted bounding box." )]
private static void WipeMultis_OnCommand( CommandEventArgs e )
{
BeginWipe( e.Mobile, WipeType.Multis );
}
[Usage("WipeMultis")]
[Description("Wipes all multis in a targeted bounding box.")]
private static void WipeMultis_OnCommand(CommandEventArgs e)
{
BeginWipe(e.Mobile, WipeType.Multis);
}
public static void BeginWipe( Mobile from, WipeType type )
{
BoundingBoxPicker.Begin( from, new BoundingBoxCallback( WipeBox_Callback ), type );
}
public static void BeginWipe(Mobile from, WipeType type)
{
BoundingBoxPicker.Begin(from, WipeBox_Callback, type);
}
private static void WipeBox_Callback( Mobile from, Map map, Point3D start, Point3D end, object state )
{
DoWipe( from, map, start, end, (WipeType)state );
}
private static void WipeBox_Callback(Mobile from, Map map, Point3D start, Point3D end, object state)
{
DoWipe(from, map, start, end, (WipeType)state);
}
public static void DoWipe( Mobile from, Map map, Point3D start, Point3D end, WipeType type )
{
CommandLogging.WriteLine( from, "{0} {1} wiping from {2} to {3} in {5} ({4})", from.AccessLevel, CommandLogging.Format( from ), start, end, type, map );
public static void DoWipe(Mobile from, Map map, Point3D start, Point3D end, WipeType type)
{
CommandLogging.WriteLine(from, "{0} {1} wiping from {2} to {3} in {5} ({4})", from.AccessLevel,
CommandLogging.Format(from), start, end, type, map);
bool mobiles = ( (type & WipeType.Mobiles) != 0 );
bool multis = ( (type & WipeType.Multis) != 0 );
bool items = ( (type & WipeType.Items) != 0 );
bool mobiles = (type & WipeType.Mobiles) != 0;
bool multis = (type & WipeType.Multis) != 0;
bool items = (type & WipeType.Items) != 0;
List<IEntity> toDelete = new List<IEntity>();
List<IEntity> toDelete = new List<IEntity>();
Rectangle2D rect = new Rectangle2D( start.X, start.Y, end.X - start.X + 1, end.Y - start.Y + 1 );
Rectangle2D rect = new Rectangle2D(start.X, start.Y, end.X - start.X + 1, end.Y - start.Y + 1);
IPooledEnumerable<IEntity> eable;
IPooledEnumerable<IEntity> eable;
if ( (items || multis) && mobiles )
eable = map.GetObjectsInBounds( rect, items || multis, mobiles );
else
return;
if (!items && !multis || !mobiles)
return;
eable = map.GetObjectsInBounds(rect, true, true);
foreach ( IEntity obj in eable )
{
if ( items && (obj is Item) && !((obj is BaseMulti) || (obj is HouseSign)) )
toDelete.Add( obj );
else if ( multis && (obj is BaseMulti) )
toDelete.Add( obj );
else if ( mobiles && (obj is Mobile) && !((Mobile)obj).Player )
toDelete.Add( obj );
}
foreach (IEntity obj in eable)
if (items && obj is Item && !(obj is BaseMulti || obj is HouseSign))
toDelete.Add(obj);
else if (multis && obj is BaseMulti)
toDelete.Add(obj);
else if (obj is Mobile mobile && !mobile.Player)
toDelete.Add(mobile);
eable.Free();
eable.Free();
for ( int i = 0; i < toDelete.Count; ++i )
toDelete[i].Delete();
}
}
}
for (int i = 0; i < toDelete.Count; ++i)
toDelete[i].Delete();
}
}
}

View file

@ -1,39 +1,37 @@
using System;
using Server.Mobiles;
using Server.Engines.PartySystem;
namespace Server.ContextMenus
{
public class AddToPartyEntry : ContextMenuEntry
{
private Mobile m_From;
private Mobile m_Target;
public AddToPartyEntry( Mobile from, Mobile target ) : base( 0197, 12 )
{
m_From = from;
m_Target = target;
}
public class AddToPartyEntry : ContextMenuEntry
{
private Mobile m_From;
private Mobile m_Target;
public override void OnClick()
{
Party p = Party.Get( m_From );
Party mp = Party.Get( m_Target );
public AddToPartyEntry(Mobile from, Mobile target) : base(0197, 12)
{
m_From = from;
m_Target = target;
}
if ( m_From == m_Target )
m_From.SendLocalizedMessage( 1005439 ); // You cannot add yourself to a party.
else if ( p != null && p.Leader != m_From )
m_From.SendLocalizedMessage( 1005453 ); // You may only add members to the party if you are the leader.
else if ( p != null && (p.Members.Count + p.Candidates.Count) >= Party.Capacity )
m_From.SendLocalizedMessage( 1008095 ); // You may only have 10 in your party (this includes candidates).
else if ( !m_Target.Player )
m_From.SendLocalizedMessage( 1005444 ); // The creature ignores your offer.
else if ( mp != null && mp == p )
m_From.SendLocalizedMessage( 1005440 ); // This person is already in your party!
else if ( mp != null )
m_From.SendLocalizedMessage( 1005441 ); // This person is already in a party!
else
Party.Invite( m_From, m_Target );
}
}
}
public override void OnClick()
{
Party p = Party.Get(m_From);
Party mp = Party.Get(m_Target);
if (m_From == m_Target)
m_From.SendLocalizedMessage(1005439); // You cannot add yourself to a party.
else if (p != null && p.Leader != m_From)
m_From.SendLocalizedMessage(1005453); // You may only add members to the party if you are the leader.
else if (p != null && p.Members.Count + p.Candidates.Count >= Party.Capacity)
m_From.SendLocalizedMessage(1008095); // You may only have 10 in your party (this includes candidates).
else if (!m_Target.Player)
m_From.SendLocalizedMessage(1005444); // The creature ignores your offer.
else if (mp != null && mp == p)
m_From.SendLocalizedMessage(1005440); // This person is already in your party!
else if (mp != null)
m_From.SendLocalizedMessage(1005441); // This person is already in a party!
else
Party.Invite(m_From, m_Target);
}
}
}

View file

@ -1,64 +1,60 @@
using System;
using Server.Items;
using Server.Network;
using Server.Targeting;
namespace Server.ContextMenus
{
public class AddToSpellbookEntry : ContextMenuEntry
{
public AddToSpellbookEntry() : base( 6144, 3 )
{
}
public class AddToSpellbookEntry : ContextMenuEntry
{
public AddToSpellbookEntry() : base(6144, 3)
{
}
public override void OnClick()
{
if ( Owner.From.CheckAlive() && Owner.Target is SpellScroll )
Owner.From.Target = new InternalTarget( (SpellScroll)Owner.Target );
}
public override void OnClick()
{
if (Owner.From.CheckAlive() && Owner.Target is SpellScroll scroll)
Owner.From.Target = new InternalTarget(scroll);
}
private class InternalTarget : Target
{
private SpellScroll m_Scroll;
private class InternalTarget : Target
{
private SpellScroll m_Scroll;
public InternalTarget( SpellScroll scroll ) : base( 3, false, TargetFlags.None )
{
m_Scroll = scroll;
}
public InternalTarget(SpellScroll scroll) : base(3, false, TargetFlags.None)
{
m_Scroll = scroll;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( targeted is Spellbook )
{
if ( from.CheckAlive() && !m_Scroll.Deleted && m_Scroll.Movable && m_Scroll.Amount >= 1 && m_Scroll.CheckItemUse( from ) )
{
Spellbook book = (Spellbook)targeted;
protected override void OnTarget(Mobile from, object targeted)
{
if (targeted is Spellbook book)
if (from.CheckAlive() && !m_Scroll.Deleted && m_Scroll.Movable && m_Scroll.Amount >= 1 &&
m_Scroll.CheckItemUse(from))
{
SpellbookType type = Spellbook.GetTypeForSpell(m_Scroll.SpellID);
SpellbookType type = Spellbook.GetTypeForSpell( m_Scroll.SpellID );
if (type != book.SpellbookType)
{
}
else if (book.HasSpell(m_Scroll.SpellID))
{
from.SendLocalizedMessage(500179); // That spell is already present in that spellbook.
}
else
{
int val = m_Scroll.SpellID - book.BookOffset;
if ( type != book.SpellbookType )
{
}
else if ( book.HasSpell( m_Scroll.SpellID ) )
{
from.SendLocalizedMessage( 500179 ); // That spell is already present in that spellbook.
}
else
{
int val = m_Scroll.SpellID - book.BookOffset;
if (val >= 0 && val < book.BookCount)
{
book.Content |= (ulong)1 << val;
if ( val >= 0 && val < book.BookCount )
{
book.Content |= (ulong)1 << val;
m_Scroll.Consume();
m_Scroll.Consume();
from.Send( new Network.PlaySound( 0x249, book.GetWorldLocation() ) );
}
}
}
}
}
}
}
from.Send(new PlaySound(0x249, book.GetWorldLocation()));
}
}
}
}
}
}
}

View file

@ -1,25 +1,24 @@
using System;
using Server.Items;
namespace Server.ContextMenus
{
public class EatEntry : ContextMenuEntry
{
private Mobile m_From;
private Food m_Food;
public class EatEntry : ContextMenuEntry
{
private Food m_Food;
private Mobile m_From;
public EatEntry( Mobile from, Food food ) : base( 6135, 1 )
{
m_From = from;
m_Food = food;
}
public EatEntry(Mobile from, Food food) : base(6135, 1)
{
m_From = from;
m_Food = food;
}
public override void OnClick()
{
if ( m_Food.Deleted || !m_Food.Movable || !m_From.CheckAlive() || !m_Food.CheckItemUse( m_From ) )
return;
public override void OnClick()
{
if (m_Food.Deleted || !m_Food.Movable || !m_From.CheckAlive() || !m_Food.CheckItemUse(m_From))
return;
m_Food.Eat( m_From );
}
}
m_Food.Eat(m_From);
}
}
}

View file

@ -1,31 +1,27 @@
using System;
using Server.Mobiles;
using Server.Multis;
namespace Server.ContextMenus
{
public class EjectPlayerEntry : ContextMenuEntry
{
private Mobile m_From;
private Mobile m_Target;
private BaseHouse m_TargetHouse;
public EjectPlayerEntry( Mobile from, Mobile target ) : base( 6206, 12 )
{
m_From = from;
m_Target = target;
m_TargetHouse = BaseHouse.FindHouseAt( m_Target );
}
public class EjectPlayerEntry : ContextMenuEntry
{
private Mobile m_From;
private Mobile m_Target;
private BaseHouse m_TargetHouse;
public override void OnClick()
{
if ( !m_From.Alive || m_TargetHouse.Deleted || !m_TargetHouse.IsFriend( m_From ) )
return;
public EjectPlayerEntry(Mobile from, Mobile target) : base(6206, 12)
{
m_From = from;
m_Target = target;
m_TargetHouse = BaseHouse.FindHouseAt(m_Target);
}
if ( m_Target is Mobile )
{
m_TargetHouse.Kick( m_From, (Mobile)m_Target );
}
}
}
}
public override void OnClick()
{
if (!m_From.Alive || m_TargetHouse.Deleted || !m_TargetHouse.IsFriend(m_From))
return;
if (m_Target is Mobile mobile)
m_TargetHouse.Kick(m_From, mobile);
}
}
}

View file

@ -1,30 +1,23 @@
using System;
using Server.Items;
namespace Server.ContextMenus
{
public class OpenBankEntry : ContextMenuEntry
{
private Mobile m_Banker;
public class OpenBankEntry : ContextMenuEntry
{
private Mobile m_Banker;
public OpenBankEntry( Mobile from, Mobile banker ) : base( 6105, 12 )
{
m_Banker = banker;
}
public OpenBankEntry(Mobile from, Mobile banker) : base(6105, 12)
{
m_Banker = banker;
}
public override void OnClick()
{
if ( !Owner.From.CheckAlive() )
return;
public override void OnClick()
{
if (!Owner.From.CheckAlive())
return;
if ( Owner.From.Criminal )
{
m_Banker.Say( 500378 ); // Thou art a criminal and cannot access thy bank box.
}
else
{
this.Owner.From.BankBox.Open();
}
}
}
if (Owner.From.Criminal)
m_Banker.Say(500378); // Thou art a criminal and cannot access thy bank box.
else
Owner.From.BankBox.Open();
}
}
}

View file

@ -1,30 +1,30 @@
using System;
using Server.Mobiles;
using Server.Network;
namespace Server.ContextMenus
{
public class TeachEntry : ContextMenuEntry
{
private SkillName m_Skill;
private BaseCreature m_Mobile;
private Mobile m_From;
public class TeachEntry : ContextMenuEntry
{
private Mobile m_From;
private BaseCreature m_Mobile;
private SkillName m_Skill;
public TeachEntry( SkillName skill, BaseCreature m, Mobile from, bool enabled ) : base( 6000 + (int)skill )
{
m_Skill = skill;
m_Mobile = m;
m_From = from;
public TeachEntry(SkillName skill, BaseCreature m, Mobile from, bool enabled) : base(6000 + (int)skill)
{
m_Skill = skill;
m_Mobile = m;
m_From = from;
if ( !enabled )
Flags |= Network.CMEFlags.Disabled;
}
if (!enabled)
Flags |= CMEFlags.Disabled;
}
public override void OnClick()
{
if ( !m_From.CheckAlive() )
return;
public override void OnClick()
{
if (!m_From.CheckAlive())
return;
m_Mobile.Teach( m_Skill, m_From, 0, false );
}
}
m_Mobile.Teach(m_Skill, m_From, 0, false);
}
}
}

View file

@ -1,88 +1,62 @@
using System;
namespace Server.Engines.BulkOrders
{
public class BOBFilter
{
private int m_Type;
private int m_Quality;
private int m_Material;
private int m_Quantity;
public class BOBFilter
{
public BOBFilter()
{
}
public bool IsDefault
{
get{ return ( m_Type == 0 && m_Quality == 0 && m_Material == 0 && m_Quantity == 0 ); }
}
public BOBFilter(GenericReader reader)
{
int version = reader.ReadEncodedInt();
public void Clear()
{
m_Type = 0;
m_Quality = 0;
m_Material = 0;
m_Quantity = 0;
}
switch (version)
{
case 1:
{
Type = reader.ReadEncodedInt();
Quality = reader.ReadEncodedInt();
Material = reader.ReadEncodedInt();
Quantity = reader.ReadEncodedInt();
public int Type
{
get{ return m_Type; }
set{ m_Type = value; }
}
break;
}
}
}
public int Quality
{
get{ return m_Quality; }
set{ m_Quality = value; }
}
public bool IsDefault => Type == 0 && Quality == 0 && Material == 0 && Quantity == 0;
public int Material
{
get{ return m_Material; }
set{ m_Material = value; }
}
public int Type{ get; set; }
public int Quantity
{
get{ return m_Quantity; }
set{ m_Quantity = value; }
}
public int Quality{ get; set; }
public BOBFilter()
{
}
public int Material{ get; set; }
public BOBFilter( GenericReader reader )
{
int version = reader.ReadEncodedInt();
public int Quantity{ get; set; }
switch ( version )
{
case 1:
{
m_Type = reader.ReadEncodedInt();
m_Quality = reader.ReadEncodedInt();
m_Material = reader.ReadEncodedInt();
m_Quantity = reader.ReadEncodedInt();
public void Clear()
{
Type = 0;
Quality = 0;
Material = 0;
Quantity = 0;
}
break;
}
}
}
public void Serialize(GenericWriter writer)
{
if (IsDefault)
{
writer.WriteEncodedInt(0); // version
}
else
{
writer.WriteEncodedInt(1); // version
public void Serialize( GenericWriter writer )
{
if ( IsDefault )
{
writer.WriteEncodedInt( 0 ); // version
}
else
{
writer.WriteEncodedInt( 1 ); // version
writer.WriteEncodedInt( m_Type );
writer.WriteEncodedInt( m_Quality );
writer.WriteEncodedInt( m_Material );
writer.WriteEncodedInt( m_Quantity );
}
}
}
writer.WriteEncodedInt(Type);
writer.WriteEncodedInt(Quality);
writer.WriteEncodedInt(Material);
writer.WriteEncodedInt(Quantity);
}
}
}
}

View file

@ -1,215 +1,224 @@
using System;
using System.Collections;
using Server;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
using Server.Network;
namespace Server.Engines.BulkOrders
{
public class BOBFilterGump : Gump
{
private PlayerMobile m_From;
private BulkOrderBook m_Book;
public class BOBFilterGump : Gump
{
private const int LabelColor = 0x7FFF;
private const int LabelColor = 0x7FFF;
private static int[,] m_MaterialFilters =
{
{ 1044067, 1 }, // Blacksmithy
{ 1062226, 3 }, // Iron
{ 1018332, 4 }, // Dull Copper
{ 1018333, 5 }, // Shadow Iron
{ 1018334, 6 }, // Copper
{ 1018335, 7 }, // Bronze
private static int[,] m_MaterialFilters = new int[,]
{
{ 1044067, 1 }, // Blacksmithy
{ 1062226, 3 }, // Iron
{ 1018332, 4 }, // Dull Copper
{ 1018333, 5 }, // Shadow Iron
{ 1018334, 6 }, // Copper
{ 1018335, 7 }, // Bronze
{ 0, 0 }, // --Blank--
{ 1018336, 8 }, // Golden
{ 1018337, 9 }, // Agapite
{ 1018338, 10 }, // Verite
{ 1018339, 11 }, // Valorite
{ 0, 0 }, // --Blank--
{ 0, 0 }, // --Blank--
{ 1018336, 8 }, // Golden
{ 1018337, 9 }, // Agapite
{ 1018338, 10 }, // Verite
{ 1018339, 11 }, // Valorite
{ 0, 0 }, // --Blank--
{ 1044094, 2 }, // Tailoring
{ 1044286, 12 }, // Cloth
{ 1062235, 13 }, // Leather
{ 1062236, 14 }, // Spined
{ 1062237, 15 }, // Horned
{ 1062238, 16 } // Barbed
};
{ 1044094, 2 }, // Tailoring
{ 1044286, 12 }, // Cloth
{ 1062235, 13 }, // Leather
{ 1062236, 14 }, // Spined
{ 1062237, 15 }, // Horned
{ 1062238, 16 } // Barbed
};
private static int[,] m_TypeFilters =
{
{ 1062229, 0 }, // All
{ 1062224, 1 }, // Small
{ 1062225, 2 } // Large
};
private static int[,] m_TypeFilters = new int[,]
{
{ 1062229, 0 }, // All
{ 1062224, 1 }, // Small
{ 1062225, 2 } // Large
};
private static int[,] m_QualityFilters =
{
{ 1062229, 0 }, // All
{ 1011542, 1 }, // Normal
{ 1060636, 2 } // Exceptional
};
private static int[,] m_QualityFilters = new int[,]
{
{ 1062229, 0 }, // All
{ 1011542, 1 }, // Normal
{ 1060636, 2 } // Exceptional
};
private static int[,] m_AmountFilters =
{
{ 1062229, 0 }, // All
{ 1049706, 1 }, // 10
{ 1016007, 2 }, // 15
{ 1062239, 3 } // 20
};
private static int[,] m_AmountFilters = new int[,]
{
{ 1062229, 0 }, // All
{ 1049706, 1 }, // 10
{ 1016007, 2 }, // 15
{ 1062239, 3 } // 20
};
private static int[][,] m_Filters =
{
m_TypeFilters,
m_QualityFilters,
m_MaterialFilters,
m_AmountFilters
};
private static int[][,] m_Filters = new int[][,]
{
m_TypeFilters,
m_QualityFilters,
m_MaterialFilters,
m_AmountFilters
};
private static int[] m_XOffsets_Type = { 0, 75, 170 };
private static int[] m_XOffsets_Quality = { 0, 75, 170 };
private static int[] m_XOffsets_Amount = { 0, 75, 180, 275 };
private static int[] m_XOffsets_Material = { 0, 105, 210, 305, 390, 485 };
private static int[] m_XOffsets_Type = new int[]{ 0, 75, 170 };
private static int[] m_XOffsets_Quality = new int[]{ 0, 75, 170 };
private static int[] m_XOffsets_Amount = new int[]{ 0, 75, 180, 275 };
private static int[] m_XOffsets_Material = new int[]{ 0, 105, 210, 305, 390, 485 };
private static int[] m_XWidths_Small = { 50, 50, 70, 50 };
private static int[] m_XWidths_Large = { 80, 50, 50, 50, 50, 50 };
private BulkOrderBook m_Book;
private PlayerMobile m_From;
private static int[] m_XWidths_Small = new int[]{ 50, 50, 70, 50 };
private static int[] m_XWidths_Large = new int[]{ 80, 50, 50, 50, 50, 50 };
public BOBFilterGump(PlayerMobile from, BulkOrderBook book) : base(12, 24)
{
from.CloseGump(typeof(BOBGump));
from.CloseGump(typeof(BOBFilterGump));
private void AddFilterList( int x, int y, int[] xOffsets, int yOffset, int[,] filters, int[] xWidths, int filterValue, int filterIndex )
{
for ( int i = 0; i < filters.GetLength( 0 ); ++i )
{
int number = filters[i, 0];
m_From = from;
m_Book = book;
if ( number == 0 )
continue;
BOBFilter f = from.UseOwnFilter ? from.BOBFilter : book.Filter;
bool isSelected = ( filters[i, 1] == filterValue );
AddPage(0);
if ( !isSelected && (i % xOffsets.Length) == 0 )
isSelected = ( filterValue == 0 );
AddBackground(10, 10, 600, 439, 5054);
AddHtmlLocalized( x + 35 + xOffsets[i % xOffsets.Length], y + ((i / xOffsets.Length) * yOffset), xWidths[i % xOffsets.Length], 32, number, isSelected ? 16927 : LabelColor, false, false );
AddButton( x + xOffsets[i % xOffsets.Length], y + ((i / xOffsets.Length) * yOffset), 4005, 4007, 4 + filterIndex + (i * 4), GumpButtonType.Reply, 0 );
}
}
AddImageTiled(18, 20, 583, 420, 2624);
AddAlphaRegion(18, 20, 583, 420);
public override void OnResponse( Server.Network.NetState sender, RelayInfo info )
{
BOBFilter f = ( m_From.UseOwnFilter ? m_From.BOBFilter : m_Book.Filter );
AddImage(5, 5, 10460);
AddImage(585, 5, 10460);
AddImage(5, 424, 10460);
AddImage(585, 424, 10460);
int index = info.ButtonID;
AddHtmlLocalized(270, 32, 200, 32, 1062223, LabelColor, false, false); // Filter Preference
switch ( index )
{
case 0: // Apply
{
m_From.SendGump( new BOBGump( m_From, m_Book ) );
AddHtmlLocalized(26, 64, 120, 32, 1062228, LabelColor, false, false); // Bulk Order Type
AddFilterList(25, 96, m_XOffsets_Type, 40, m_TypeFilters, m_XWidths_Small, f.Type, 0);
break;
}
case 1: // Set Book Filter
{
m_From.UseOwnFilter = false;
m_From.SendGump( new BOBFilterGump( m_From, m_Book ) );
AddHtmlLocalized(320, 64, 50, 32, 1062215, LabelColor, false, false); // Quality
AddFilterList(320, 96, m_XOffsets_Quality, 40, m_QualityFilters, m_XWidths_Small, f.Quality, 1);
break;
}
case 2: // Set Your Filter
{
m_From.UseOwnFilter = true;
m_From.SendGump( new BOBFilterGump( m_From, m_Book ) );
AddHtmlLocalized(26, 160, 120, 32, 1062232, LabelColor, false, false); // Material Type
AddFilterList(25, 192, m_XOffsets_Material, 40, m_MaterialFilters, m_XWidths_Large, f.Material, 2);
break;
}
case 3: // Clear Filter
{
f.Clear();
m_From.SendGump( new BOBFilterGump( m_From, m_Book ) );
AddHtmlLocalized(26, 320, 120, 32, 1062217, LabelColor, false, false); // Amount
AddFilterList(25, 352, m_XOffsets_Amount, 40, m_AmountFilters, m_XWidths_Small, f.Quantity, 3);
break;
}
default:
{
index -= 4;
AddHtmlLocalized(75, 416, 120, 32, 1062477, from.UseOwnFilter ? LabelColor : 16927, false,
false); // Set Book Filter
AddButton(40, 416, 4005, 4007, 1, GumpButtonType.Reply, 0);
int type = index % 4;
index /= 4;
AddHtmlLocalized(235, 416, 120, 32, 1062478, from.UseOwnFilter ? 16927 : LabelColor, false,
false); // Set Your Filter
AddButton(200, 416, 4005, 4007, 2, GumpButtonType.Reply, 0);
if ( type >= 0 && type < m_Filters.Length )
{
int[,] filters = m_Filters[type];
AddHtmlLocalized(405, 416, 120, 32, 1062231, LabelColor, false, false); // Clear Filter
AddButton(370, 416, 4005, 4007, 3, GumpButtonType.Reply, 0);
if ( index >= 0 && index < filters.GetLength( 0 ) )
{
if ( filters[index, 0] == 0 )
break;
AddHtmlLocalized(540, 416, 50, 32, 1011046, LabelColor, false, false); // APPLY
AddButton(505, 416, 4017, 4018, 0, GumpButtonType.Reply, 0);
}
switch ( type )
{
case 0: f.Type = filters[index, 1]; break;
case 1: f.Quality = filters[index, 1]; break;
case 2: f.Material = filters[index, 1]; break;
case 3: f.Quantity = filters[index, 1]; break;
}
private void AddFilterList(int x, int y, int[] xOffsets, int yOffset, int[,] filters, int[] xWidths, int filterValue,
int filterIndex)
{
for (int i = 0; i < filters.GetLength(0); ++i)
{
int number = filters[i, 0];
m_From.SendGump( new BOBFilterGump( m_From, m_Book ) );
}
}
if (number == 0)
continue;
break;
}
}
}
bool isSelected = filters[i, 1] == filterValue;
public BOBFilterGump( PlayerMobile from, BulkOrderBook book ) : base( 12, 24 )
{
from.CloseGump( typeof( BOBGump ) );
from.CloseGump( typeof( BOBFilterGump ) );
if (!isSelected && i % xOffsets.Length == 0)
isSelected = filterValue == 0;
m_From = from;
m_Book = book;
AddHtmlLocalized(x + 35 + xOffsets[i % xOffsets.Length], y + i / xOffsets.Length * yOffset,
xWidths[i % xOffsets.Length], 32, number, isSelected ? 16927 : LabelColor, false, false);
AddButton(x + xOffsets[i % xOffsets.Length], y + i / xOffsets.Length * yOffset, 4005, 4007,
4 + filterIndex + i * 4, GumpButtonType.Reply, 0);
}
}
BOBFilter f = ( from.UseOwnFilter ? from.BOBFilter : book.Filter );
public override void OnResponse(NetState sender, RelayInfo info)
{
BOBFilter f = m_From.UseOwnFilter ? m_From.BOBFilter : m_Book.Filter;
AddPage( 0 );
int index = info.ButtonID;
AddBackground( 10, 10, 600, 439, 5054 );
switch (index)
{
case 0: // Apply
{
m_From.SendGump(new BOBGump(m_From, m_Book));
AddImageTiled( 18, 20, 583, 420, 2624 );
AddAlphaRegion( 18, 20, 583, 420 );
break;
}
case 1: // Set Book Filter
{
m_From.UseOwnFilter = false;
m_From.SendGump(new BOBFilterGump(m_From, m_Book));
AddImage( 5, 5, 10460 );
AddImage( 585, 5, 10460 );
AddImage( 5, 424, 10460 );
AddImage( 585, 424, 10460 );
break;
}
case 2: // Set Your Filter
{
m_From.UseOwnFilter = true;
m_From.SendGump(new BOBFilterGump(m_From, m_Book));
AddHtmlLocalized( 270, 32, 200, 32, 1062223, LabelColor, false, false ); // Filter Preference
break;
}
case 3: // Clear Filter
{
f.Clear();
m_From.SendGump(new BOBFilterGump(m_From, m_Book));
AddHtmlLocalized( 26, 64, 120, 32, 1062228, LabelColor, false, false ); // Bulk Order Type
AddFilterList( 25, 96, m_XOffsets_Type, 40, m_TypeFilters, m_XWidths_Small, f.Type, 0 );
break;
}
default:
{
index -= 4;
AddHtmlLocalized( 320, 64, 50, 32, 1062215, LabelColor, false, false ); // Quality
AddFilterList( 320, 96, m_XOffsets_Quality, 40, m_QualityFilters, m_XWidths_Small, f.Quality, 1 );
int type = index % 4;
index /= 4;
AddHtmlLocalized( 26, 160, 120, 32, 1062232, LabelColor, false, false ); // Material Type
AddFilterList( 25, 192, m_XOffsets_Material, 40, m_MaterialFilters, m_XWidths_Large, f.Material, 2 );
if (type >= 0 && type < m_Filters.Length)
{
int[,] filters = m_Filters[type];
AddHtmlLocalized( 26, 320, 120, 32, 1062217, LabelColor, false, false ); // Amount
AddFilterList( 25, 352, m_XOffsets_Amount, 40, m_AmountFilters, m_XWidths_Small, f.Quantity, 3 );
if (index >= 0 && index < filters.GetLength(0))
{
if (filters[index, 0] == 0)
break;
AddHtmlLocalized( 75, 416, 120, 32, 1062477, ( from.UseOwnFilter ? LabelColor : 16927 ), false, false ); // Set Book Filter
AddButton( 40, 416, 4005, 4007, 1, GumpButtonType.Reply, 0 );
switch (type)
{
case 0:
f.Type = filters[index, 1];
break;
case 1:
f.Quality = filters[index, 1];
break;
case 2:
f.Material = filters[index, 1];
break;
case 3:
f.Quantity = filters[index, 1];
break;
}
AddHtmlLocalized( 235, 416, 120, 32, 1062478, ( from.UseOwnFilter ? 16927 : LabelColor ), false, false ); // Set Your Filter
AddButton( 200, 416, 4005, 4007, 2, GumpButtonType.Reply, 0 );
m_From.SendGump(new BOBFilterGump(m_From, m_Book));
}
}
AddHtmlLocalized( 405, 416, 120, 32, 1062231, LabelColor, false, false ); // Clear Filter
AddButton( 370, 416, 4005, 4007, 3, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 540, 416, 50, 32, 1011046, LabelColor, false, false ); // APPLY
AddButton( 505, 416, 4017, 4018, 0, GumpButtonType.Reply, 0 );
}
}
break;
}
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,110 +1,107 @@
using System;
namespace Server.Engines.BulkOrders
{
public class BOBLargeEntry
{
private bool m_RequireExceptional;
private BODType m_DeedType;
private BulkMaterialType m_Material;
private int m_AmountMax;
private int m_Price;
private BOBLargeSubEntry[] m_Entries;
public class BOBLargeEntry
{
public BOBLargeEntry(LargeBOD bod)
{
RequireExceptional = bod.RequireExceptional;
public bool RequireExceptional{ get{ return m_RequireExceptional; } }
public BODType DeedType{ get{ return m_DeedType; } }
public BulkMaterialType Material{ get{ return m_Material; } }
public int AmountMax{ get{ return m_AmountMax; } }
public int Price{ get{ return m_Price; } set{ m_Price = value; } }
public BOBLargeSubEntry[] Entries{ get{ return m_Entries; } }
if (bod is LargeTailorBOD)
DeedType = BODType.Tailor;
else if (bod is LargeSmithBOD)
DeedType = BODType.Smith;
public Item Reconstruct()
{
LargeBOD bod = null;
Material = bod.Material;
AmountMax = bod.AmountMax;
if ( m_DeedType == BODType.Smith )
bod = new LargeSmithBOD( m_AmountMax, m_RequireExceptional, m_Material, ReconstructEntries() );
else if ( m_DeedType == BODType.Tailor )
bod = new LargeTailorBOD( m_AmountMax, m_RequireExceptional, m_Material, ReconstructEntries() );
Entries = new BOBLargeSubEntry[bod.Entries.Length];
for ( int i = 0; bod != null && i < bod.Entries.Length; ++i )
bod.Entries[i].Owner = bod;
for (int i = 0; i < Entries.Length; ++i)
Entries[i] = new BOBLargeSubEntry(bod.Entries[i]);
}
return bod;
}
public BOBLargeEntry(GenericReader reader)
{
int version = reader.ReadEncodedInt();
private LargeBulkEntry[] ReconstructEntries()
{
LargeBulkEntry[] entries = new LargeBulkEntry[m_Entries.Length];
switch (version)
{
case 0:
{
RequireExceptional = reader.ReadBool();
for ( int i = 0; i < m_Entries.Length; ++i )
{
entries[i] = new LargeBulkEntry( null, new SmallBulkEntry( m_Entries[i].ItemType, m_Entries[i].Number, m_Entries[i].Graphic ) );
entries[i].Amount = m_Entries[i].AmountCur;
}
DeedType = (BODType)reader.ReadEncodedInt();
return entries;
}
Material = (BulkMaterialType)reader.ReadEncodedInt();
AmountMax = reader.ReadEncodedInt();
Price = reader.ReadEncodedInt();
public BOBLargeEntry( LargeBOD bod )
{
m_RequireExceptional = bod.RequireExceptional;
Entries = new BOBLargeSubEntry[reader.ReadEncodedInt()];
if ( bod is LargeTailorBOD )
m_DeedType = BODType.Tailor;
else if ( bod is LargeSmithBOD )
m_DeedType = BODType.Smith;
for (int i = 0; i < Entries.Length; ++i)
Entries[i] = new BOBLargeSubEntry(reader);
m_Material = bod.Material;
m_AmountMax = bod.AmountMax;
break;
}
}
}
m_Entries = new BOBLargeSubEntry[bod.Entries.Length];
public bool RequireExceptional{ get; }
for ( int i = 0; i < m_Entries.Length; ++i )
m_Entries[i] = new BOBLargeSubEntry( bod.Entries[i] );
}
public BODType DeedType{ get; }
public BOBLargeEntry( GenericReader reader )
{
int version = reader.ReadEncodedInt();
public BulkMaterialType Material{ get; }
switch ( version )
{
case 0:
{
m_RequireExceptional = reader.ReadBool();
public int AmountMax{ get; }
m_DeedType = (BODType)reader.ReadEncodedInt();
public int Price{ get; set; }
m_Material = (BulkMaterialType)reader.ReadEncodedInt();
m_AmountMax = reader.ReadEncodedInt();
m_Price = reader.ReadEncodedInt();
public BOBLargeSubEntry[] Entries{ get; }
m_Entries = new BOBLargeSubEntry[reader.ReadEncodedInt()];
public Item Reconstruct()
{
LargeBOD bod = null;
for ( int i = 0; i < m_Entries.Length; ++i )
m_Entries[i] = new BOBLargeSubEntry( reader );
if (DeedType == BODType.Smith)
bod = new LargeSmithBOD(AmountMax, RequireExceptional, Material, ReconstructEntries());
else if (DeedType == BODType.Tailor)
bod = new LargeTailorBOD(AmountMax, RequireExceptional, Material, ReconstructEntries());
break;
}
}
}
for (int i = 0; bod != null && i < bod.Entries.Length; ++i)
bod.Entries[i].Owner = bod;
public void Serialize( GenericWriter writer )
{
writer.WriteEncodedInt( 0 ); // version
return bod;
}
writer.Write( (bool) m_RequireExceptional );
private LargeBulkEntry[] ReconstructEntries()
{
LargeBulkEntry[] entries = new LargeBulkEntry[Entries.Length];
writer.WriteEncodedInt( (int) m_DeedType );
writer.WriteEncodedInt( (int) m_Material );
writer.WriteEncodedInt( (int) m_AmountMax );
writer.WriteEncodedInt( (int) m_Price );
for (int i = 0; i < Entries.Length; ++i)
{
entries[i] = new LargeBulkEntry(null,
new SmallBulkEntry(Entries[i].ItemType, Entries[i].Number, Entries[i].Graphic));
entries[i].Amount = Entries[i].AmountCur;
}
writer.WriteEncodedInt( (int) m_Entries.Length );
return entries;
}
for ( int i = 0; i < m_Entries.Length; ++i )
m_Entries[i].Serialize( writer );
}
}
public void Serialize(GenericWriter writer)
{
writer.WriteEncodedInt(0); // version
writer.Write(RequireExceptional);
writer.WriteEncodedInt((int)DeedType);
writer.WriteEncodedInt((int)Material);
writer.WriteEncodedInt(AmountMax);
writer.WriteEncodedInt(Price);
writer.WriteEncodedInt(Entries.Length);
for (int i = 0; i < Entries.Length; ++i)
Entries[i].Serialize(writer);
}
}
}

View file

@ -2,57 +2,55 @@ using System;
namespace Server.Engines.BulkOrders
{
public class BOBLargeSubEntry
{
private Type m_ItemType;
private int m_AmountCur;
private int m_Number;
private int m_Graphic;
public class BOBLargeSubEntry
{
public BOBLargeSubEntry(LargeBulkEntry lbe)
{
ItemType = lbe.Details.Type;
AmountCur = lbe.Amount;
Number = lbe.Details.Number;
Graphic = lbe.Details.Graphic;
}
public Type ItemType{ get{ return m_ItemType; } }
public int AmountCur{ get{ return m_AmountCur; } }
public int Number{ get{ return m_Number; } }
public int Graphic{ get{ return m_Graphic; } }
public BOBLargeSubEntry(GenericReader reader)
{
int version = reader.ReadEncodedInt();
public BOBLargeSubEntry( LargeBulkEntry lbe )
{
m_ItemType = lbe.Details.Type;
m_AmountCur = lbe.Amount;
m_Number = lbe.Details.Number;
m_Graphic = lbe.Details.Graphic;
}
switch (version)
{
case 0:
{
string type = reader.ReadString();
public BOBLargeSubEntry( GenericReader reader )
{
int version = reader.ReadEncodedInt();
if (type != null)
ItemType = ScriptCompiler.FindTypeByFullName(type);
switch ( version )
{
case 0:
{
string type = reader.ReadString();
AmountCur = reader.ReadEncodedInt();
Number = reader.ReadEncodedInt();
Graphic = reader.ReadEncodedInt();
if ( type != null )
m_ItemType = ScriptCompiler.FindTypeByFullName( type );
break;
}
}
}
m_AmountCur = reader.ReadEncodedInt();
m_Number = reader.ReadEncodedInt();
m_Graphic = reader.ReadEncodedInt();
public Type ItemType{ get; }
break;
}
}
}
public int AmountCur{ get; }
public void Serialize( GenericWriter writer )
{
writer.WriteEncodedInt( 0 ); // version
public int Number{ get; }
writer.Write( m_ItemType == null ? null : m_ItemType.FullName );
public int Graphic{ get; }
writer.WriteEncodedInt( (int) m_AmountCur );
writer.WriteEncodedInt( (int) m_Number );
writer.WriteEncodedInt( (int) m_Graphic );
}
}
public void Serialize(GenericWriter writer)
{
writer.WriteEncodedInt(0); // version
writer.Write(ItemType == null ? null : ItemType.FullName);
writer.WriteEncodedInt(AmountCur);
writer.WriteEncodedInt(Number);
writer.WriteEncodedInt(Graphic);
}
}
}

View file

@ -2,100 +2,99 @@ using System;
namespace Server.Engines.BulkOrders
{
public class BOBSmallEntry
{
private Type m_ItemType;
private bool m_RequireExceptional;
private BODType m_DeedType;
private BulkMaterialType m_Material;
private int m_AmountCur, m_AmountMax;
private int m_Number;
private int m_Graphic;
private int m_Price;
public class BOBSmallEntry
{
public BOBSmallEntry(SmallBOD bod)
{
ItemType = bod.Type;
RequireExceptional = bod.RequireExceptional;
public Type ItemType{ get{ return m_ItemType; } }
public bool RequireExceptional{ get{ return m_RequireExceptional; } }
public BODType DeedType{ get{ return m_DeedType; } }
public BulkMaterialType Material{ get{ return m_Material; } }
public int AmountCur{ get{ return m_AmountCur; } }
public int AmountMax{ get{ return m_AmountMax; } }
public int Number{ get{ return m_Number; } }
public int Graphic{ get{ return m_Graphic; } }
public int Price{ get{ return m_Price; } set{ m_Price = value; } }
if (bod is SmallTailorBOD)
DeedType = BODType.Tailor;
else if (bod is SmallSmithBOD)
DeedType = BODType.Smith;
public Item Reconstruct()
{
SmallBOD bod = null;
Material = bod.Material;
AmountCur = bod.AmountCur;
AmountMax = bod.AmountMax;
Number = bod.Number;
Graphic = bod.Graphic;
}
if ( m_DeedType == BODType.Smith )
bod = new SmallSmithBOD( m_AmountCur, m_AmountMax, m_ItemType, m_Number, m_Graphic, m_RequireExceptional, m_Material );
else if ( m_DeedType == BODType.Tailor )
bod = new SmallTailorBOD( m_AmountCur, m_AmountMax, m_ItemType, m_Number, m_Graphic, m_RequireExceptional, m_Material );
public BOBSmallEntry(GenericReader reader)
{
int version = reader.ReadEncodedInt();
return bod;
}
switch (version)
{
case 0:
{
string type = reader.ReadString();
public BOBSmallEntry( SmallBOD bod )
{
m_ItemType = bod.Type;
m_RequireExceptional = bod.RequireExceptional;
if (type != null)
ItemType = ScriptCompiler.FindTypeByFullName(type);
if ( bod is SmallTailorBOD )
m_DeedType = BODType.Tailor;
else if ( bod is SmallSmithBOD )
m_DeedType = BODType.Smith;
RequireExceptional = reader.ReadBool();
m_Material = bod.Material;
m_AmountCur = bod.AmountCur;
m_AmountMax = bod.AmountMax;
m_Number = bod.Number;
m_Graphic = bod.Graphic;
}
DeedType = (BODType)reader.ReadEncodedInt();
public BOBSmallEntry( GenericReader reader )
{
int version = reader.ReadEncodedInt();
Material = (BulkMaterialType)reader.ReadEncodedInt();
AmountCur = reader.ReadEncodedInt();
AmountMax = reader.ReadEncodedInt();
Number = reader.ReadEncodedInt();
Graphic = reader.ReadEncodedInt();
Price = reader.ReadEncodedInt();
switch ( version )
{
case 0:
{
string type = reader.ReadString();
break;
}
}
}
if ( type != null )
m_ItemType = ScriptCompiler.FindTypeByFullName( type );
public Type ItemType{ get; }
m_RequireExceptional = reader.ReadBool();
public bool RequireExceptional{ get; }
m_DeedType = (BODType)reader.ReadEncodedInt();
public BODType DeedType{ get; }
m_Material = (BulkMaterialType)reader.ReadEncodedInt();
m_AmountCur = reader.ReadEncodedInt();
m_AmountMax = reader.ReadEncodedInt();
m_Number = reader.ReadEncodedInt();
m_Graphic = reader.ReadEncodedInt();
m_Price = reader.ReadEncodedInt();
public BulkMaterialType Material{ get; }
break;
}
}
}
public int AmountCur{ get; }
public void Serialize( GenericWriter writer )
{
writer.WriteEncodedInt( 0 ); // version
public int AmountMax{ get; }
writer.Write( m_ItemType == null ? null : m_ItemType.FullName );
public int Number{ get; }
writer.Write( (bool) m_RequireExceptional );
public int Graphic{ get; }
writer.WriteEncodedInt( (int) m_DeedType );
writer.WriteEncodedInt( (int) m_Material );
writer.WriteEncodedInt( (int) m_AmountCur );
writer.WriteEncodedInt( (int) m_AmountMax );
writer.WriteEncodedInt( (int) m_Number );
writer.WriteEncodedInt( (int) m_Graphic );
writer.WriteEncodedInt( (int) m_Price );
}
}
public int Price{ get; set; }
public Item Reconstruct()
{
SmallBOD bod = null;
if (DeedType == BODType.Smith)
bod = new SmallSmithBOD(AmountCur, AmountMax, ItemType, Number, Graphic, RequireExceptional, Material);
else if (DeedType == BODType.Tailor)
bod = new SmallTailorBOD(AmountCur, AmountMax, ItemType, Number, Graphic, RequireExceptional, Material);
return bod;
}
public void Serialize(GenericWriter writer)
{
writer.WriteEncodedInt(0); // version
writer.Write(ItemType == null ? null : ItemType.FullName);
writer.Write(RequireExceptional);
writer.WriteEncodedInt((int)DeedType);
writer.WriteEncodedInt((int)Material);
writer.WriteEncodedInt(AmountCur);
writer.WriteEncodedInt(AmountMax);
writer.WriteEncodedInt(Number);
writer.WriteEncodedInt(Graphic);
writer.WriteEncodedInt(Price);
}
}
}

View file

@ -1,138 +1,140 @@
using System;
using Server;
using Server.Items;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
using Server.Network;
namespace Server.Engines.BulkOrders
{
public class BODBuyGump : Gump
{
private PlayerMobile m_From;
private BulkOrderBook m_Book;
private object m_Object;
private int m_Price;
private int m_Page;
public class BODBuyGump : Gump
{
private BulkOrderBook m_Book;
private PlayerMobile m_From;
private object m_Object;
private int m_Page;
private int m_Price;
public override void OnResponse( Server.Network.NetState sender, RelayInfo info )
{
if ( info.ButtonID == 2 )
{
PlayerVendor pv = m_Book.RootParent as PlayerVendor;
public BODBuyGump(PlayerMobile from, BulkOrderBook book, object obj, int page, int price) : base(100, 200)
{
m_From = from;
m_Book = book;
m_Object = obj;
m_Price = price;
m_Page = page;
if ( m_Book.Entries.Contains( m_Object ) && pv != null )
{
int price = 0;
AddPage(0);
VendorItem vi = pv.GetVendorItem( m_Book );
AddBackground(100, 10, 300, 150, 5054);
if ( vi != null && !vi.IsForSale )
{
if ( m_Object is BOBLargeEntry )
price = ((BOBLargeEntry)m_Object).Price;
else if ( m_Object is BOBSmallEntry )
price = ((BOBSmallEntry)m_Object).Price;
}
AddHtmlLocalized(125, 20, 250, 24, 1019070, false, false); // You have agreed to purchase:
AddHtmlLocalized(125, 45, 250, 24, 1045151, false, false); // a bulk order deed
if ( price != m_Price )
{
pv.SayTo( m_From, "The price has been been changed. If you like, you may offer to purchase the item again." );
}
else if ( price == 0 )
{
pv.SayTo( m_From, 1062382 ); // The deed selected is not available.
}
else
{
Item item = null;
AddHtmlLocalized(125, 70, 250, 24, 1019071, false, false); // for the amount of:
AddLabel(125, 95, 0, price.ToString());
if ( m_Object is BOBLargeEntry )
item = ((BOBLargeEntry)m_Object).Reconstruct();
else if ( m_Object is BOBSmallEntry )
item = ((BOBSmallEntry)m_Object).Reconstruct();
AddButton(250, 130, 4005, 4007, 1, GumpButtonType.Reply, 0);
AddHtmlLocalized(282, 130, 100, 24, 1011012, false, false); // CANCEL
if ( item == null )
{
m_From.SendMessage( "Internal error. The bulk order deed could not be reconstructed." );
}
else
{
pv.Say( m_From.Name );
AddButton(120, 130, 4005, 4007, 2, GumpButtonType.Reply, 0);
AddHtmlLocalized(152, 130, 100, 24, 1011036, false, false); // OKAY
}
Container pack = m_From.Backpack;
public override void OnResponse(NetState sender, RelayInfo info)
{
if (info.ButtonID == 2)
{
PlayerVendor pv = m_Book.RootParent as PlayerVendor;
if ( (pack == null) || ((pack != null) && (!pack.CheckHold(m_From, item, true, true, 0, item.PileWeight + item.TotalWeight)) ) )
{
pv.SayTo(m_From, 503204); // You do not have room in your backpack for this
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page, null));
}
else
{
if ((pack != null && pack.ConsumeTotal( typeof( Gold ), price )) || Banker.Withdraw( m_From, price ) )
{
m_Book.Entries.Remove( m_Object );
m_Book.InvalidateProperties();
pv.HoldGold += price;
m_From.AddToBackpack( item );
m_From.SendLocalizedMessage( 1045152 ); // The bulk order deed has been placed in your backpack.
if ( m_Book.Entries.Count / 5 < m_Book.ItemCount )
{
m_Book.ItemCount--;
m_Book.InvalidateItems();
}
if (m_Book.Entries.Contains(m_Object) && pv != null)
{
int price = 0;
if ( m_Book.Entries.Count > 0 )
m_From.SendGump( new BOBGump( m_From, m_Book, m_Page, null ) );
else
m_From.SendLocalizedMessage( 1062381 ); // The book is empty.
}
else
{
pv.SayTo( m_From, 503205 ); // You cannot afford this item.
item.Delete();
}
}
}
}
}
else
{
if ( pv == null )
m_From.SendLocalizedMessage( 1062382 ); // The deed selected is not available.
else
pv.SayTo( m_From, 1062382 ); // The deed selected is not available.
}
}
else
{
m_From.SendLocalizedMessage( 503207 ); // Cancelled purchase.
}
}
VendorItem vi = pv.GetVendorItem(m_Book);
public BODBuyGump( PlayerMobile from, BulkOrderBook book, object obj, int page, int price ) : base( 100, 200 )
{
m_From = from;
m_Book = book;
m_Object = obj;
m_Price = price;
m_Page = page;
if (vi != null && !vi.IsForSale)
{
if (m_Object is BOBLargeEntry entry)
price = entry.Price;
else
price = ((BOBSmallEntry)m_Object).Price;
}
AddPage( 0 );
if (price != m_Price)
{
pv.SayTo(m_From,
"The price has been been changed. If you like, you may offer to purchase the item again.");
}
else if (price == 0)
{
pv.SayTo(m_From, 1062382); // The deed selected is not available.
}
else
{
Item item = null;
AddBackground( 100, 10, 300, 150, 5054 );
if (m_Object is BOBLargeEntry entry)
item = entry.Reconstruct();
else
item = ((BOBSmallEntry)m_Object).Reconstruct();
AddHtmlLocalized( 125, 20, 250, 24, 1019070, false, false ); // You have agreed to purchase:
AddHtmlLocalized( 125, 45, 250, 24, 1045151, false, false ); // a bulk order deed
if (item == null)
{
m_From.SendMessage("Internal error. The bulk order deed could not be reconstructed.");
}
else
{
pv.Say(m_From.Name);
AddHtmlLocalized( 125, 70, 250, 24, 1019071, false, false ); // for the amount of:
AddLabel( 125, 95, 0, price.ToString() );
Container pack = m_From.Backpack;
AddButton( 250, 130, 4005, 4007, 1, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 282, 130, 100, 24, 1011012, false, false ); // CANCEL
if (pack == null || !pack.CheckHold(m_From, item, true, true, 0,
item.PileWeight + item.TotalWeight))
{
pv.SayTo(m_From, 503204); // You do not have room in your backpack for this
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page, null));
}
else
{
if (pack.ConsumeTotal(typeof(Gold), price) || Banker.Withdraw(m_From, price))
{
m_Book.Entries.Remove(m_Object);
m_Book.InvalidateProperties();
pv.HoldGold += price;
m_From.AddToBackpack(item);
m_From.SendLocalizedMessage(
1045152); // The bulk order deed has been placed in your backpack.
AddButton( 120, 130, 4005, 4007, 2, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 152, 130, 100, 24, 1011036, false, false ); // OKAY
}
}
}
if (m_Book.Entries.Count / 5 < m_Book.ItemCount)
{
m_Book.ItemCount--;
m_Book.InvalidateItems();
}
if (m_Book.Entries.Count > 0)
m_From.SendGump(new BOBGump(m_From, m_Book, m_Page, null));
else
m_From.SendLocalizedMessage(1062381); // The book is empty.
}
else
{
pv.SayTo(m_From, 503205); // You cannot afford this item.
item.Delete();
}
}
}
}
}
else
{
if (pv == null)
m_From.SendLocalizedMessage(1062382); // The deed selected is not available.
else
pv.SayTo(m_From, 1062382); // The deed selected is not available.
}
}
else
{
m_From.SendLocalizedMessage(503207); // Cancelled purchase.
}
}
}
}

View file

@ -1,10 +1,8 @@
using System;
namespace Server.Engines.BulkOrders
{
public enum BODType
{
Smith,
Tailor
}
public enum BODType
{
Smith,
Tailor
}
}

View file

@ -1,7 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Gumps;
using Server.Multis;
using Server.Prompts;
@ -13,41 +12,23 @@ namespace Server.Engines.BulkOrders
{
public class BulkOrderBook : Item, ISecurable
{
private ArrayList m_Entries;
private BOBFilter m_Filter;
private string m_BookName;
private SecureLevel m_Level;
private int m_ItemCount;
[CommandProperty( AccessLevel.GameMaster )]
public string BookName
{
get{ return m_BookName; }
get => m_BookName;
set{ m_BookName = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public SecureLevel Level
{
get{ return m_Level; }
set{ m_Level = value; }
}
public SecureLevel Level { get; set; }
public ArrayList Entries
{
get{ return m_Entries; }
}
public ArrayList Entries { get; private set; }
public BOBFilter Filter
{
get{ return m_Filter; }
}
public int ItemCount
{
get{ return m_ItemCount; }
set{ m_ItemCount = value; }
}
public BOBFilter Filter { get; private set; }
public int ItemCount { get; set; }
[Constructible]
public BulkOrderBook() : base( 0x2259 )
@ -55,20 +36,20 @@ namespace Server.Engines.BulkOrders
Weight = 1.0;
LootType = LootType.Blessed;
m_Entries = new ArrayList();
m_Filter = new BOBFilter();
Entries = new ArrayList();
Filter = new BOBFilter();
m_Level = SecureLevel.CoOwners;
Level = SecureLevel.CoOwners;
}
public override void OnDoubleClick( Mobile from )
{
if ( !from.InRange( GetWorldLocation(), 2 ) )
from.LocalOverheadMessage( Network.MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
else if ( m_Entries.Count == 0 )
else if ( Entries.Count == 0 )
from.SendLocalizedMessage( 1062381 ); // The book is empty.
else if ( from is PlayerMobile )
from.SendGump( new BOBGump( (PlayerMobile)from, this ) );
else if ( from is PlayerMobile mobile )
mobile.SendGump( new BOBGump( mobile, this ) );
}
public override void OnDoubleClickSecureTrade( Mobile from )
@ -77,7 +58,7 @@ namespace Server.Engines.BulkOrders
{
from.SendLocalizedMessage( 500446 ); // That is too far away.
}
else if ( m_Entries.Count == 0 )
else if ( Entries.Count == 0 )
{
from.SendLocalizedMessage( 1062381 ); // The book is empty.
}
@ -108,71 +89,65 @@ namespace Server.Engines.BulkOrders
from.SendLocalizedMessage( 1062385 ); // You must have the book in your backpack to add deeds to it.
return false;
}
else if ( !from.Backpack.CheckHold( from, dropped, true, true ) )
if ( !from.Backpack.CheckHold( from, dropped, true, true ) )
return false;
else if ( m_Entries.Count < 500 )
if ( Entries.Count < 500 )
{
if ( dropped is LargeBOD )
m_Entries.Add( new BOBLargeEntry( (LargeBOD)dropped ) );
else if ( dropped is SmallBOD ) // Sanity
m_Entries.Add( new BOBSmallEntry( (SmallBOD)dropped ) );
if ( dropped is LargeBOD bod )
Entries.Add( new BOBLargeEntry( bod ) );
else
Entries.Add( new BOBSmallEntry( (SmallBOD)dropped ) );
InvalidateProperties();
if ( m_Entries.Count / 5 > m_ItemCount )
if ( Entries.Count / 5 > ItemCount )
{
m_ItemCount++;
ItemCount++;
InvalidateItems();
}
from.SendSound(0x42, GetWorldLocation());
from.SendLocalizedMessage( 1062386 ); // Deed added to book.
if ( from is PlayerMobile )
from.SendGump( new BOBGump( (PlayerMobile)from, this ) );
if ( from is PlayerMobile pm )
pm.SendGump( new BOBGump( pm, this ) );
dropped.Delete();
return true;
}
else
{
from.SendLocalizedMessage( 1062387 ); // The book is full of deeds.
return false;
}
from.SendLocalizedMessage( 1062387 ); // The book is full of deeds.
return false;
}
from.SendLocalizedMessage( 1062388 ); // That is not a bulk order deed.
return false;
}
public override int GetTotal( TotalType type )
{
int total = base.GetTotal( type );
if ( type == TotalType.Items )
total = m_ItemCount;
total = ItemCount;
return total;
}
public void InvalidateItems()
{
if ( RootParent is Mobile )
if ( RootParent is Mobile m )
{
Mobile m = (Mobile) RootParent;
m.UpdateTotals();
InvalidateContainers( Parent );
}
}
public void InvalidateContainers( object parent )
{
if ( parent != null && parent is Container )
if ( parent is Container c )
{
Container c = (Container)parent;
c.InvalidateProperties();
InvalidateContainers( c.Parent );
}
@ -187,34 +162,30 @@ namespace Server.Engines.BulkOrders
base.Serialize( writer );
writer.Write( (int) 2 ); // version
writer.Write( (int) m_ItemCount );
writer.Write( (int) m_Level );
writer.Write( (int) ItemCount );
writer.Write( (int) Level );
writer.Write( m_BookName );
m_Filter.Serialize( writer );
Filter.Serialize( writer );
writer.WriteEncodedInt( (int) m_Entries.Count );
writer.WriteEncodedInt( (int) Entries.Count );
for ( int i = 0; i < m_Entries.Count; ++i )
for ( int i = 0; i < Entries.Count; ++i )
{
object obj = m_Entries[i];
object obj = Entries[i];
if ( obj is BOBLargeEntry )
if ( obj is BOBLargeEntry entry )
{
writer.WriteEncodedInt( 0 );
((BOBLargeEntry)obj).Serialize( writer );
}
else if ( obj is BOBSmallEntry )
{
writer.WriteEncodedInt( 1 );
((BOBSmallEntry)obj).Serialize( writer );
entry.Serialize( writer );
}
else
{
writer.WriteEncodedInt( -1 );
writer.WriteEncodedInt( 1 );
((BOBSmallEntry)obj).Serialize( writer );
}
}
}
@ -229,23 +200,23 @@ namespace Server.Engines.BulkOrders
{
case 2:
{
m_ItemCount = reader.ReadInt();
ItemCount = reader.ReadInt();
goto case 1;
}
case 1:
{
m_Level = (SecureLevel)reader.ReadInt();
Level = (SecureLevel)reader.ReadInt();
goto case 0;
}
case 0:
{
m_BookName = reader.ReadString();
m_Filter = new BOBFilter( reader );
Filter = new BOBFilter( reader );
int count = reader.ReadEncodedInt();
m_Entries = new ArrayList( count );
Entries = new ArrayList( count );
for ( int i = 0; i < count; ++i )
{
@ -253,8 +224,8 @@ namespace Server.Engines.BulkOrders
switch ( v )
{
case 0: m_Entries.Add( new BOBLargeEntry( reader ) ); break;
case 1: m_Entries.Add( new BOBSmallEntry( reader ) ); break;
case 0: Entries.Add( new BOBLargeEntry( reader ) ); break;
case 1: Entries.Add( new BOBSmallEntry( reader ) ); break;
}
}
@ -267,7 +238,7 @@ namespace Server.Engines.BulkOrders
{
base.GetProperties( list );
list.Add( 1062344, m_Entries.Count.ToString() ); // Deeds in book: ~1_val~
list.Add( 1062344, Entries.Count.ToString() ); // Deeds in book: ~1_val~
if ( m_BookName != null && m_BookName.Length > 0 )
list.Add( 1062481, m_BookName ); // Book Name: ~1_val~
@ -277,9 +248,9 @@ namespace Server.Engines.BulkOrders
{
base.OnSingleClick(from);
LabelTo(from, 1062344, m_Entries.Count.ToString()); // Deeds in book: ~1_val~
LabelTo(from, 1062344, Entries.Count.ToString()); // Deeds in book: ~1_val~
if (!String.IsNullOrEmpty(m_BookName))
if (!string.IsNullOrEmpty(m_BookName))
LabelTo(from, 1062481, m_BookName);
}
@ -341,4 +312,4 @@ namespace Server.Engines.BulkOrders
}
}
}
}
}

View file

@ -1,45 +1,44 @@
using System;
using Server;
using Server.Items;
namespace Server.Engines.BulkOrders
{
public enum BulkMaterialType
{
None,
DullCopper,
ShadowIron,
Copper,
Bronze,
Gold,
Agapite,
Verite,
Valorite,
Spined,
Horned,
Barbed
}
public enum BulkMaterialType
{
None,
DullCopper,
ShadowIron,
Copper,
Bronze,
Gold,
Agapite,
Verite,
Valorite,
Spined,
Horned,
Barbed
}
public enum BulkGenericType
{
Iron,
Cloth,
Leather
}
public enum BulkGenericType
{
Iron,
Cloth,
Leather
}
public class BGTClassifier
{
public static BulkGenericType Classify( BODType deedType, Type itemType )
{
if ( deedType == BODType.Tailor )
{
if ( itemType == null || itemType.IsSubclassOf( typeof( BaseArmor ) ) || itemType.IsSubclassOf( typeof( BaseShoes ) ) )
return BulkGenericType.Leather;
public class BGTClassifier
{
public static BulkGenericType Classify(BODType deedType, Type itemType)
{
if (deedType == BODType.Tailor)
{
if (itemType == null || itemType.IsSubclassOf(typeof(BaseArmor)) || itemType.IsSubclassOf(typeof(BaseShoes)))
return BulkGenericType.Leather;
return BulkGenericType.Cloth;
}
return BulkGenericType.Cloth;
}
return BulkGenericType.Iron;
}
}
return BulkGenericType.Iron;
}
}
}

View file

@ -1,7 +1,3 @@
using System;
using System.Collections;
using Server;
using Server.Items;
using System.Collections.Generic;
using Server.Mobiles;
@ -16,15 +12,19 @@ namespace Server.Engines.BulkOrders
private LargeBulkEntry[] m_Entries;
[CommandProperty( AccessLevel.GameMaster )]
public int AmountMax{ get{ return m_AmountMax; } set{ m_AmountMax = value; InvalidateProperties(); } }
public int AmountMax{ get => m_AmountMax;
set{ m_AmountMax = value; InvalidateProperties(); } }
[CommandProperty( AccessLevel.GameMaster )]
public bool RequireExceptional{ get{ return m_RequireExceptional; } set{ m_RequireExceptional = value; InvalidateProperties(); } }
public bool RequireExceptional{ get => m_RequireExceptional;
set{ m_RequireExceptional = value; InvalidateProperties(); } }
[CommandProperty( AccessLevel.GameMaster )]
public BulkMaterialType Material{ get{ return m_Material; } set{ m_Material = value; InvalidateProperties(); } }
public BulkMaterialType Material{ get => m_Material;
set{ m_Material = value; InvalidateProperties(); } }
public LargeBulkEntry[] Entries{ get{ return m_Entries; } set{ m_Entries = value; InvalidateProperties(); } }
public LargeBulkEntry[] Entries{ get => m_Entries;
set{ m_Entries = value; InvalidateProperties(); } }
[CommandProperty( AccessLevel.GameMaster )]
public bool Complete
@ -146,12 +146,10 @@ namespace Server.Engines.BulkOrders
public void EndCombine( Mobile from, object o )
{
if ( o is Item && ((Item)o).IsChildOf( from.Backpack ) )
if ( o is Item item && item.IsChildOf( from.Backpack ) )
{
if ( o is SmallBOD )
if ( item is SmallBOD small )
{
SmallBOD small = (SmallBOD)o;
LargeBulkEntry entry = null;
for ( int i = 0; entry == null && i < m_Entries.Length; ++i )

View file

@ -1,106 +1,107 @@
using System;
using Server;
using Server.Gumps;
using Server.Network;
namespace Server.Engines.BulkOrders
{
public class LargeBODAcceptGump : Gump
{
private LargeBOD m_Deed;
private Mobile m_From;
public class LargeBODAcceptGump : Gump
{
private LargeBOD m_Deed;
private Mobile m_From;
public LargeBODAcceptGump( Mobile from, LargeBOD deed ) : base( 50, 50 )
{
m_From = from;
m_Deed = deed;
public LargeBODAcceptGump(Mobile from, LargeBOD deed) : base(50, 50)
{
m_From = from;
m_Deed = deed;
m_From.CloseGump( typeof( LargeBODAcceptGump ) );
m_From.CloseGump( typeof( SmallBODAcceptGump ) );
m_From.CloseGump(typeof(LargeBODAcceptGump));
m_From.CloseGump(typeof(SmallBODAcceptGump));
LargeBulkEntry[] entries = deed.Entries;
LargeBulkEntry[] entries = deed.Entries;
AddPage( 0 );
AddPage(0);
AddBackground( 25, 10, 430, 240 + (entries.Length * 24), 5054 );
AddBackground(25, 10, 430, 240 + entries.Length * 24, 5054);
AddImageTiled( 33, 20, 413, 221 + (entries.Length * 24), 2624 );
AddAlphaRegion( 33, 20, 413, 221 + (entries.Length * 24) );
AddImageTiled(33, 20, 413, 221 + entries.Length * 24, 2624);
AddAlphaRegion(33, 20, 413, 221 + entries.Length * 24);
AddImage( 20, 5, 10460 );
AddImage( 430, 5, 10460 );
AddImage( 20, 225 + (entries.Length * 24), 10460 );
AddImage( 430, 225 + (entries.Length * 24), 10460 );
AddImage(20, 5, 10460);
AddImage(430, 5, 10460);
AddImage(20, 225 + entries.Length * 24, 10460);
AddImage(430, 225 + entries.Length * 24, 10460);
AddHtmlLocalized( 180, 25, 120, 20, 1045134, 0x7FFF, false, false ); // A large bulk order
AddHtmlLocalized(180, 25, 120, 20, 1045134, 0x7FFF, false, false); // A large bulk order
AddHtmlLocalized( 40, 48, 350, 20, 1045135, 0x7FFF, false, false ); // Ah! Thanks for the goods! Would you help me out?
AddHtmlLocalized(40, 48, 350, 20, 1045135, 0x7FFF, false,
false); // Ah! Thanks for the goods! Would you help me out?
AddHtmlLocalized( 40, 72, 210, 20, 1045138, 0x7FFF, false, false ); // Amount to make:
AddLabel( 250, 72, 1152, deed.AmountMax.ToString() );
AddHtmlLocalized(40, 72, 210, 20, 1045138, 0x7FFF, false, false); // Amount to make:
AddLabel(250, 72, 1152, deed.AmountMax.ToString());
AddHtmlLocalized( 40, 96, 120, 20, 1045137, 0x7FFF, false, false ); // Items requested:
AddHtmlLocalized(40, 96, 120, 20, 1045137, 0x7FFF, false, false); // Items requested:
int y = 120;
int y = 120;
for ( int i = 0; i < entries.Length; ++i, y += 24 )
AddHtmlLocalized( 40, y, 210, 20, entries[i].Details.Number, 0x7FFF, false, false );
for (int i = 0; i < entries.Length; ++i, y += 24)
AddHtmlLocalized(40, y, 210, 20, entries[i].Details.Number, 0x7FFF, false, false);
if ( deed.RequireExceptional || deed.Material != BulkMaterialType.None )
{
AddHtmlLocalized( 40, y, 210, 20, 1045140, 0x7FFF, false, false ); // Special requirements to meet:
y += 24;
if (deed.RequireExceptional || deed.Material != BulkMaterialType.None)
{
AddHtmlLocalized(40, y, 210, 20, 1045140, 0x7FFF, false, false); // Special requirements to meet:
y += 24;
if ( deed.RequireExceptional )
{
AddHtmlLocalized( 40, y, 350, 20, 1045141, 0x7FFF, false, false ); // All items must be exceptional.
y += 24;
}
if (deed.RequireExceptional)
{
AddHtmlLocalized(40, y, 350, 20, 1045141, 0x7FFF, false, false); // All items must be exceptional.
y += 24;
}
if ( deed.Material != BulkMaterialType.None )
{
AddHtmlLocalized( 40, y, 350, 20, GetMaterialNumberFor( deed.Material ), 0x7FFF, false, false ); // All items must be made with x material.
y += 24;
}
}
if (deed.Material != BulkMaterialType.None)
{
AddHtmlLocalized(40, y, 350, 20, GetMaterialNumberFor(deed.Material), 0x7FFF, false,
false); // All items must be made with x material.
y += 24;
}
}
AddHtmlLocalized( 40, 192 + (entries.Length * 24), 350, 20, 1045139, 0x7FFF, false, false ); // Do you want to accept this order?
AddHtmlLocalized(40, 192 + entries.Length * 24, 350, 20, 1045139, 0x7FFF, false,
false); // Do you want to accept this order?
AddButton( 100, 216 + (entries.Length * 24), 4005, 4007, 1, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 135, 216 + (entries.Length * 24), 120, 20, 1006044, 0x7FFF, false, false ); // Ok
AddButton(100, 216 + entries.Length * 24, 4005, 4007, 1, GumpButtonType.Reply, 0);
AddHtmlLocalized(135, 216 + entries.Length * 24, 120, 20, 1006044, 0x7FFF, false, false); // Ok
AddButton( 275, 216 + (entries.Length * 24), 4005, 4007, 0, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 310, 216 + (entries.Length * 24), 120, 20, 1011012, 0x7FFF, false, false ); // CANCEL
}
AddButton(275, 216 + entries.Length * 24, 4005, 4007, 0, GumpButtonType.Reply, 0);
AddHtmlLocalized(310, 216 + entries.Length * 24, 120, 20, 1011012, 0x7FFF, false, false); // CANCEL
}
public override void OnResponse( NetState sender, RelayInfo info )
{
if ( info.ButtonID == 1 ) // Ok
{
if ( m_From.PlaceInBackpack( m_Deed ) )
{
m_From.SendLocalizedMessage( 1045152 ); // The bulk order deed has been placed in your backpack.
}
else
{
m_From.SendLocalizedMessage( 1045150 ); // There is not enough room in your backpack for the deed.
m_Deed.Delete();
}
}
else
{
m_Deed.Delete();
}
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (info.ButtonID == 1) // Ok
{
if (m_From.PlaceInBackpack(m_Deed))
{
m_From.SendLocalizedMessage(1045152); // The bulk order deed has been placed in your backpack.
}
else
{
m_From.SendLocalizedMessage(1045150); // There is not enough room in your backpack for the deed.
m_Deed.Delete();
}
}
else
{
m_Deed.Delete();
}
}
public static int GetMaterialNumberFor( BulkMaterialType material )
{
if ( material >= BulkMaterialType.DullCopper && material <= BulkMaterialType.Valorite )
return 1045142 + (int)(material - BulkMaterialType.DullCopper);
else if ( material >= BulkMaterialType.Spined && material <= BulkMaterialType.Barbed )
return 1049348 + (int)(material - BulkMaterialType.Spined);
public static int GetMaterialNumberFor(BulkMaterialType material)
{
if (material >= BulkMaterialType.DullCopper && material <= BulkMaterialType.Valorite)
return 1045142 + (material - BulkMaterialType.DullCopper);
if (material >= BulkMaterialType.Spined && material <= BulkMaterialType.Barbed)
return 1049348 + (material - BulkMaterialType.Spined);
return 0;
}
}
return 0;
}
}
}

View file

@ -1,100 +1,100 @@
using System;
using Server;
using Server.Gumps;
using Server.Network;
namespace Server.Engines.BulkOrders
{
public class LargeBODGump : Gump
{
private LargeBOD m_Deed;
private Mobile m_From;
public class LargeBODGump : Gump
{
private LargeBOD m_Deed;
private Mobile m_From;
public LargeBODGump( Mobile from, LargeBOD deed ) : base( 25, 25 )
{
m_From = from;
m_Deed = deed;
public LargeBODGump(Mobile from, LargeBOD deed) : base(25, 25)
{
m_From = from;
m_Deed = deed;
m_From.CloseGump( typeof( LargeBODGump ) );
m_From.CloseGump( typeof( SmallBODGump ) );
m_From.CloseGump(typeof(LargeBODGump));
m_From.CloseGump(typeof(SmallBODGump));
LargeBulkEntry[] entries = deed.Entries;
LargeBulkEntry[] entries = deed.Entries;
AddPage( 0 );
AddPage(0);
AddBackground( 50, 10, 455, 236 + (entries.Length * 24), 5054 );
AddBackground(50, 10, 455, 236 + entries.Length * 24, 5054);
AddImageTiled( 58, 20, 438, 217 + (entries.Length * 24), 2624 );
AddAlphaRegion( 58, 20, 438, 217 + (entries.Length * 24) );
AddImageTiled(58, 20, 438, 217 + entries.Length * 24, 2624);
AddAlphaRegion(58, 20, 438, 217 + entries.Length * 24);
AddImage( 45, 5, 10460 );
AddImage( 480, 5, 10460 );
AddImage( 45, 221 + (entries.Length * 24), 10460 );
AddImage( 480, 221 + (entries.Length * 24), 10460 );
AddImage(45, 5, 10460);
AddImage(480, 5, 10460);
AddImage(45, 221 + entries.Length * 24, 10460);
AddImage(480, 221 + entries.Length * 24, 10460);
AddHtmlLocalized( 225, 25, 120, 20, 1045134, 0x7FFF, false, false ); // A large bulk order
AddHtmlLocalized(225, 25, 120, 20, 1045134, 0x7FFF, false, false); // A large bulk order
AddHtmlLocalized( 75, 48, 250, 20, 1045138, 0x7FFF, false, false ); // Amount to make:
AddLabel( 275, 48, 1152, deed.AmountMax.ToString() );
AddHtmlLocalized(75, 48, 250, 20, 1045138, 0x7FFF, false, false); // Amount to make:
AddLabel(275, 48, 1152, deed.AmountMax.ToString());
AddHtmlLocalized( 75, 72, 120, 20, 1045137, 0x7FFF, false, false ); // Items requested:
AddHtmlLocalized( 275, 76, 200, 20, 1045153, 0x7FFF, false, false ); // Amount finished:
AddHtmlLocalized(75, 72, 120, 20, 1045137, 0x7FFF, false, false); // Items requested:
AddHtmlLocalized(275, 76, 200, 20, 1045153, 0x7FFF, false, false); // Amount finished:
int y = 96;
int y = 96;
for ( int i = 0; i < entries.Length; ++i )
{
LargeBulkEntry entry = entries[i];
SmallBulkEntry details = entry.Details;
for (int i = 0; i < entries.Length; ++i)
{
LargeBulkEntry entry = entries[i];
SmallBulkEntry details = entry.Details;
AddHtmlLocalized( 75, y, 210, 20, details.Number, 0x7FFF, false, false );
AddLabel( 275, y, 0x480, entry.Amount.ToString() );
AddHtmlLocalized(75, y, 210, 20, details.Number, 0x7FFF, false, false);
AddLabel(275, y, 0x480, entry.Amount.ToString());
y += 24;
}
y += 24;
}
if ( deed.RequireExceptional || deed.Material != BulkMaterialType.None )
{
AddHtmlLocalized( 75, y, 200, 20, 1045140, 0x7FFF, false, false ); // Special requirements to meet:
y += 24;
}
if (deed.RequireExceptional || deed.Material != BulkMaterialType.None)
{
AddHtmlLocalized(75, y, 200, 20, 1045140, 0x7FFF, false, false); // Special requirements to meet:
y += 24;
}
if ( deed.RequireExceptional )
{
AddHtmlLocalized( 75, y, 300, 20, 1045141, 0x7FFF, false, false ); // All items must be exceptional.
y += 24;
}
if (deed.RequireExceptional)
{
AddHtmlLocalized(75, y, 300, 20, 1045141, 0x7FFF, false, false); // All items must be exceptional.
y += 24;
}
if ( deed.Material != BulkMaterialType.None )
AddHtmlLocalized( 75, y, 300, 20, GetMaterialNumberFor( deed.Material ), 0x7FFF, false, false ); // All items must be made with x material.
if (deed.Material != BulkMaterialType.None)
AddHtmlLocalized(75, y, 300, 20, GetMaterialNumberFor(deed.Material), 0x7FFF, false,
false); // All items must be made with x material.
AddButton( 125, 168 + (entries.Length * 24), 4005, 4007, 2, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 160, 168 + (entries.Length * 24), 300, 20, 1045155, 0x7FFF, false, false ); // Combine this deed with another deed.
AddButton(125, 168 + entries.Length * 24, 4005, 4007, 2, GumpButtonType.Reply, 0);
AddHtmlLocalized(160, 168 + entries.Length * 24, 300, 20, 1045155, 0x7FFF, false,
false); // Combine this deed with another deed.
AddButton( 125, 192 + (entries.Length * 24), 4005, 4007, 1, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 160, 192 + (entries.Length * 24), 120, 20, 1011441, 0x7FFF, false, false ); // EXIT
}
AddButton(125, 192 + entries.Length * 24, 4005, 4007, 1, GumpButtonType.Reply, 0);
AddHtmlLocalized(160, 192 + entries.Length * 24, 120, 20, 1011441, 0x7FFF, false, false); // EXIT
}
public override void OnResponse( NetState sender, RelayInfo info )
{
if ( m_Deed.Deleted || !m_Deed.IsChildOf( m_From.Backpack ) )
return;
public override void OnResponse(NetState sender, RelayInfo info)
{
if (m_Deed.Deleted || !m_Deed.IsChildOf(m_From.Backpack))
return;
if ( info.ButtonID == 2 ) // Combine
{
m_From.SendGump( new LargeBODGump( m_From, m_Deed ) );
m_Deed.BeginCombine( m_From );
}
}
if (info.ButtonID == 2) // Combine
{
m_From.SendGump(new LargeBODGump(m_From, m_Deed));
m_Deed.BeginCombine(m_From);
}
}
public static int GetMaterialNumberFor( BulkMaterialType material )
{
if ( material >= BulkMaterialType.DullCopper && material <= BulkMaterialType.Valorite )
return 1045142 + (int)(material - BulkMaterialType.DullCopper);
else if ( material >= BulkMaterialType.Spined && material <= BulkMaterialType.Barbed )
return 1049348 + (int)(material - BulkMaterialType.Spined);
public static int GetMaterialNumberFor(BulkMaterialType material)
{
if (material >= BulkMaterialType.DullCopper && material <= BulkMaterialType.Valorite)
return 1045142 + (material - BulkMaterialType.DullCopper);
if (material >= BulkMaterialType.Spined && material <= BulkMaterialType.Barbed)
return 1049348 + (material - BulkMaterialType.Spined);
return 0;
}
}
return 0;
}
}
}

View file

@ -1,25 +1,22 @@
using System;
using Server;
using Server.Targeting;
using Server.Network;
namespace Server.Engines.BulkOrders
{
public class LargeBODTarget : Target
{
private LargeBOD m_Deed;
public class LargeBODTarget : Target
{
private LargeBOD m_Deed;
public LargeBODTarget( LargeBOD deed ) : base( 18, false, TargetFlags.None )
{
m_Deed = deed;
}
public LargeBODTarget(LargeBOD deed) : base(18, false, TargetFlags.None)
{
m_Deed = deed;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( m_Deed.Deleted || !m_Deed.IsChildOf( from.Backpack ) )
return;
protected override void OnTarget(Mobile from, object targeted)
{
if (m_Deed.Deleted || !m_Deed.IsChildOf(from.Backpack))
return;
m_Deed.EndCombine( from, targeted );
}
}
m_Deed.EndCombine(from, targeted);
}
}
}

View file

@ -1,130 +1,64 @@
using System;
using System.Collections.Generic;
using System.IO;
using Server;
namespace Server.Engines.BulkOrders
{
public class LargeBulkEntry
{
private LargeBOD m_Owner;
private int m_Amount;
private SmallBulkEntry m_Details;
public LargeBOD Owner{ get{ return m_Owner; } set{ m_Owner = value; } }
public int Amount{ get{ return m_Amount; } set{ m_Amount = value; if ( m_Owner != null ) m_Owner.InvalidateProperties(); } }
public SmallBulkEntry Details{ get{ return m_Details; } }
public LargeBOD Owner { get; set; }
public static SmallBulkEntry[] LargeRing
{
get{ return GetEntries( "Blacksmith", "largering" ); }
}
public int Amount{ get => m_Amount;
set{ m_Amount = value;
Owner?.InvalidateProperties();
} }
public SmallBulkEntry Details { get; }
public static SmallBulkEntry[] LargePlate
{
get{ return GetEntries( "Blacksmith", "largeplate" ); }
}
public static SmallBulkEntry[] LargeRing => GetEntries( "Blacksmith", "largering" );
public static SmallBulkEntry[] LargeChain
{
get{ return GetEntries( "Blacksmith", "largechain" ); }
}
public static SmallBulkEntry[] LargePlate => GetEntries( "Blacksmith", "largeplate" );
public static SmallBulkEntry[] LargeAxes
{
get{ return GetEntries( "Blacksmith", "largeaxes" ); }
}
public static SmallBulkEntry[] LargeChain => GetEntries( "Blacksmith", "largechain" );
public static SmallBulkEntry[] LargeFencing
{
get{ return GetEntries( "Blacksmith", "largefencing" ); }
}
public static SmallBulkEntry[] LargeAxes => GetEntries( "Blacksmith", "largeaxes" );
public static SmallBulkEntry[] LargeMaces
{
get{ return GetEntries( "Blacksmith", "largemaces" ); }
}
public static SmallBulkEntry[] LargeFencing => GetEntries( "Blacksmith", "largefencing" );
public static SmallBulkEntry[] LargePolearms
{
get{ return GetEntries( "Blacksmith", "largepolearms" ); }
}
public static SmallBulkEntry[] LargeMaces => GetEntries( "Blacksmith", "largemaces" );
public static SmallBulkEntry[] LargeSwords
{
get{ return GetEntries( "Blacksmith", "largeswords" ); }
}
public static SmallBulkEntry[] LargePolearms => GetEntries( "Blacksmith", "largepolearms" );
public static SmallBulkEntry[] LargeSwords => GetEntries( "Blacksmith", "largeswords" );
public static SmallBulkEntry[] BoneSet
{
get{ return GetEntries( "Tailoring", "boneset" ); }
}
public static SmallBulkEntry[] BoneSet => GetEntries( "Tailoring", "boneset" );
public static SmallBulkEntry[] Farmer
{
get{ return GetEntries( "Tailoring", "farmer" ); }
}
public static SmallBulkEntry[] Farmer => GetEntries( "Tailoring", "farmer" );
public static SmallBulkEntry[] FemaleLeatherSet
{
get{ return GetEntries( "Tailoring", "femaleleatherset" ); }
}
public static SmallBulkEntry[] FemaleLeatherSet => GetEntries( "Tailoring", "femaleleatherset" );
public static SmallBulkEntry[] FisherGirl
{
get{ return GetEntries( "Tailoring", "fishergirl" ); }
}
public static SmallBulkEntry[] FisherGirl => GetEntries( "Tailoring", "fishergirl" );
public static SmallBulkEntry[] Gypsy
{
get{ return GetEntries( "Tailoring", "gypsy" ); }
}
public static SmallBulkEntry[] Gypsy => GetEntries( "Tailoring", "gypsy" );
public static SmallBulkEntry[] HatSet
{
get{ return GetEntries( "Tailoring", "hatset" ); }
}
public static SmallBulkEntry[] HatSet => GetEntries( "Tailoring", "hatset" );
public static SmallBulkEntry[] Jester
{
get{ return GetEntries( "Tailoring", "jester" ); }
}
public static SmallBulkEntry[] Jester => GetEntries( "Tailoring", "jester" );
public static SmallBulkEntry[] Lady
{
get{ return GetEntries( "Tailoring", "lady" ); }
}
public static SmallBulkEntry[] Lady => GetEntries( "Tailoring", "lady" );
public static SmallBulkEntry[] MaleLeatherSet
{
get{ return GetEntries( "Tailoring", "maleleatherset" ); }
}
public static SmallBulkEntry[] MaleLeatherSet => GetEntries( "Tailoring", "maleleatherset" );
public static SmallBulkEntry[] Pirate
{
get{ return GetEntries( "Tailoring", "pirate" ); }
}
public static SmallBulkEntry[] Pirate => GetEntries( "Tailoring", "pirate" );
public static SmallBulkEntry[] ShoeSet
{
get{ return GetEntries( "Tailoring", "shoeset" ); }
}
public static SmallBulkEntry[] ShoeSet => GetEntries( "Tailoring", "shoeset" );
public static SmallBulkEntry[] StuddedSet
{
get{ return GetEntries( "Tailoring", "studdedset" ); }
}
public static SmallBulkEntry[] StuddedSet => GetEntries( "Tailoring", "studdedset" );
public static SmallBulkEntry[] TownCrier
{
get{ return GetEntries( "Tailoring", "towncrier" ); }
}
public static SmallBulkEntry[] TownCrier => GetEntries( "Tailoring", "towncrier" );
public static SmallBulkEntry[] Wizard
{
get{ return GetEntries( "Tailoring", "wizard" ); }
}
public static SmallBulkEntry[] Wizard => GetEntries( "Tailoring", "wizard" );
private static Dictionary<string,Dictionary<string,SmallBulkEntry[]>> m_Cache;
@ -155,13 +89,13 @@ namespace Server.Engines.BulkOrders
public LargeBulkEntry( LargeBOD owner, SmallBulkEntry details )
{
m_Owner = owner;
m_Details = details;
Owner = owner;
Details = details;
}
public LargeBulkEntry( LargeBOD owner, GenericReader reader )
{
m_Owner = owner;
Owner = owner;
m_Amount = reader.ReadInt();
Type realType = null;
@ -171,15 +105,15 @@ namespace Server.Engines.BulkOrders
if ( type != null )
realType = ScriptCompiler.FindTypeByFullName( type );
m_Details = new SmallBulkEntry( realType, reader.ReadInt(), reader.ReadInt() );
Details = new SmallBulkEntry( realType, reader.ReadInt(), reader.ReadInt() );
}
public void Serialize( GenericWriter writer )
{
writer.Write( m_Amount );
writer.Write( m_Details.Type == null ? null : m_Details.Type.FullName );
writer.Write( m_Details.Number );
writer.Write( m_Details.Graphic );
writer.Write( Details.Type == null ? null : Details.Type.FullName );
writer.Write( Details.Number );
writer.Write( Details.Graphic );
}
}
}

View file

@ -1,140 +1,150 @@
using System;
using System.Collections;
using Server;
using Server.Items;
using Mat = Server.Engines.BulkOrders.BulkMaterialType;
using System.Collections.Generic;
using Mat = Server.Engines.BulkOrders.BulkMaterialType;
namespace Server.Engines.BulkOrders
{
[TypeAlias( "Scripts.Engines.BulkOrders.LargeSmithBOD" )]
public class LargeSmithBOD : LargeBOD
{
public static double[] m_BlacksmithMaterialChances = new double[]
{
0.501953125, // None
0.250000000, // Dull Copper
0.125000000, // Shadow Iron
0.062500000, // Copper
0.031250000, // Bronze
0.015625000, // Gold
0.007812500, // Agapite
0.003906250, // Verite
0.001953125 // Valorite
};
[TypeAlias("Scripts.Engines.BulkOrders.LargeSmithBOD")]
public class LargeSmithBOD : LargeBOD
{
public static double[] m_BlacksmithMaterialChances =
{
0.501953125, // None
0.250000000, // Dull Copper
0.125000000, // Shadow Iron
0.062500000, // Copper
0.031250000, // Bronze
0.015625000, // Gold
0.007812500, // Agapite
0.003906250, // Verite
0.001953125 // Valorite
};
public override int ComputeFame()
{
return SmithRewardCalculator.Instance.ComputeFame( this );
}
[Constructible]
public LargeSmithBOD()
{
LargeBulkEntry[] entries;
bool useMaterials = true;
public override int ComputeGold()
{
return SmithRewardCalculator.Instance.ComputeGold( this );
}
int rand = Utility.Random(8);
[Constructible]
public LargeSmithBOD()
{
LargeBulkEntry[] entries;
bool useMaterials = true;
int rand = Utility.Random( 8 );
switch (rand)
{
default:
case 0:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.LargeRing);
break;
case 1:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.LargePlate);
break;
case 2:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.LargeChain);
break;
case 3:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.LargeAxes);
break;
case 4:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.LargeFencing);
break;
case 5:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.LargeMaces);
break;
case 6:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.LargePolearms);
break;
case 7:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.LargeSwords);
break;
}
switch ( rand )
{
default:
case 0: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargeRing ); break;
case 1: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargePlate ); break;
case 2: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargeChain ); break;
case 3: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargeAxes ); break;
case 4: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargeFencing ); break;
case 5: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargeMaces ); break;
case 6: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargePolearms ); break;
case 7: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.LargeSwords ); break;
}
if( rand > 2 && rand < 8 )
useMaterials = false;
if (rand > 2 && rand < 8)
useMaterials = false;
int hue = 0x44E;
int amountMax = Utility.RandomList( 10, 15, 20, 20 );
bool reqExceptional = ( 0.825 > Utility.RandomDouble() );
int hue = 0x44E;
int amountMax = Utility.RandomList(10, 15, 20, 20);
bool reqExceptional = 0.825 > Utility.RandomDouble();
BulkMaterialType material;
BulkMaterialType material;
if ( useMaterials )
material = GetRandomMaterial( BulkMaterialType.DullCopper, m_BlacksmithMaterialChances );
else
material = BulkMaterialType.None;
if (useMaterials)
material = GetRandomMaterial(BulkMaterialType.DullCopper, m_BlacksmithMaterialChances);
else
material = BulkMaterialType.None;
this.Hue = hue;
this.AmountMax = amountMax;
this.Entries = entries;
this.RequireExceptional = reqExceptional;
this.Material = material;
}
Hue = hue;
AmountMax = amountMax;
Entries = entries;
RequireExceptional = reqExceptional;
Material = material;
}
public LargeSmithBOD( int amountMax, bool reqExceptional, BulkMaterialType mat, LargeBulkEntry[] entries )
{
this.Hue = 0x44E;
this.AmountMax = amountMax;
this.Entries = entries;
this.RequireExceptional = reqExceptional;
this.Material = mat;
}
public LargeSmithBOD(int amountMax, bool reqExceptional, BulkMaterialType mat, LargeBulkEntry[] entries)
{
Hue = 0x44E;
AmountMax = amountMax;
Entries = entries;
RequireExceptional = reqExceptional;
Material = mat;
}
public override List<Item> ComputeRewards( bool full )
{
List<Item> list = new List<Item>();
public LargeSmithBOD(Serial serial) : base(serial)
{
}
RewardGroup rewardGroup = SmithRewardCalculator.Instance.LookupRewards( SmithRewardCalculator.Instance.ComputePoints( this ) );
public override int ComputeFame()
{
return SmithRewardCalculator.Instance.ComputeFame(this);
}
if ( rewardGroup != null )
{
if ( full )
{
for ( int i = 0; i < rewardGroup.Items.Length; ++i )
{
Item item = rewardGroup.Items[i].Construct();
public override int ComputeGold()
{
return SmithRewardCalculator.Instance.ComputeGold(this);
}
if ( item != null )
list.Add( item );
}
}
else
{
RewardItem rewardItem = rewardGroup.AcquireItem();
public override List<Item> ComputeRewards(bool full)
{
List<Item> list = new List<Item>();
if ( rewardItem != null )
{
Item item = rewardItem.Construct();
RewardGroup rewardGroup =
SmithRewardCalculator.Instance.LookupRewards(SmithRewardCalculator.Instance.ComputePoints(this));
if ( item != null )
list.Add( item );
}
}
}
if (rewardGroup != null)
{
if (full)
{
for (int i = 0; i < rewardGroup.Items.Length; ++i)
{
Item item = rewardGroup.Items[i].Construct();
return list;
}
if (item != null)
list.Add(item);
}
}
else
{
RewardItem rewardItem = rewardGroup.AcquireItem();
public LargeSmithBOD( Serial serial ) : base( serial )
{
}
Item item = rewardItem?.Construct();
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
if (item != null)
list.Add(item);
}
}
writer.Write( (int) 0 ); // version
}
return list;
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
int version = reader.ReadInt();
}
}
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View file

@ -1,135 +1,162 @@
using System;
using System.Collections;
using Server;
using Server.Items;
using Mat = Server.Engines.BulkOrders.BulkMaterialType;
using System.Collections.Generic;
using Mat = Server.Engines.BulkOrders.BulkMaterialType;
namespace Server.Engines.BulkOrders
{
public class LargeTailorBOD : LargeBOD
{
public static double[] m_TailoringMaterialChances = new double[]
{
0.857421875, // None
0.125000000, // Spined
0.015625000, // Horned
0.001953125 // Barbed
};
public class LargeTailorBOD : LargeBOD
{
public static double[] m_TailoringMaterialChances =
{
0.857421875, // None
0.125000000, // Spined
0.015625000, // Horned
0.001953125 // Barbed
};
public override int ComputeFame()
{
return TailorRewardCalculator.Instance.ComputeFame( this );
}
[Constructible]
public LargeTailorBOD()
{
LargeBulkEntry[] entries;
bool useMaterials = false;
public override int ComputeGold()
{
return TailorRewardCalculator.Instance.ComputeGold( this );
}
switch (Utility.Random(14))
{
default:
case 0:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.Farmer);
break;
case 1:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.FemaleLeatherSet);
useMaterials = true;
break;
case 2:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.FisherGirl);
break;
case 3:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.Gypsy);
break;
case 4:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.HatSet);
break;
case 5:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.Jester);
break;
case 6:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.Lady);
break;
case 7:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.MaleLeatherSet);
useMaterials = true;
break;
case 8:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.Pirate);
break;
case 9:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.ShoeSet);
useMaterials = Core.ML;
break;
case 10:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.StuddedSet);
useMaterials = true;
break;
case 11:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.TownCrier);
break;
case 12:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.Wizard);
break;
case 13:
entries = LargeBulkEntry.ConvertEntries(this, LargeBulkEntry.BoneSet);
useMaterials = true;
break;
}
[Constructible]
public LargeTailorBOD()
{
LargeBulkEntry[] entries;
bool useMaterials = false;
int hue = 0x483;
int amountMax = Utility.RandomList(10, 15, 20, 20);
bool reqExceptional = 0.825 > Utility.RandomDouble();
switch ( Utility.Random( 14 ) )
{
default:
case 0: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.Farmer ); break;
case 1: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.FemaleLeatherSet ); useMaterials = true; break;
case 2: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.FisherGirl ); break;
case 3: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.Gypsy ); break;
case 4: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.HatSet ); break;
case 5: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.Jester ); break;
case 6: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.Lady ); break;
case 7: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.MaleLeatherSet ); useMaterials = true; break;
case 8: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.Pirate ); break;
case 9: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.ShoeSet ); useMaterials = Core.ML; break;
case 10: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.StuddedSet ); useMaterials = true; break;
case 11: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.TownCrier ); break;
case 12: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.Wizard ); break;
case 13: entries = LargeBulkEntry.ConvertEntries( this, LargeBulkEntry.BoneSet ); useMaterials = true; break;
}
BulkMaterialType material;
int hue = 0x483;
int amountMax = Utility.RandomList( 10, 15, 20, 20 );
bool reqExceptional = ( 0.825 > Utility.RandomDouble() );
if (useMaterials)
material = GetRandomMaterial(BulkMaterialType.Spined, m_TailoringMaterialChances);
else
material = BulkMaterialType.None;
BulkMaterialType material;
Hue = hue;
AmountMax = amountMax;
Entries = entries;
RequireExceptional = reqExceptional;
Material = material;
}
if ( useMaterials )
material = GetRandomMaterial( BulkMaterialType.Spined, m_TailoringMaterialChances );
else
material = BulkMaterialType.None;
public LargeTailorBOD(int amountMax, bool reqExceptional, BulkMaterialType mat, LargeBulkEntry[] entries)
{
Hue = 0x483;
AmountMax = amountMax;
Entries = entries;
RequireExceptional = reqExceptional;
Material = mat;
}
this.Hue = hue;
this.AmountMax = amountMax;
this.Entries = entries;
this.RequireExceptional = reqExceptional;
this.Material = material;
}
public LargeTailorBOD(Serial serial) : base(serial)
{
}
public LargeTailorBOD( int amountMax, bool reqExceptional, BulkMaterialType mat, LargeBulkEntry[] entries )
{
this.Hue = 0x483;
this.AmountMax = amountMax;
this.Entries = entries;
this.RequireExceptional = reqExceptional;
this.Material = mat;
}
public override int ComputeFame()
{
return TailorRewardCalculator.Instance.ComputeFame(this);
}
public override List<Item> ComputeRewards( bool full )
{
List<Item> list = new List<Item>();
public override int ComputeGold()
{
return TailorRewardCalculator.Instance.ComputeGold(this);
}
RewardGroup rewardGroup = TailorRewardCalculator.Instance.LookupRewards( TailorRewardCalculator.Instance.ComputePoints( this ) );
public override List<Item> ComputeRewards(bool full)
{
List<Item> list = new List<Item>();
if ( rewardGroup != null )
{
if ( full )
{
for ( int i = 0; i < rewardGroup.Items.Length; ++i )
{
Item item = rewardGroup.Items[i].Construct();
RewardGroup rewardGroup =
TailorRewardCalculator.Instance.LookupRewards(TailorRewardCalculator.Instance.ComputePoints(this));
if ( item != null )
list.Add( item );
}
}
else
{
RewardItem rewardItem = rewardGroup.AcquireItem();
if (rewardGroup != null)
{
if (full)
{
for (int i = 0; i < rewardGroup.Items.Length; ++i)
{
Item item = rewardGroup.Items[i].Construct();
if ( rewardItem != null )
{
Item item = rewardItem.Construct();
if (item != null)
list.Add(item);
}
}
else
{
RewardItem rewardItem = rewardGroup.AcquireItem();
if ( item != null )
list.Add( item );
}
}
}
Item item = rewardItem?.Construct();
return list;
}
if (item != null)
list.Add(item);
}
}
public LargeTailorBOD( Serial serial ) : base( serial )
{
}
return list;
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write( (int) 0 ); // version
}
writer.Write(0); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
int version = reader.ReadInt();
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,291 +1,329 @@
using System;
using System.Collections;
using Server;
using Server.Items;
using System.Collections.Generic;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.BulkOrders
{
[TypeAlias( "Scripts.Engines.BulkOrders.SmallBOD" )]
public abstract class SmallBOD : Item
{
private int m_AmountCur, m_AmountMax;
private Type m_Type;
private int m_Number;
private int m_Graphic;
private bool m_RequireExceptional;
private BulkMaterialType m_Material;
[TypeAlias("Scripts.Engines.BulkOrders.SmallBOD")]
public abstract class SmallBOD : Item
{
private int m_AmountCur, m_AmountMax;
private BulkMaterialType m_Material;
private int m_Number;
private bool m_RequireExceptional;
[CommandProperty( AccessLevel.GameMaster )]
public int AmountCur{ get{ return m_AmountCur; } set{ m_AmountCur = value; InvalidateProperties(); } }
[Constructible]
public SmallBOD(int hue, int amountMax, Type type, int number, int graphic, bool requireExeptional,
BulkMaterialType material) : base(Core.AOS ? 0x2258 : 0x14EF)
{
Weight = 1.0;
Hue = hue; // Blacksmith: 0x44E; Tailoring: 0x483
LootType = LootType.Blessed;
[CommandProperty( AccessLevel.GameMaster )]
public int AmountMax{ get{ return m_AmountMax; } set{ m_AmountMax = value; InvalidateProperties(); } }
m_AmountMax = amountMax;
Type = type;
m_Number = number;
Graphic = graphic;
m_RequireExceptional = requireExeptional;
m_Material = material;
}
[CommandProperty( AccessLevel.GameMaster )]
public Type Type{ get{ return m_Type; } set{ m_Type = value; } }
public SmallBOD() : base(Core.AOS ? 0x2258 : 0x14EF)
{
Weight = 1.0;
LootType = LootType.Blessed;
}
[CommandProperty( AccessLevel.GameMaster )]
public int Number{ get{ return m_Number; } set{ m_Number = value; InvalidateProperties(); } }
public SmallBOD(Serial serial) : base(serial)
{
}
[CommandProperty( AccessLevel.GameMaster )]
public int Graphic{ get{ return m_Graphic; } set{ m_Graphic = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public int AmountCur
{
get => m_AmountCur;
set
{
m_AmountCur = value;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public bool RequireExceptional{ get{ return m_RequireExceptional; } set{ m_RequireExceptional = value; InvalidateProperties(); } }
[CommandProperty(AccessLevel.GameMaster)]
public int AmountMax
{
get => m_AmountMax;
set
{
m_AmountMax = value;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public BulkMaterialType Material{ get{ return m_Material; } set{ m_Material = value; InvalidateProperties(); } }
[CommandProperty(AccessLevel.GameMaster)]
public Type Type{ get; set; }
[CommandProperty( AccessLevel.GameMaster )]
public bool Complete{ get{ return ( m_AmountCur == m_AmountMax ); } }
[CommandProperty(AccessLevel.GameMaster)]
public int Number
{
get => m_Number;
set
{
m_Number = value;
InvalidateProperties();
}
}
public override int LabelNumber => 1045151; // a bulk order deed
[CommandProperty(AccessLevel.GameMaster)]
public int Graphic{ get; set; }
[Constructible]
public SmallBOD( int hue, int amountMax, Type type, int number, int graphic, bool requireExeptional, BulkMaterialType material ) : base( Core.AOS ? 0x2258 : 0x14EF )
{
Weight = 1.0;
Hue = hue; // Blacksmith: 0x44E; Tailoring: 0x483
LootType = LootType.Blessed;
[CommandProperty(AccessLevel.GameMaster)]
public bool RequireExceptional
{
get => m_RequireExceptional;
set
{
m_RequireExceptional = value;
InvalidateProperties();
}
}
m_AmountMax = amountMax;
m_Type = type;
m_Number = number;
m_Graphic = graphic;
m_RequireExceptional = requireExeptional;
m_Material = material;
}
[CommandProperty(AccessLevel.GameMaster)]
public BulkMaterialType Material
{
get => m_Material;
set
{
m_Material = value;
InvalidateProperties();
}
}
public SmallBOD() : base( Core.AOS ? 0x2258 : 0x14EF )
{
Weight = 1.0;
LootType = LootType.Blessed;
}
[CommandProperty(AccessLevel.GameMaster)]
public bool Complete => m_AmountCur == m_AmountMax;
public static BulkMaterialType GetRandomMaterial( BulkMaterialType start, double[] chances )
{
double random = Utility.RandomDouble();
public override int LabelNumber => 1045151; // a bulk order deed
for ( int i = 0; i < chances.Length; ++i )
{
if ( random < chances[i] )
return ( i == 0 ? BulkMaterialType.None : start + (i - 1) );
public static BulkMaterialType GetRandomMaterial(BulkMaterialType start, double[] chances)
{
double random = Utility.RandomDouble();
random -= chances[i];
}
for (int i = 0; i < chances.Length; ++i)
{
if (random < chances[i])
return i == 0 ? BulkMaterialType.None : start + (i - 1);
return BulkMaterialType.None;
}
random -= chances[i];
}
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
return BulkMaterialType.None;
}
list.Add( 1060654 ); // small bulk order
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
if ( m_RequireExceptional )
list.Add( 1045141 ); // All items must be exceptional.
list.Add(1060654); // small bulk order
if ( m_Material != BulkMaterialType.None )
list.Add( SmallBODGump.GetMaterialNumberFor( m_Material ) ); // All items must be made with x material.
if (m_RequireExceptional)
list.Add(1045141); // All items must be exceptional.
list.Add( 1060656, m_AmountMax.ToString() ); // amount to make: ~1_val~
list.Add( 1060658, "#{0}\t{1}", m_Number, m_AmountCur ); // ~1_val~: ~2_val~
}
if (m_Material != BulkMaterialType.None)
list.Add(SmallBODGump.GetMaterialNumberFor(m_Material)); // All items must be made with x material.
public override void OnDoubleClick( Mobile from )
{
if ( IsChildOf( from.Backpack ) || InSecureTrade || RootParent is PlayerVendor )
from.SendGump( new SmallBODGump( from, this ) );
else
from.SendLocalizedMessage( 1045156 ); // You must have the deed in your backpack to use it.
}
list.Add(1060656, m_AmountMax.ToString()); // amount to make: ~1_val~
list.Add(1060658, "#{0}\t{1}", m_Number, m_AmountCur); // ~1_val~: ~2_val~
}
public override void OnDoubleClickNotAccessible( Mobile from )
{
OnDoubleClick( from );
}
public override void OnDoubleClick(Mobile from)
{
if (IsChildOf(from.Backpack) || InSecureTrade || RootParent is PlayerVendor)
from.SendGump(new SmallBODGump(from, this));
else
from.SendLocalizedMessage(1045156); // You must have the deed in your backpack to use it.
}
public override void OnDoubleClickSecureTrade( Mobile from )
{
OnDoubleClick( from );
}
public override void OnDoubleClickNotAccessible(Mobile from)
{
OnDoubleClick(from);
}
public void BeginCombine( Mobile from )
{
if ( m_AmountCur < m_AmountMax )
from.Target = new SmallBODTarget( this );
else
from.SendLocalizedMessage( 1045166 ); // The maximum amount of requested items have already been combined to this deed.
}
public override void OnDoubleClickSecureTrade(Mobile from)
{
OnDoubleClick(from);
}
public abstract List<Item> ComputeRewards( bool full );
public abstract int ComputeGold();
public abstract int ComputeFame();
public void BeginCombine(Mobile from)
{
if (m_AmountCur < m_AmountMax)
from.Target = new SmallBODTarget(this);
else
from.SendLocalizedMessage(
1045166); // The maximum amount of requested items have already been combined to this deed.
}
public virtual void GetRewards( out Item reward, out int gold, out int fame )
{
reward = null;
gold = ComputeGold();
fame = ComputeFame();
public abstract List<Item> ComputeRewards(bool full);
public abstract int ComputeGold();
public abstract int ComputeFame();
List<Item> rewards = ComputeRewards( false );
public virtual void GetRewards(out Item reward, out int gold, out int fame)
{
reward = null;
gold = ComputeGold();
fame = ComputeFame();
if ( rewards.Count > 0 )
{
reward = rewards[Utility.Random( rewards.Count )];
List<Item> rewards = ComputeRewards(false);
for ( int i = 0; i < rewards.Count; ++i )
{
if ( rewards[i] != reward )
rewards[i].Delete();
}
}
}
if (rewards.Count > 0)
{
reward = rewards[Utility.Random(rewards.Count)];
public static BulkMaterialType GetMaterial( CraftResource resource )
{
switch ( resource )
{
case CraftResource.DullCopper: return BulkMaterialType.DullCopper;
case CraftResource.ShadowIron: return BulkMaterialType.ShadowIron;
case CraftResource.Copper: return BulkMaterialType.Copper;
case CraftResource.Bronze: return BulkMaterialType.Bronze;
case CraftResource.Gold: return BulkMaterialType.Gold;
case CraftResource.Agapite: return BulkMaterialType.Agapite;
case CraftResource.Verite: return BulkMaterialType.Verite;
case CraftResource.Valorite: return BulkMaterialType.Valorite;
case CraftResource.SpinedLeather: return BulkMaterialType.Spined;
case CraftResource.HornedLeather: return BulkMaterialType.Horned;
case CraftResource.BarbedLeather: return BulkMaterialType.Barbed;
}
for (int i = 0; i < rewards.Count; ++i)
if (rewards[i] != reward)
rewards[i].Delete();
}
}
return BulkMaterialType.None;
}
public static BulkMaterialType GetMaterial(CraftResource resource)
{
switch (resource)
{
case CraftResource.DullCopper: return BulkMaterialType.DullCopper;
case CraftResource.ShadowIron: return BulkMaterialType.ShadowIron;
case CraftResource.Copper: return BulkMaterialType.Copper;
case CraftResource.Bronze: return BulkMaterialType.Bronze;
case CraftResource.Gold: return BulkMaterialType.Gold;
case CraftResource.Agapite: return BulkMaterialType.Agapite;
case CraftResource.Verite: return BulkMaterialType.Verite;
case CraftResource.Valorite: return BulkMaterialType.Valorite;
case CraftResource.SpinedLeather: return BulkMaterialType.Spined;
case CraftResource.HornedLeather: return BulkMaterialType.Horned;
case CraftResource.BarbedLeather: return BulkMaterialType.Barbed;
}
public void EndCombine( Mobile from, object o )
{
if ( o is Item && ((Item)o).IsChildOf( from.Backpack ) )
{
Type objectType = o.GetType();
return BulkMaterialType.None;
}
if ( m_AmountCur >= m_AmountMax )
{
from.SendLocalizedMessage( 1045166 ); // The maximum amount of requested items have already been combined to this deed.
}
else if ( m_Type == null || (objectType != m_Type && !objectType.IsSubclassOf( m_Type )) || (!(o is BaseWeapon) && !(o is BaseArmor) && !(o is BaseClothing)) )
{
from.SendLocalizedMessage( 1045169 ); // The item is not in the request.
}
else
{
BulkMaterialType material = BulkMaterialType.None;
public void EndCombine(Mobile from, object o)
{
if (o is Item item && item.IsChildOf(from.Backpack))
{
Type objectType = item.GetType();
if ( o is BaseArmor )
material = GetMaterial( ((BaseArmor)o).Resource );
else if ( o is BaseClothing )
material = GetMaterial( ((BaseClothing)o).Resource );
if (m_AmountCur >= m_AmountMax)
{
from.SendLocalizedMessage(
1045166); // The maximum amount of requested items have already been combined to this deed.
}
else if (Type == null || objectType != Type && !objectType.IsSubclassOf(Type) ||
!(item is BaseWeapon) && !(item is BaseArmor) && !(item is BaseClothing))
{
from.SendLocalizedMessage(1045169); // The item is not in the request.
}
else
{
BaseArmor armor = item as BaseArmor;
BaseClothing clothing = item as BaseClothing;
if ( m_Material >= BulkMaterialType.DullCopper && m_Material <= BulkMaterialType.Valorite && material != m_Material )
{
from.SendLocalizedMessage( 1045168 ); // The item is not made from the requested ore.
}
else if ( m_Material >= BulkMaterialType.Spined && m_Material <= BulkMaterialType.Barbed && material != m_Material )
{
from.SendLocalizedMessage( 1049352 ); // The item is not made from the requested leather type.
}
else
{
bool isExceptional = false;
BulkMaterialType material = GetMaterial(armor?.Resource ?? clothing?.Resource ?? CraftResource.None);
if ( o is BaseWeapon )
isExceptional = ( ((BaseWeapon)o).Quality == WeaponQuality.Exceptional );
else if ( o is BaseArmor )
isExceptional = ( ((BaseArmor)o).Quality == ArmorQuality.Exceptional );
else if ( o is BaseClothing )
isExceptional = ( ((BaseClothing)o).Quality == ClothingQuality.Exceptional );
if (m_Material >= BulkMaterialType.DullCopper && m_Material <= BulkMaterialType.Valorite &&
material != m_Material)
{
from.SendLocalizedMessage(1045168); // The item is not made from the requested ore.
}
else if (m_Material >= BulkMaterialType.Spined && m_Material <= BulkMaterialType.Barbed &&
material != m_Material)
{
from.SendLocalizedMessage(1049352); // The item is not made from the requested leather type.
}
else
{
bool isExceptional;
if ( m_RequireExceptional && !isExceptional )
{
from.SendLocalizedMessage( 1045167 ); // The item must be exceptional.
}
else
{
((Item)o).Delete();
++AmountCur;
if (item is BaseWeapon weapon)
isExceptional = weapon.Quality == WeaponQuality.Exceptional;
else if (armor != null)
isExceptional = armor.Quality == ArmorQuality.Exceptional;
else
isExceptional = clothing.Quality == ClothingQuality.Exceptional;
from.SendLocalizedMessage( 1045170 ); // The item has been combined with the deed.
if (m_RequireExceptional && !isExceptional)
{
from.SendLocalizedMessage(1045167); // The item must be exceptional.
}
else
{
item.Delete();
++AmountCur;
from.SendGump( new SmallBODGump( from, this ) );
from.SendLocalizedMessage(1045170); // The item has been combined with the deed.
if ( m_AmountCur < m_AmountMax )
BeginCombine( from );
}
}
}
}
else
{
from.SendLocalizedMessage( 1045158 ); // You must have the item in your backpack to target it.
}
}
from.SendGump(new SmallBODGump(from, this));
public SmallBOD( Serial serial ) : base( serial )
{
}
if (m_AmountCur < m_AmountMax)
BeginCombine(from);
}
}
}
}
else
{
from.SendLocalizedMessage(1045158); // You must have the item in your backpack to target it.
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write( (int) 0 ); // version
writer.Write(0); // version
writer.Write( m_AmountCur );
writer.Write( m_AmountMax );
writer.Write( m_Type == null ? null : m_Type.FullName );
writer.Write( m_Number );
writer.Write( m_Graphic );
writer.Write( m_RequireExceptional );
writer.Write( (int) m_Material );
}
writer.Write(m_AmountCur);
writer.Write(m_AmountMax);
writer.Write(Type == null ? null : Type.FullName);
writer.Write(m_Number);
writer.Write(Graphic);
writer.Write(m_RequireExceptional);
writer.Write((int)m_Material);
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
m_AmountCur = reader.ReadInt();
m_AmountMax = reader.ReadInt();
switch (version)
{
case 0:
{
m_AmountCur = reader.ReadInt();
m_AmountMax = reader.ReadInt();
string type = reader.ReadString();
string type = reader.ReadString();
if ( type != null )
m_Type = ScriptCompiler.FindTypeByFullName( type );
if (type != null)
Type = ScriptCompiler.FindTypeByFullName(type);
m_Number = reader.ReadInt();
m_Graphic = reader.ReadInt();
m_RequireExceptional = reader.ReadBool();
m_Material = (BulkMaterialType)reader.ReadInt();
m_Number = reader.ReadInt();
Graphic = reader.ReadInt();
m_RequireExceptional = reader.ReadBool();
m_Material = (BulkMaterialType)reader.ReadInt();
break;
}
}
break;
}
}
if ( Weight == 0.0 )
Weight = 1.0;
if (Weight == 0.0)
Weight = 1.0;
if ( Core.AOS && ItemID == 0x14EF )
ItemID = 0x2258;
if (Core.AOS && ItemID == 0x14EF)
ItemID = 0x2258;
if ( Parent == null && Map == Map.Internal && Location == Point3D.Zero )
Delete();
}
}
}
if (Parent == null && Map == Map.Internal && Location == Point3D.Zero)
Delete();
}
}
}

View file

@ -1,93 +1,93 @@
using System;
using Server;
using Server.Gumps;
using Server.Network;
namespace Server.Engines.BulkOrders
{
public class SmallBODAcceptGump : Gump
{
private SmallBOD m_Deed;
private Mobile m_From;
public class SmallBODAcceptGump : Gump
{
private SmallBOD m_Deed;
private Mobile m_From;
public SmallBODAcceptGump( Mobile from, SmallBOD deed ) : base( 50, 50 )
{
m_From = from;
m_Deed = deed;
public SmallBODAcceptGump(Mobile from, SmallBOD deed) : base(50, 50)
{
m_From = from;
m_Deed = deed;
m_From.CloseGump( typeof( LargeBODAcceptGump ) );
m_From.CloseGump( typeof( SmallBODAcceptGump ) );
m_From.CloseGump(typeof(LargeBODAcceptGump));
m_From.CloseGump(typeof(SmallBODAcceptGump));
AddPage( 0 );
AddPage(0);
AddBackground( 25, 10, 430, 264, 5054 );
AddBackground(25, 10, 430, 264, 5054);
AddImageTiled( 33, 20, 413, 245, 2624 );
AddAlphaRegion( 33, 20, 413, 245 );
AddImageTiled(33, 20, 413, 245, 2624);
AddAlphaRegion(33, 20, 413, 245);
AddImage( 20, 5, 10460 );
AddImage( 430, 5, 10460 );
AddImage( 20, 249, 10460 );
AddImage( 430, 249, 10460 );
AddImage(20, 5, 10460);
AddImage(430, 5, 10460);
AddImage(20, 249, 10460);
AddImage(430, 249, 10460);
AddHtmlLocalized( 190, 25, 120, 20, 1045133, 0x7FFF, false, false ); // A bulk order
AddHtmlLocalized( 40, 48, 350, 20, 1045135, 0x7FFF, false, false ); // Ah! Thanks for the goods! Would you help me out?
AddHtmlLocalized(190, 25, 120, 20, 1045133, 0x7FFF, false, false); // A bulk order
AddHtmlLocalized(40, 48, 350, 20, 1045135, 0x7FFF, false,
false); // Ah! Thanks for the goods! Would you help me out?
AddHtmlLocalized( 40, 72, 210, 20, 1045138, 0x7FFF, false, false ); // Amount to make:
AddLabel( 250, 72, 1152, deed.AmountMax.ToString() );
AddHtmlLocalized(40, 72, 210, 20, 1045138, 0x7FFF, false, false); // Amount to make:
AddLabel(250, 72, 1152, deed.AmountMax.ToString());
AddHtmlLocalized( 40, 96, 120, 20, 1045136, 0x7FFF, false, false ); // Item requested:
AddItem( 385, 96, deed.Graphic );
AddHtmlLocalized( 40, 120, 210, 20, deed.Number, 0xFFFFFF, false, false );
AddHtmlLocalized(40, 96, 120, 20, 1045136, 0x7FFF, false, false); // Item requested:
AddItem(385, 96, deed.Graphic);
AddHtmlLocalized(40, 120, 210, 20, deed.Number, 0xFFFFFF, false, false);
if ( deed.RequireExceptional || deed.Material != BulkMaterialType.None )
{
AddHtmlLocalized( 40, 144, 210, 20, 1045140, 0x7FFF, false, false ); // Special requirements to meet:
if (deed.RequireExceptional || deed.Material != BulkMaterialType.None)
{
AddHtmlLocalized(40, 144, 210, 20, 1045140, 0x7FFF, false, false); // Special requirements to meet:
if ( deed.RequireExceptional )
AddHtmlLocalized( 40, 168, 350, 20, 1045141, 0x7FFF, false, false ); // All items must be exceptional.
if (deed.RequireExceptional)
AddHtmlLocalized(40, 168, 350, 20, 1045141, 0x7FFF, false, false); // All items must be exceptional.
if ( deed.Material != BulkMaterialType.None )
AddHtmlLocalized( 40, deed.RequireExceptional ? 192 : 168, 350, 20, GetMaterialNumberFor( deed.Material ), 0x7FFF, false, false ); // All items must be made with x material.
}
if (deed.Material != BulkMaterialType.None)
AddHtmlLocalized(40, deed.RequireExceptional ? 192 : 168, 350, 20, GetMaterialNumberFor(deed.Material),
0x7FFF, false, false); // All items must be made with x material.
}
AddHtmlLocalized( 40, 216, 350, 20, 1045139, 0x7FFF, false, false ); // Do you want to accept this order?
AddHtmlLocalized(40, 216, 350, 20, 1045139, 0x7FFF, false, false); // Do you want to accept this order?
AddButton( 100, 240, 4005, 4007, 1, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 135, 240, 120, 20, 1006044, 0x7FFF, false, false ); // Ok
AddButton(100, 240, 4005, 4007, 1, GumpButtonType.Reply, 0);
AddHtmlLocalized(135, 240, 120, 20, 1006044, 0x7FFF, false, false); // Ok
AddButton( 275, 240, 4005, 4007, 0, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 310, 240, 120, 20, 1011012, 0x7FFF, false, false ); // CANCEL
}
AddButton(275, 240, 4005, 4007, 0, GumpButtonType.Reply, 0);
AddHtmlLocalized(310, 240, 120, 20, 1011012, 0x7FFF, false, false); // CANCEL
}
public override void OnResponse( NetState sender, RelayInfo info )
{
if ( info.ButtonID == 1 ) // Ok
{
if ( m_From.PlaceInBackpack( m_Deed ) )
{
m_From.SendLocalizedMessage( 1045152 ); // The bulk order deed has been placed in your backpack.
}
else
{
m_From.SendLocalizedMessage( 1045150 ); // There is not enough room in your backpack for the deed.
m_Deed.Delete();
}
}
else
{
m_Deed.Delete();
}
}
public override void OnResponse(NetState sender, RelayInfo info)
{
if (info.ButtonID == 1) // Ok
{
if (m_From.PlaceInBackpack(m_Deed))
{
m_From.SendLocalizedMessage(1045152); // The bulk order deed has been placed in your backpack.
}
else
{
m_From.SendLocalizedMessage(1045150); // There is not enough room in your backpack for the deed.
m_Deed.Delete();
}
}
else
{
m_Deed.Delete();
}
}
public static int GetMaterialNumberFor( BulkMaterialType material )
{
if ( material >= BulkMaterialType.DullCopper && material <= BulkMaterialType.Valorite )
return 1045142 + (int)(material - BulkMaterialType.DullCopper);
else if ( material >= BulkMaterialType.Spined && material <= BulkMaterialType.Barbed )
return 1049348 + (int)(material - BulkMaterialType.Spined);
public static int GetMaterialNumberFor(BulkMaterialType material)
{
if (material >= BulkMaterialType.DullCopper && material <= BulkMaterialType.Valorite)
return 1045142 + (material - BulkMaterialType.DullCopper);
if (material >= BulkMaterialType.Spined && material <= BulkMaterialType.Barbed)
return 1049348 + (material - BulkMaterialType.Spined);
return 0;
}
}
return 0;
}
}
}

View file

@ -1,83 +1,82 @@
using System;
using Server;
using Server.Gumps;
using Server.Network;
namespace Server.Engines.BulkOrders
{
public class SmallBODGump : Gump
{
private SmallBOD m_Deed;
private Mobile m_From;
public class SmallBODGump : Gump
{
private SmallBOD m_Deed;
private Mobile m_From;
public SmallBODGump( Mobile from, SmallBOD deed ) : base( 25, 25 )
{
m_From = from;
m_Deed = deed;
public SmallBODGump(Mobile from, SmallBOD deed) : base(25, 25)
{
m_From = from;
m_Deed = deed;
m_From.CloseGump( typeof( LargeBODGump ) );
m_From.CloseGump( typeof( SmallBODGump ) );
m_From.CloseGump(typeof(LargeBODGump));
m_From.CloseGump(typeof(SmallBODGump));
AddPage( 0 );
AddPage(0);
AddBackground( 50, 10, 455, 260, 5054 );
AddImageTiled( 58, 20, 438, 241, 2624 );
AddAlphaRegion( 58, 20, 438, 241 );
AddBackground(50, 10, 455, 260, 5054);
AddImageTiled(58, 20, 438, 241, 2624);
AddAlphaRegion(58, 20, 438, 241);
AddImage( 45, 5, 10460 );
AddImage( 480, 5, 10460 );
AddImage( 45, 245, 10460 );
AddImage( 480, 245, 10460 );
AddImage(45, 5, 10460);
AddImage(480, 5, 10460);
AddImage(45, 245, 10460);
AddImage(480, 245, 10460);
AddHtmlLocalized( 225, 25, 120, 20, 1045133, 0x7FFF, false, false ); // A bulk order
AddHtmlLocalized(225, 25, 120, 20, 1045133, 0x7FFF, false, false); // A bulk order
AddHtmlLocalized( 75, 48, 250, 20, 1045138, 0x7FFF, false, false ); // Amount to make:
AddLabel( 275, 48, 1152, deed.AmountMax.ToString() );
AddHtmlLocalized(75, 48, 250, 20, 1045138, 0x7FFF, false, false); // Amount to make:
AddLabel(275, 48, 1152, deed.AmountMax.ToString());
AddHtmlLocalized( 275, 76, 200, 20, 1045153, 0x7FFF, false, false ); // Amount finished:
AddHtmlLocalized( 75, 72, 120, 20, 1045136, 0x7FFF, false, false ); // Item requested:
AddHtmlLocalized(275, 76, 200, 20, 1045153, 0x7FFF, false, false); // Amount finished:
AddHtmlLocalized(75, 72, 120, 20, 1045136, 0x7FFF, false, false); // Item requested:
AddItem( 410, 72, deed.Graphic );
AddItem(410, 72, deed.Graphic);
AddHtmlLocalized( 75, 96, 210, 20, deed.Number, 0x7FFF, false, false );
AddLabel( 275, 96, 0x480, deed.AmountCur.ToString() );
AddHtmlLocalized(75, 96, 210, 20, deed.Number, 0x7FFF, false, false);
AddLabel(275, 96, 0x480, deed.AmountCur.ToString());
if ( deed.RequireExceptional || deed.Material != BulkMaterialType.None )
AddHtmlLocalized( 75, 120, 200, 20, 1045140, 0x7FFF, false, false ); // Special requirements to meet:
if (deed.RequireExceptional || deed.Material != BulkMaterialType.None)
AddHtmlLocalized(75, 120, 200, 20, 1045140, 0x7FFF, false, false); // Special requirements to meet:
if ( deed.RequireExceptional )
AddHtmlLocalized( 75, 144, 300, 20, 1045141, 0x7FFF, false, false ); // All items must be exceptional.
if (deed.RequireExceptional)
AddHtmlLocalized(75, 144, 300, 20, 1045141, 0x7FFF, false, false); // All items must be exceptional.
if ( deed.Material != BulkMaterialType.None )
AddHtmlLocalized( 75, deed.RequireExceptional ? 168 : 144, 300, 20, GetMaterialNumberFor( deed.Material ), 0x7FFF, false, false ); // All items must be made with x material.
if (deed.Material != BulkMaterialType.None)
AddHtmlLocalized(75, deed.RequireExceptional ? 168 : 144, 300, 20, GetMaterialNumberFor(deed.Material),
0x7FFF, false, false); // All items must be made with x material.
AddButton( 125, 192, 4005, 4007, 2, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 160, 192, 300, 20, 1045154, 0x7FFF, false, false ); // Combine this deed with the item requested.
AddButton(125, 192, 4005, 4007, 2, GumpButtonType.Reply, 0);
AddHtmlLocalized(160, 192, 300, 20, 1045154, 0x7FFF, false, false); // Combine this deed with the item requested.
AddButton( 125, 216, 4005, 4007, 1, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 160, 216, 120, 20, 1011441, 0x7FFF, false, false ); // EXIT
}
AddButton(125, 216, 4005, 4007, 1, GumpButtonType.Reply, 0);
AddHtmlLocalized(160, 216, 120, 20, 1011441, 0x7FFF, false, false); // EXIT
}
public override void OnResponse( NetState sender, RelayInfo info )
{
if ( m_Deed.Deleted || !m_Deed.IsChildOf( m_From.Backpack ) )
return;
public override void OnResponse(NetState sender, RelayInfo info)
{
if (m_Deed.Deleted || !m_Deed.IsChildOf(m_From.Backpack))
return;
if ( info.ButtonID == 2 ) // Combine
{
m_From.SendGump( new SmallBODGump( m_From, m_Deed ) );
m_Deed.BeginCombine( m_From );
}
}
if (info.ButtonID == 2) // Combine
{
m_From.SendGump(new SmallBODGump(m_From, m_Deed));
m_Deed.BeginCombine(m_From);
}
}
public static int GetMaterialNumberFor( BulkMaterialType material )
{
if ( material >= BulkMaterialType.DullCopper && material <= BulkMaterialType.Valorite )
return 1045142 + (int)(material - BulkMaterialType.DullCopper);
else if ( material >= BulkMaterialType.Spined && material <= BulkMaterialType.Barbed )
return 1049348 + (int)(material - BulkMaterialType.Spined);
public static int GetMaterialNumberFor(BulkMaterialType material)
{
if (material >= BulkMaterialType.DullCopper && material <= BulkMaterialType.Valorite)
return 1045142 + (material - BulkMaterialType.DullCopper);
if (material >= BulkMaterialType.Spined && material <= BulkMaterialType.Barbed)
return 1049348 + (material - BulkMaterialType.Spined);
return 0;
}
}
return 0;
}
}
}

View file

@ -1,25 +1,22 @@
using System;
using Server;
using Server.Targeting;
using Server.Network;
namespace Server.Engines.BulkOrders
{
public class SmallBODTarget : Target
{
private SmallBOD m_Deed;
public class SmallBODTarget : Target
{
private SmallBOD m_Deed;
public SmallBODTarget( SmallBOD deed ) : base( 18, false, TargetFlags.None )
{
m_Deed = deed;
}
public SmallBODTarget(SmallBOD deed) : base(18, false, TargetFlags.None)
{
m_Deed = deed;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( m_Deed.Deleted || !m_Deed.IsChildOf( from.Backpack ) )
return;
protected override void OnTarget(Mobile from, object targeted)
{
if (m_Deed.Deleted || !m_Deed.IsChildOf(from.Backpack))
return;
m_Deed.EndCombine( from, targeted );
}
}
m_Deed.EndCombine(from, targeted);
}
}
}

View file

@ -1,46 +1,31 @@
using System;
using System.Collections.Generic;
using System.IO;
using Server;
namespace Server.Engines.BulkOrders
{
public class SmallBulkEntry
{
private Type m_Type;
private int m_Number;
private int m_Graphic;
public Type Type { get; }
public Type Type{ get{ return m_Type; } }
public int Number{ get{ return m_Number; } }
public int Graphic{ get{ return m_Graphic; } }
public int Number { get; }
public int Graphic { get; }
public SmallBulkEntry( Type type, int number, int graphic )
{
m_Type = type;
m_Number = number;
m_Graphic = graphic;
Type = type;
Number = number;
Graphic = graphic;
}
public static SmallBulkEntry[] BlacksmithWeapons
{
get{ return GetEntries( "Blacksmith", "weapons" ); }
}
public static SmallBulkEntry[] BlacksmithWeapons => GetEntries( "Blacksmith", "weapons" );
public static SmallBulkEntry[] BlacksmithArmor
{
get{ return GetEntries( "Blacksmith", "armor" ); }
}
public static SmallBulkEntry[] BlacksmithArmor => GetEntries( "Blacksmith", "armor" );
public static SmallBulkEntry[] TailorCloth
{
get{ return GetEntries( "Tailoring", "cloth" ); }
}
public static SmallBulkEntry[] TailorCloth => GetEntries( "Tailoring", "cloth" );
public static SmallBulkEntry[] TailorLeather
{
get{ return GetEntries( "Tailoring", "leather" ); }
}
public static SmallBulkEntry[] TailorLeather => GetEntries( "Tailoring", "leather" );
private static Dictionary<string, Dictionary<string, SmallBulkEntry[]>> m_Cache;
@ -60,7 +45,7 @@ namespace Server.Engines.BulkOrders
public static SmallBulkEntry[] LoadEntries( string type, string name )
{
return LoadEntries( String.Format( "Data/Bulk Orders/{0}/{1}.cfg", type, name ) );
return LoadEntries($"Data/Bulk Orders/{type}/{name}.cfg");
}
public static SmallBulkEntry[] LoadEntries( string path )

View file

@ -1,244 +1,261 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Engines.Craft;
using Server.Items;
using Mat = Server.Engines.BulkOrders.BulkMaterialType;
namespace Server.Engines.BulkOrders
{
[TypeAlias( "Scripts.Engines.BulkOrders.SmallSmithBOD" )]
public class SmallSmithBOD : SmallBOD
{
public static double[] m_BlacksmithMaterialChances = new double[]
{
0.501953125, // None
0.250000000, // Dull Copper
0.125000000, // Shadow Iron
0.062500000, // Copper
0.031250000, // Bronze
0.015625000, // Gold
0.007812500, // Agapite
0.003906250, // Verite
0.001953125 // Valorite
};
[TypeAlias("Scripts.Engines.BulkOrders.SmallSmithBOD")]
public class SmallSmithBOD : SmallBOD
{
public static double[] m_BlacksmithMaterialChances =
{
0.501953125, // None
0.250000000, // Dull Copper
0.125000000, // Shadow Iron
0.062500000, // Copper
0.031250000, // Bronze
0.015625000, // Gold
0.007812500, // Agapite
0.003906250, // Verite
0.001953125 // Valorite
};
public override int ComputeFame()
{
return SmithRewardCalculator.Instance.ComputeFame( this );
}
private SmallSmithBOD(SmallBulkEntry entry, BulkMaterialType material, int amountMax, bool reqExceptional)
{
Hue = 0x44E;
AmountMax = amountMax;
Type = entry.Type;
Number = entry.Number;
Graphic = entry.Graphic;
RequireExceptional = reqExceptional;
Material = material;
}
public override int ComputeGold()
{
return SmithRewardCalculator.Instance.ComputeGold( this );
}
[Constructible]
public SmallSmithBOD()
{
SmallBulkEntry[] entries;
bool useMaterials;
public override List<Item> ComputeRewards( bool full )
{
List<Item> list = new List<Item>();
if (useMaterials = Utility.RandomBool())
entries = SmallBulkEntry.BlacksmithArmor;
else
entries = SmallBulkEntry.BlacksmithWeapons;
RewardGroup rewardGroup = SmithRewardCalculator.Instance.LookupRewards( SmithRewardCalculator.Instance.ComputePoints( this ) );
if (entries.Length > 0)
{
int hue = 0x44E;
int amountMax = Utility.RandomList(10, 15, 20);
if ( rewardGroup != null )
{
if ( full )
{
for ( int i = 0; i < rewardGroup.Items.Length; ++i )
{
Item item = rewardGroup.Items[i].Construct();
BulkMaterialType material;
if ( item != null )
list.Add( item );
}
}
else
{
RewardItem rewardItem = rewardGroup.AcquireItem();
if (useMaterials)
material = GetRandomMaterial(BulkMaterialType.DullCopper, m_BlacksmithMaterialChances);
else
material = BulkMaterialType.None;
if ( rewardItem != null )
{
Item item = rewardItem.Construct();
bool reqExceptional = Utility.RandomBool() || material == BulkMaterialType.None;
if ( item != null )
list.Add( item );
}
}
}
SmallBulkEntry entry = entries[Utility.Random(entries.Length)];
return list;
}
Hue = hue;
AmountMax = amountMax;
Type = entry.Type;
Number = entry.Number;
Graphic = entry.Graphic;
RequireExceptional = reqExceptional;
Material = material;
}
}
public static SmallSmithBOD CreateRandomFor( Mobile m )
{
SmallBulkEntry[] entries;
bool useMaterials;
public SmallSmithBOD(int amountCur, int amountMax, Type type, int number, int graphic, bool reqExceptional,
BulkMaterialType mat)
{
Hue = 0x44E;
AmountMax = amountMax;
AmountCur = amountCur;
Type = type;
Number = number;
Graphic = graphic;
RequireExceptional = reqExceptional;
Material = mat;
}
if ( useMaterials = Utility.RandomBool() )
entries = SmallBulkEntry.BlacksmithArmor;
else
entries = SmallBulkEntry.BlacksmithWeapons;
public SmallSmithBOD(Serial serial) : base(serial)
{
}
if ( entries.Length > 0 )
{
double theirSkill = m.Skills[SkillName.Blacksmith].Base;
int amountMax;
public override int ComputeFame()
{
return SmithRewardCalculator.Instance.ComputeFame(this);
}
if ( theirSkill >= 70.1 )
amountMax = Utility.RandomList( 10, 15, 20, 20 );
else if ( theirSkill >= 50.1 )
amountMax = Utility.RandomList( 10, 15, 15, 20 );
else
amountMax = Utility.RandomList( 10, 10, 15, 20 );
public override int ComputeGold()
{
return SmithRewardCalculator.Instance.ComputeGold(this);
}
BulkMaterialType material = BulkMaterialType.None;
public override List<Item> ComputeRewards(bool full)
{
List<Item> list = new List<Item>();
if ( useMaterials && theirSkill >= 70.1 )
{
for ( int i = 0; i < 20; ++i )
{
BulkMaterialType check = GetRandomMaterial( BulkMaterialType.DullCopper, m_BlacksmithMaterialChances );
double skillReq = 0.0;
RewardGroup rewardGroup =
SmithRewardCalculator.Instance.LookupRewards(SmithRewardCalculator.Instance.ComputePoints(this));
switch ( check )
{
case BulkMaterialType.DullCopper: skillReq = 65.0; break;
case BulkMaterialType.ShadowIron: skillReq = 70.0; break;
case BulkMaterialType.Copper: skillReq = 75.0; break;
case BulkMaterialType.Bronze: skillReq = 80.0; break;
case BulkMaterialType.Gold: skillReq = 85.0; break;
case BulkMaterialType.Agapite: skillReq = 90.0; break;
case BulkMaterialType.Verite: skillReq = 95.0; break;
case BulkMaterialType.Valorite: skillReq = 100.0; break;
case BulkMaterialType.Spined: skillReq = 65.0; break;
case BulkMaterialType.Horned: skillReq = 80.0; break;
case BulkMaterialType.Barbed: skillReq = 99.0; break;
}
if (rewardGroup != null)
{
if (full)
{
for (int i = 0; i < rewardGroup.Items.Length; ++i)
{
Item item = rewardGroup.Items[i].Construct();
if ( theirSkill >= skillReq )
{
material = check;
break;
}
}
}
if (item != null)
list.Add(item);
}
}
else
{
RewardItem rewardItem = rewardGroup.AcquireItem();
double excChance = 0.0;
Item item = rewardItem?.Construct();
if ( theirSkill >= 70.1 )
excChance = (theirSkill + 80.0) / 200.0;
if (item != null)
list.Add(item);
}
}
bool reqExceptional = ( excChance > Utility.RandomDouble() );
return list;
}
CraftSystem system = DefBlacksmithy.CraftSystem;
public static SmallSmithBOD CreateRandomFor(Mobile m)
{
SmallBulkEntry[] entries;
bool useMaterials;
List<SmallBulkEntry> validEntries = new List<SmallBulkEntry>();
if (useMaterials = Utility.RandomBool())
entries = SmallBulkEntry.BlacksmithArmor;
else
entries = SmallBulkEntry.BlacksmithWeapons;
for ( int i = 0; i < entries.Length; ++i )
{
CraftItem item = system.CraftItems.SearchFor( entries[i].Type );
if (entries.Length > 0)
{
double theirSkill = m.Skills[SkillName.Blacksmith].Base;
int amountMax;
if ( item != null )
{
bool allRequiredSkills = true;
double chance = item.GetSuccessChance( m, null, system, false, ref allRequiredSkills );
if (theirSkill >= 70.1)
amountMax = Utility.RandomList(10, 15, 20, 20);
else if (theirSkill >= 50.1)
amountMax = Utility.RandomList(10, 15, 15, 20);
else
amountMax = Utility.RandomList(10, 10, 15, 20);
if ( allRequiredSkills && chance >= 0.0 )
{
if ( reqExceptional )
chance = item.GetExceptionalChance( system, chance, m );
BulkMaterialType material = BulkMaterialType.None;
if ( chance > 0.0 )
validEntries.Add( entries[i] );
}
}
}
if (useMaterials && theirSkill >= 70.1)
for (int i = 0; i < 20; ++i)
{
BulkMaterialType check = GetRandomMaterial(BulkMaterialType.DullCopper, m_BlacksmithMaterialChances);
double skillReq = 0.0;
if ( validEntries.Count > 0 )
{
SmallBulkEntry entry = validEntries[Utility.Random( validEntries.Count )];
return new SmallSmithBOD( entry, material, amountMax, reqExceptional );
}
}
switch (check)
{
case BulkMaterialType.DullCopper:
skillReq = 65.0;
break;
case BulkMaterialType.ShadowIron:
skillReq = 70.0;
break;
case BulkMaterialType.Copper:
skillReq = 75.0;
break;
case BulkMaterialType.Bronze:
skillReq = 80.0;
break;
case BulkMaterialType.Gold:
skillReq = 85.0;
break;
case BulkMaterialType.Agapite:
skillReq = 90.0;
break;
case BulkMaterialType.Verite:
skillReq = 95.0;
break;
case BulkMaterialType.Valorite:
skillReq = 100.0;
break;
case BulkMaterialType.Spined:
skillReq = 65.0;
break;
case BulkMaterialType.Horned:
skillReq = 80.0;
break;
case BulkMaterialType.Barbed:
skillReq = 99.0;
break;
}
return null;
}
if (theirSkill >= skillReq)
{
material = check;
break;
}
}
private SmallSmithBOD( SmallBulkEntry entry, BulkMaterialType material, int amountMax, bool reqExceptional )
{
this.Hue = 0x44E;
this.AmountMax = amountMax;
this.Type = entry.Type;
this.Number = entry.Number;
this.Graphic = entry.Graphic;
this.RequireExceptional = reqExceptional;
this.Material = material;
}
double excChance = 0.0;
[Constructible]
public SmallSmithBOD()
{
SmallBulkEntry[] entries;
bool useMaterials;
if (theirSkill >= 70.1)
excChance = (theirSkill + 80.0) / 200.0;
if ( useMaterials = Utility.RandomBool() )
entries = SmallBulkEntry.BlacksmithArmor;
else
entries = SmallBulkEntry.BlacksmithWeapons;
bool reqExceptional = excChance > Utility.RandomDouble();
if ( entries.Length > 0 )
{
int hue = 0x44E;
int amountMax = Utility.RandomList( 10, 15, 20 );
CraftSystem system = DefBlacksmithy.CraftSystem;
BulkMaterialType material;
List<SmallBulkEntry> validEntries = new List<SmallBulkEntry>();
if ( useMaterials )
material = GetRandomMaterial( BulkMaterialType.DullCopper, m_BlacksmithMaterialChances );
else
material = BulkMaterialType.None;
for (int i = 0; i < entries.Length; ++i)
{
CraftItem item = system.CraftItems.SearchFor(entries[i].Type);
bool reqExceptional = Utility.RandomBool() || (material == BulkMaterialType.None);
if (item != null)
{
bool allRequiredSkills = true;
double chance = item.GetSuccessChance(m, null, system, false, ref allRequiredSkills);
SmallBulkEntry entry = entries[Utility.Random( entries.Length )];
if (allRequiredSkills && chance >= 0.0)
{
if (reqExceptional)
chance = item.GetExceptionalChance(system, chance, m);
this.Hue = hue;
this.AmountMax = amountMax;
this.Type = entry.Type;
this.Number = entry.Number;
this.Graphic = entry.Graphic;
this.RequireExceptional = reqExceptional;
this.Material = material;
}
}
if (chance > 0.0)
validEntries.Add(entries[i]);
}
}
}
public SmallSmithBOD( int amountCur, int amountMax, Type type, int number, int graphic, bool reqExceptional, BulkMaterialType mat )
{
this.Hue = 0x44E;
this.AmountMax = amountMax;
this.AmountCur = amountCur;
this.Type = type;
this.Number = number;
this.Graphic = graphic;
this.RequireExceptional = reqExceptional;
this.Material = mat;
}
if (validEntries.Count > 0)
{
SmallBulkEntry entry = validEntries[Utility.Random(validEntries.Count)];
return new SmallSmithBOD(entry, material, amountMax, reqExceptional);
}
}
public SmallSmithBOD( Serial serial ) : base( serial )
{
}
return null;
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write( (int) 0 ); // version
}
writer.Write(0); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
int version = reader.ReadInt();
}
}
}

View file

@ -1,236 +1,250 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Engines.Craft;
using Server.Items;
namespace Server.Engines.BulkOrders
{
public class SmallTailorBOD : SmallBOD
{
public static double[] m_TailoringMaterialChances = new double[]
{
0.857421875, // None
0.125000000, // Spined
0.015625000, // Horned
0.001953125 // Barbed
};
public class SmallTailorBOD : SmallBOD
{
public static double[] m_TailoringMaterialChances =
{
0.857421875, // None
0.125000000, // Spined
0.015625000, // Horned
0.001953125 // Barbed
};
public override int ComputeFame()
{
return TailorRewardCalculator.Instance.ComputeFame( this );
}
private SmallTailorBOD(SmallBulkEntry entry, BulkMaterialType material, int amountMax, bool reqExceptional)
{
Hue = 0x483;
AmountMax = amountMax;
Type = entry.Type;
Number = entry.Number;
Graphic = entry.Graphic;
RequireExceptional = reqExceptional;
Material = material;
}
public override int ComputeGold()
{
return TailorRewardCalculator.Instance.ComputeGold( this );
}
[Constructible]
public SmallTailorBOD()
{
SmallBulkEntry[] entries;
bool useMaterials;
public override List<Item> ComputeRewards( bool full )
{
List<Item> list = new List<Item>();
if (useMaterials = Utility.RandomBool())
entries = SmallBulkEntry.TailorLeather;
else
entries = SmallBulkEntry.TailorCloth;
RewardGroup rewardGroup = TailorRewardCalculator.Instance.LookupRewards( TailorRewardCalculator.Instance.ComputePoints( this ) );
if (entries.Length > 0)
{
int hue = 0x483;
int amountMax = Utility.RandomList(10, 15, 20);
if ( rewardGroup != null )
{
if ( full )
{
for ( int i = 0; i < rewardGroup.Items.Length; ++i )
{
Item item = rewardGroup.Items[i].Construct();
BulkMaterialType material;
if ( item != null )
list.Add( item );
}
}
else
{
RewardItem rewardItem = rewardGroup.AcquireItem();
if (useMaterials)
material = GetRandomMaterial(BulkMaterialType.Spined, m_TailoringMaterialChances);
else
material = BulkMaterialType.None;
if ( rewardItem != null )
{
Item item = rewardItem.Construct();
bool reqExceptional = Utility.RandomBool() || material == BulkMaterialType.None;
if ( item != null )
list.Add( item );
}
}
}
SmallBulkEntry entry = entries[Utility.Random(entries.Length)];
return list;
}
Hue = hue;
AmountMax = amountMax;
Type = entry.Type;
Number = entry.Number;
Graphic = entry.Graphic;
RequireExceptional = reqExceptional;
Material = material;
}
}
public static SmallTailorBOD CreateRandomFor( Mobile m )
{
SmallBulkEntry[] entries;
bool useMaterials = Utility.RandomBool();
public SmallTailorBOD(int amountCur, int amountMax, Type type, int number, int graphic, bool reqExceptional,
BulkMaterialType mat)
{
Hue = 0x483;
AmountMax = amountMax;
AmountCur = amountCur;
Type = type;
Number = number;
Graphic = graphic;
RequireExceptional = reqExceptional;
Material = mat;
}
double theirSkill = m.Skills[SkillName.Tailoring].Base;
if ( useMaterials && theirSkill >= 6.2 ) // Ugly, but the easiest leather BOD is Leather Cap which requires at least 6.2 skill.
entries = SmallBulkEntry.TailorLeather;
else
entries = SmallBulkEntry.TailorCloth;
public SmallTailorBOD(Serial serial) : base(serial)
{
}
if ( entries.Length > 0 )
{
int amountMax;
public override int ComputeFame()
{
return TailorRewardCalculator.Instance.ComputeFame(this);
}
if ( theirSkill >= 70.1 )
amountMax = Utility.RandomList( 10, 15, 20, 20 );
else if ( theirSkill >= 50.1 )
amountMax = Utility.RandomList( 10, 15, 15, 20 );
else
amountMax = Utility.RandomList( 10, 10, 15, 20 );
public override int ComputeGold()
{
return TailorRewardCalculator.Instance.ComputeGold(this);
}
BulkMaterialType material = BulkMaterialType.None;
public override List<Item> ComputeRewards(bool full)
{
List<Item> list = new List<Item>();
if ( useMaterials && theirSkill >= 70.1 )
{
for ( int i = 0; i < 20; ++i )
{
BulkMaterialType check = GetRandomMaterial( BulkMaterialType.Spined, m_TailoringMaterialChances );
double skillReq = 0.0;
RewardGroup rewardGroup =
TailorRewardCalculator.Instance.LookupRewards(TailorRewardCalculator.Instance.ComputePoints(this));
switch ( check )
{
case BulkMaterialType.DullCopper: skillReq = 65.0; break;
case BulkMaterialType.Bronze: skillReq = 80.0; break;
case BulkMaterialType.Gold: skillReq = 85.0; break;
case BulkMaterialType.Agapite: skillReq = 90.0; break;
case BulkMaterialType.Verite: skillReq = 95.0; break;
case BulkMaterialType.Valorite: skillReq = 100.0; break;
case BulkMaterialType.Spined: skillReq = 65.0; break;
case BulkMaterialType.Horned: skillReq = 80.0; break;
case BulkMaterialType.Barbed: skillReq = 99.0; break;
}
if (rewardGroup != null)
{
if (full)
{
for (int i = 0; i < rewardGroup.Items.Length; ++i)
{
Item item = rewardGroup.Items[i].Construct();
if ( theirSkill >= skillReq )
{
material = check;
break;
}
}
}
if (item != null)
list.Add(item);
}
}
else
{
RewardItem rewardItem = rewardGroup.AcquireItem();
double excChance = 0.0;
Item item = rewardItem?.Construct();
if ( theirSkill >= 70.1 )
excChance = (theirSkill + 80.0) / 200.0;
if (item != null)
list.Add(item);
}
}
bool reqExceptional = ( excChance > Utility.RandomDouble() );
return list;
}
public static SmallTailorBOD CreateRandomFor(Mobile m)
{
SmallBulkEntry[] entries;
bool useMaterials = Utility.RandomBool();
double theirSkill = m.Skills[SkillName.Tailoring].Base;
if (useMaterials && theirSkill >= 6.2
) // Ugly, but the easiest leather BOD is Leather Cap which requires at least 6.2 skill.
entries = SmallBulkEntry.TailorLeather;
else
entries = SmallBulkEntry.TailorCloth;
if (entries.Length > 0)
{
int amountMax;
if (theirSkill >= 70.1)
amountMax = Utility.RandomList(10, 15, 20, 20);
else if (theirSkill >= 50.1)
amountMax = Utility.RandomList(10, 15, 15, 20);
else
amountMax = Utility.RandomList(10, 10, 15, 20);
BulkMaterialType material = BulkMaterialType.None;
if (useMaterials && theirSkill >= 70.1)
for (int i = 0; i < 20; ++i)
{
BulkMaterialType check = GetRandomMaterial(BulkMaterialType.Spined, m_TailoringMaterialChances);
double skillReq = 0.0;
switch (check)
{
case BulkMaterialType.DullCopper:
skillReq = 65.0;
break;
case BulkMaterialType.Bronze:
skillReq = 80.0;
break;
case BulkMaterialType.Gold:
skillReq = 85.0;
break;
case BulkMaterialType.Agapite:
skillReq = 90.0;
break;
case BulkMaterialType.Verite:
skillReq = 95.0;
break;
case BulkMaterialType.Valorite:
skillReq = 100.0;
break;
case BulkMaterialType.Spined:
skillReq = 65.0;
break;
case BulkMaterialType.Horned:
skillReq = 80.0;
break;
case BulkMaterialType.Barbed:
skillReq = 99.0;
break;
}
if (theirSkill >= skillReq)
{
material = check;
break;
}
}
double excChance = 0.0;
if (theirSkill >= 70.1)
excChance = (theirSkill + 80.0) / 200.0;
bool reqExceptional = excChance > Utility.RandomDouble();
CraftSystem system = DefTailoring.CraftSystem;
CraftSystem system = DefTailoring.CraftSystem;
List<SmallBulkEntry> validEntries = new List<SmallBulkEntry>();
List<SmallBulkEntry> validEntries = new List<SmallBulkEntry>();
for ( int i = 0; i < entries.Length; ++i )
{
CraftItem item = system.CraftItems.SearchFor( entries[i].Type );
for (int i = 0; i < entries.Length; ++i)
{
CraftItem item = system.CraftItems.SearchFor(entries[i].Type);
if ( item != null )
{
bool allRequiredSkills = true;
double chance = item.GetSuccessChance( m, null, system, false, ref allRequiredSkills );
if (item != null)
{
bool allRequiredSkills = true;
double chance = item.GetSuccessChance(m, null, system, false, ref allRequiredSkills);
if ( allRequiredSkills && chance >= 0.0 )
{
if ( reqExceptional )
chance = item.GetExceptionalChance( system, chance, m );
if (allRequiredSkills && chance >= 0.0)
{
if (reqExceptional)
chance = item.GetExceptionalChance(system, chance, m);
if ( chance > 0.0 )
validEntries.Add( entries[i] );
}
}
}
if (chance > 0.0)
validEntries.Add(entries[i]);
}
}
}
if ( validEntries.Count > 0 )
{
SmallBulkEntry entry = validEntries[Utility.Random( validEntries.Count )];
return new SmallTailorBOD( entry, material, amountMax, reqExceptional );
}
}
if (validEntries.Count > 0)
{
SmallBulkEntry entry = validEntries[Utility.Random(validEntries.Count)];
return new SmallTailorBOD(entry, material, amountMax, reqExceptional);
}
}
return null;
}
return null;
}
private SmallTailorBOD( SmallBulkEntry entry, BulkMaterialType material, int amountMax, bool reqExceptional )
{
this.Hue = 0x483;
this.AmountMax = amountMax;
this.Type = entry.Type;
this.Number = entry.Number;
this.Graphic = entry.Graphic;
this.RequireExceptional = reqExceptional;
this.Material = material;
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
[Constructible]
public SmallTailorBOD()
{
SmallBulkEntry[] entries;
bool useMaterials;
writer.Write(0); // version
}
if ( useMaterials = Utility.RandomBool() )
entries = SmallBulkEntry.TailorLeather;
else
entries = SmallBulkEntry.TailorCloth;
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
if ( entries.Length > 0 )
{
int hue = 0x483;
int amountMax = Utility.RandomList( 10, 15, 20 );
BulkMaterialType material;
if ( useMaterials )
material = GetRandomMaterial( BulkMaterialType.Spined, m_TailoringMaterialChances );
else
material = BulkMaterialType.None;
bool reqExceptional = Utility.RandomBool() || (material == BulkMaterialType.None);
SmallBulkEntry entry = entries[Utility.Random( entries.Length )];
this.Hue = hue;
this.AmountMax = amountMax;
this.Type = entry.Type;
this.Number = entry.Number;
this.Graphic = entry.Graphic;
this.RequireExceptional = reqExceptional;
this.Material = material;
}
}
public SmallTailorBOD( int amountCur, int amountMax, Type type, int number, int graphic, bool reqExceptional, BulkMaterialType mat )
{
this.Hue = 0x483;
this.AmountMax = amountMax;
this.AmountCur = amountCur;
this.Type = type;
this.Number = number;
this.Graphic = graphic;
this.RequireExceptional = reqExceptional;
this.Material = mat;
}
public SmallTailorBOD( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
int version = reader.ReadInt();
}
}
}

View file

@ -1,58 +1,54 @@
using System;
using System.Collections;
using Server;
using Server.Items;
namespace Server.Engines.CannedEvil
{
public class ChampionAltar : PentagramAddon
{
private ChampionSpawn m_Spawn;
public class ChampionAltar : PentagramAddon
{
private ChampionSpawn m_Spawn;
public ChampionAltar( ChampionSpawn spawn )
{
m_Spawn = spawn;
}
public ChampionAltar(ChampionSpawn spawn)
{
m_Spawn = spawn;
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
public ChampionAltar(Serial serial) : base(serial)
{
}
if ( m_Spawn != null )
m_Spawn.Delete();
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
public ChampionAltar( Serial serial ) : base( serial )
{
}
m_Spawn?.Delete();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write( (int) 0 ); // version
writer.Write(0); // version
writer.Write( m_Spawn );
}
writer.Write(m_Spawn);
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
m_Spawn = reader.ReadItem() as ChampionSpawn;
switch (version)
{
case 0:
{
m_Spawn = reader.ReadItem() as ChampionSpawn;
if ( m_Spawn == null )
Delete();
if (m_Spawn == null)
Delete();
break;
}
}
}
}
break;
}
}
}
}
}

View file

@ -1,89 +1,85 @@
using System;
using System.Collections;
using Server;
using Server.Items;
namespace Server.Engines.CannedEvil
{
public class ChampionPlatform : BaseAddon
{
private ChampionSpawn m_Spawn;
public class ChampionPlatform : BaseAddon
{
private ChampionSpawn m_Spawn;
public ChampionPlatform( ChampionSpawn spawn )
{
m_Spawn = spawn;
public ChampionPlatform(ChampionSpawn spawn)
{
m_Spawn = spawn;
for ( int x = -2; x <= 2; ++x )
for ( int y = -2; y <= 2; ++y )
AddComponent( 0x750, x, y, -5 );
for (int x = -2; x <= 2; ++x)
for (int y = -2; y <= 2; ++y)
AddComponent(0x750, x, y, -5);
for ( int x = -1; x <= 1; ++x )
for ( int y = -1; y <= 1; ++y )
AddComponent( 0x750, x, y, 0 );
for (int x = -1; x <= 1; ++x)
for (int y = -1; y <= 1; ++y)
AddComponent(0x750, x, y, 0);
for ( int i = -1; i <= 1; ++i )
{
AddComponent( 0x751, i, 2, 0 );
AddComponent( 0x752, 2, i, 0 );
for (int i = -1; i <= 1; ++i)
{
AddComponent(0x751, i, 2, 0);
AddComponent(0x752, 2, i, 0);
AddComponent( 0x753, i, -2, 0 );
AddComponent( 0x754, -2, i, 0 );
}
AddComponent(0x753, i, -2, 0);
AddComponent(0x754, -2, i, 0);
}
AddComponent( 0x759, -2, -2, 0 );
AddComponent( 0x75A, 2, 2, 0 );
AddComponent( 0x75B, -2, 2, 0 );
AddComponent( 0x75C, 2, -2, 0 );
}
AddComponent(0x759, -2, -2, 0);
AddComponent(0x75A, 2, 2, 0);
AddComponent(0x75B, -2, 2, 0);
AddComponent(0x75C, 2, -2, 0);
}
public void AddComponent( int id, int x, int y, int z )
{
AddonComponent ac = new AddonComponent( id );
public ChampionPlatform(Serial serial) : base(serial)
{
}
ac.Hue = 0x497;
public void AddComponent(int id, int x, int y, int z)
{
AddonComponent ac = new AddonComponent(id);
AddComponent( ac, x, y, z );
}
ac.Hue = 0x497;
public override void OnAfterDelete()
{
base.OnAfterDelete();
AddComponent(ac, x, y, z);
}
if ( m_Spawn != null )
m_Spawn.Delete();
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
public ChampionPlatform( Serial serial ) : base( serial )
{
}
m_Spawn?.Delete();
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write( (int) 0 ); // version
writer.Write(0); // version
writer.Write( m_Spawn );
}
writer.Write(m_Spawn);
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
m_Spawn = reader.ReadItem() as ChampionSpawn;
switch (version)
{
case 0:
{
m_Spawn = reader.ReadItem() as ChampionSpawn;
if ( m_Spawn == null )
Delete();
if (m_Spawn == null)
Delete();
break;
}
}
}
}
break;
}
}
}
}
}

View file

@ -1,73 +1,89 @@
using System;
using Server;
using Server.Engines.CannedEvil;
namespace Server.Items
{
public class ChampionSkull : Item
{
private ChampionSkullType m_Type;
public class ChampionSkull : Item
{
private ChampionSkullType m_Type;
[CommandProperty( AccessLevel.GameMaster )]
public ChampionSkullType Type{ get{ return m_Type; } set{ m_Type = value; InvalidateProperties(); } }
[Constructible]
public ChampionSkull(ChampionSkullType type) : base(0x1AE1)
{
m_Type = type;
LootType = LootType.Cursed;
public override int LabelNumber => 1049479 + (int)m_Type;
// TODO: All hue values
switch (type)
{
case ChampionSkullType.Power:
Hue = 0x159;
break;
case ChampionSkullType.Venom:
Hue = 0x172;
break;
case ChampionSkullType.Greed:
Hue = 0x1EE;
break;
case ChampionSkullType.Death:
Hue = 0x025;
break;
case ChampionSkullType.Pain:
Hue = 0x035;
break;
}
}
[Constructible]
public ChampionSkull( ChampionSkullType type ) : base( 0x1AE1 )
{
m_Type = type;
LootType = LootType.Cursed;
public ChampionSkull(Serial serial) : base(serial)
{
}
// TODO: All hue values
switch ( type )
{
case ChampionSkullType.Power: Hue = 0x159; break;
case ChampionSkullType.Venom: Hue = 0x172; break;
case ChampionSkullType.Greed: Hue = 0x1EE; break;
case ChampionSkullType.Death: Hue = 0x025; break;
case ChampionSkullType.Pain: Hue = 0x035; break;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public ChampionSkullType Type
{
get => m_Type;
set
{
m_Type = value;
InvalidateProperties();
}
}
public ChampionSkull( Serial serial ) : base( serial )
{
}
public override int LabelNumber => 1049479 + (int)m_Type;
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write( (int) 1 ); // version
writer.Write(1); // version
writer.Write( (int) m_Type );
}
writer.Write((int)m_Type);
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
int version = reader.ReadInt();
switch ( version )
{
case 1:
case 0:
{
m_Type = (ChampionSkullType)reader.ReadInt();
switch (version)
{
case 1:
case 0:
{
m_Type = (ChampionSkullType)reader.ReadInt();
break;
}
}
break;
}
}
if( version == 0 )
{
if ( LootType != LootType.Cursed )
LootType = LootType.Cursed;
if (version == 0)
{
if (LootType != LootType.Cursed)
LootType = LootType.Cursed;
if ( Insured )
Insured = false;
}
}
}
}
if (Insured)
Insured = false;
}
}
}
}

View file

@ -1,173 +1,184 @@
using System;
using System.Collections;
using Server;
using Server.Items;
using Server.Targeting;
using Server.Mobiles;
using Server.Targeting;
namespace Server.Engines.CannedEvil
{
public class ChampionSkullBrazier : AddonComponent
{
private ChampionSkullPlatform m_Platform;
private ChampionSkullType m_Type;
private Item m_Skull;
public class ChampionSkullBrazier : AddonComponent
{
private Item m_Skull;
private ChampionSkullType m_Type;
[CommandProperty( AccessLevel.GameMaster )]
public ChampionSkullPlatform Platform{ get{ return m_Platform; } }
public ChampionSkullBrazier(ChampionSkullPlatform platform, ChampionSkullType type) : base(0x19BB)
{
Hue = 0x455;
Light = LightType.Circle300;
[CommandProperty( AccessLevel.GameMaster )]
public ChampionSkullType Type{ get{ return m_Type; } set{ m_Type = value; InvalidateProperties(); } }
Platform = platform;
m_Type = type;
}
[CommandProperty( AccessLevel.GameMaster )]
public Item Skull{ get{ return m_Skull; } set{ m_Skull = value; if ( m_Platform != null ) m_Platform.Validate(); } }
public ChampionSkullBrazier(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1049489 + (int)m_Type;
[CommandProperty(AccessLevel.GameMaster)]
public ChampionSkullPlatform Platform{ get; private set; }
public ChampionSkullBrazier( ChampionSkullPlatform platform, ChampionSkullType type ) : base( 0x19BB )
{
Hue = 0x455;
Light = LightType.Circle300;
[CommandProperty(AccessLevel.GameMaster)]
public ChampionSkullType Type
{
get => m_Type;
set
{
m_Type = value;
InvalidateProperties();
}
}
m_Platform = platform;
m_Type = type;
}
[CommandProperty(AccessLevel.GameMaster)]
public Item Skull
{
get => m_Skull;
set
{
m_Skull = value;
Platform?.Validate();
}
}
public ChampionSkullBrazier( Serial serial ) : base( serial )
{
}
public override int LabelNumber => 1049489 + (int)m_Type;
public override void OnDoubleClick( Mobile from )
{
if ( m_Platform != null )
m_Platform.Validate();
public override void OnDoubleClick(Mobile from)
{
Platform?.Validate();
BeginSacrifice( from );
}
BeginSacrifice(from);
}
public void BeginSacrifice( Mobile from )
{
if ( Deleted )
return;
public void BeginSacrifice(Mobile from)
{
if (Deleted)
return;
if ( m_Skull != null && m_Skull.Deleted )
Skull = null;
if (m_Skull != null && m_Skull.Deleted)
Skull = null;
if ( from.Map != this.Map || !from.InRange( GetWorldLocation(), 3 ) )
{
from.SendLocalizedMessage( 500446 ); // That is too far away.
}
else if ( !Harrower.CanSpawn )
{
from.SendMessage( "The harrower has already been spawned." );
}
else if ( m_Skull == null )
{
from.SendLocalizedMessage( 1049485 ); // What would you like to sacrifice?
from.Target = new SacrificeTarget( this );
}
else
{
SendLocalizedMessageTo( from, 1049487, "" ); // I already have my champions awakening skull!
}
}
if (from.Map != Map || !from.InRange(GetWorldLocation(), 3))
{
from.SendLocalizedMessage(500446); // That is too far away.
}
else if (!Harrower.CanSpawn)
{
from.SendMessage("The harrower has already been spawned.");
}
else if (m_Skull == null)
{
from.SendLocalizedMessage(1049485); // What would you like to sacrifice?
from.Target = new SacrificeTarget(this);
}
else
{
SendLocalizedMessageTo(from, 1049487, ""); // I already have my champions awakening skull!
}
}
public void EndSacrifice( Mobile from, ChampionSkull skull )
{
if ( Deleted )
return;
public void EndSacrifice(Mobile from, ChampionSkull skull)
{
if (Deleted)
return;
if ( m_Skull != null && m_Skull.Deleted )
Skull = null;
if (m_Skull != null && m_Skull.Deleted)
Skull = null;
if ( from.Map != this.Map || !from.InRange( GetWorldLocation(), 3 ) )
{
from.SendLocalizedMessage( 500446 ); // That is too far away.
}
else if ( !Harrower.CanSpawn )
{
from.SendMessage( "The harrower has already been spawned." );
}
else if ( skull == null )
{
SendLocalizedMessageTo( from, 1049488, "" ); // That is not my champions awakening skull!
}
else if ( m_Skull != null )
{
SendLocalizedMessageTo( from, 1049487, "" ); // I already have my champions awakening skull!
}
else if ( !skull.IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 1049486 ); // You can only sacrifice items that are in your backpack!
}
else
{
if ( skull.Type == this.Type )
{
skull.Movable = false;
skull.MoveToWorld( GetWorldTop(), this.Map );
if (from.Map != Map || !from.InRange(GetWorldLocation(), 3))
{
from.SendLocalizedMessage(500446); // That is too far away.
}
else if (!Harrower.CanSpawn)
{
from.SendMessage("The harrower has already been spawned.");
}
else if (skull == null)
{
SendLocalizedMessageTo(from, 1049488, ""); // That is not my champions awakening skull!
}
else if (m_Skull != null)
{
SendLocalizedMessageTo(from, 1049487, ""); // I already have my champions awakening skull!
}
else if (!skull.IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1049486); // You can only sacrifice items that are in your backpack!
}
else
{
if (skull.Type == Type)
{
skull.Movable = false;
skull.MoveToWorld(GetWorldTop(), Map);
this.Skull = skull;
}
else
{
SendLocalizedMessageTo( from, 1049488, "" ); // That is not my champions awakening skull!
}
}
}
Skull = skull;
}
else
{
SendLocalizedMessageTo(from, 1049488, ""); // That is not my champions awakening skull!
}
}
}
private class SacrificeTarget : Target
{
private ChampionSkullBrazier m_Brazier;
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
public SacrificeTarget( ChampionSkullBrazier brazier ) : base( 12, false, TargetFlags.None )
{
m_Brazier = brazier;
}
writer.Write(0); // version
protected override void OnTarget( Mobile from, object targeted )
{
m_Brazier.EndSacrifice( from, targeted as ChampionSkull );
}
}
writer.Write((int)m_Type);
writer.Write(Platform);
writer.Write(m_Skull);
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
writer.Write( (int) 0 ); // version
int version = reader.ReadInt();
writer.Write( (int) m_Type );
writer.Write( m_Platform );
writer.Write( m_Skull );
}
switch (version)
{
case 0:
{
m_Type = (ChampionSkullType)reader.ReadInt();
Platform = reader.ReadItem() as ChampionSkullPlatform;
m_Skull = reader.ReadItem();
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
if (Platform == null)
Delete();
int version = reader.ReadInt();
break;
}
}
switch ( version )
{
case 0:
{
m_Type = (ChampionSkullType)reader.ReadInt();
m_Platform = reader.ReadItem() as ChampionSkullPlatform;
m_Skull = reader.ReadItem();
if (Hue == 0x497)
Hue = 0x455;
if ( m_Platform == null )
Delete();
if (Light != LightType.Circle300)
Light = LightType.Circle300;
}
break;
}
}
private class SacrificeTarget : Target
{
private ChampionSkullBrazier m_Brazier;
if ( Hue == 0x497 )
Hue = 0x455;
public SacrificeTarget(ChampionSkullBrazier brazier) : base(12, false, TargetFlags.None)
{
m_Brazier = brazier;
}
if ( Light != LightType.Circle300 )
Light = LightType.Circle300;
}
}
}
protected override void OnTarget(Mobile from, object targeted)
{
m_Brazier.EndSacrifice(from, targeted as ChampionSkull);
}
}
}
}

View file

@ -1,131 +1,128 @@
using System;
using System.Collections;
using Server;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.CannedEvil
{
public class ChampionSkullPlatform : BaseAddon
{
private ChampionSkullBrazier m_Power, m_Enlightenment, m_Venom, m_Pain, m_Greed, m_Death;
public class ChampionSkullPlatform : BaseAddon
{
private ChampionSkullBrazier m_Power, m_Enlightenment, m_Venom, m_Pain, m_Greed, m_Death;
[Constructible]
public ChampionSkullPlatform()
{
AddComponent( new AddonComponent( 0x71A ), -1, -1, -1 );
AddComponent( new AddonComponent( 0x709 ), 0, -1, -1 );
AddComponent( new AddonComponent( 0x709 ), 1, -1, -1 );
AddComponent( new AddonComponent( 0x709 ), -1, 0, -1 );
AddComponent( new AddonComponent( 0x709 ), 0, 0, -1 );
AddComponent( new AddonComponent( 0x709 ), 1, 0, -1 );
AddComponent( new AddonComponent( 0x709 ), -1, 1, -1 );
AddComponent( new AddonComponent( 0x709 ), 0, 1, -1 );
AddComponent( new AddonComponent( 0x71B ), 1, 1, -1 );
[Constructible]
public ChampionSkullPlatform()
{
AddComponent(new AddonComponent(0x71A), -1, -1, -1);
AddComponent(new AddonComponent(0x709), 0, -1, -1);
AddComponent(new AddonComponent(0x709), 1, -1, -1);
AddComponent(new AddonComponent(0x709), -1, 0, -1);
AddComponent(new AddonComponent(0x709), 0, 0, -1);
AddComponent(new AddonComponent(0x709), 1, 0, -1);
AddComponent(new AddonComponent(0x709), -1, 1, -1);
AddComponent(new AddonComponent(0x709), 0, 1, -1);
AddComponent(new AddonComponent(0x71B), 1, 1, -1);
AddComponent( new AddonComponent( 0x50F ), 0, -1, 4 );
AddComponent( m_Power = new ChampionSkullBrazier( this, ChampionSkullType.Power ), 0, -1, 5 );
AddComponent(new AddonComponent(0x50F), 0, -1, 4);
AddComponent(m_Power = new ChampionSkullBrazier(this, ChampionSkullType.Power), 0, -1, 5);
AddComponent( new AddonComponent( 0x50F ), 1, -1, 4 );
AddComponent( m_Enlightenment = new ChampionSkullBrazier( this, ChampionSkullType.Enlightenment ), 1, -1, 5 );
AddComponent(new AddonComponent(0x50F), 1, -1, 4);
AddComponent(m_Enlightenment = new ChampionSkullBrazier(this, ChampionSkullType.Enlightenment), 1, -1, 5);
AddComponent( new AddonComponent( 0x50F ), -1, 0, 4 );
AddComponent( m_Venom = new ChampionSkullBrazier( this, ChampionSkullType.Venom ), -1, 0, 5 );
AddComponent(new AddonComponent(0x50F), -1, 0, 4);
AddComponent(m_Venom = new ChampionSkullBrazier(this, ChampionSkullType.Venom), -1, 0, 5);
AddComponent( new AddonComponent( 0x50F ), 1, 0, 4 );
AddComponent( m_Pain = new ChampionSkullBrazier( this, ChampionSkullType.Pain ), 1, 0, 5 );
AddComponent(new AddonComponent(0x50F), 1, 0, 4);
AddComponent(m_Pain = new ChampionSkullBrazier(this, ChampionSkullType.Pain), 1, 0, 5);
AddComponent( new AddonComponent( 0x50F ), -1, 1, 4 );
AddComponent( m_Greed = new ChampionSkullBrazier( this, ChampionSkullType.Greed ), -1, 1, 5 );
AddComponent(new AddonComponent(0x50F), -1, 1, 4);
AddComponent(m_Greed = new ChampionSkullBrazier(this, ChampionSkullType.Greed), -1, 1, 5);
AddComponent( new AddonComponent( 0x50F ), 0, 1, 4 );
AddComponent( m_Death = new ChampionSkullBrazier( this, ChampionSkullType.Death ), 0, 1, 5 );
AddComponent(new AddonComponent(0x50F), 0, 1, 4);
AddComponent(m_Death = new ChampionSkullBrazier(this, ChampionSkullType.Death), 0, 1, 5);
AddonComponent comp = new LocalizedAddonComponent( 0x20D2, 1049495 );
comp.Hue = 0x482;
AddComponent( comp, 0, 0, 5 );
AddonComponent comp = new LocalizedAddonComponent(0x20D2, 1049495);
comp.Hue = 0x482;
AddComponent(comp, 0, 0, 5);
comp = new LocalizedAddonComponent( 0x0BCF, 1049496 );
comp.Hue = 0x482;
AddComponent( comp, 0, 2, -7 );
comp = new LocalizedAddonComponent(0x0BCF, 1049496);
comp.Hue = 0x482;
AddComponent(comp, 0, 2, -7);
comp = new LocalizedAddonComponent( 0x0BD0, 1049497 );
comp.Hue = 0x482;
AddComponent( comp, 2, 0, -7 );
}
comp = new LocalizedAddonComponent(0x0BD0, 1049497);
comp.Hue = 0x482;
AddComponent(comp, 2, 0, -7);
}
public void Validate()
{
if ( Validate( m_Power ) && Validate( m_Enlightenment ) && Validate( m_Venom ) && Validate( m_Pain ) && Validate( m_Greed ) && Validate( m_Death ) )
{
Mobile harrower = Harrower.Spawn( new Point3D( X, Y, Z + 6 ), this.Map );
public ChampionSkullPlatform(Serial serial) : base(serial)
{
}
if ( harrower == null )
return;
public void Validate()
{
if (Validate(m_Power) && Validate(m_Enlightenment) && Validate(m_Venom) && Validate(m_Pain) &&
Validate(m_Greed) && Validate(m_Death))
{
Mobile harrower = Harrower.Spawn(new Point3D(X, Y, Z + 6), Map);
Clear( m_Power );
Clear( m_Enlightenment );
Clear( m_Venom );
Clear( m_Pain );
Clear( m_Greed );
Clear( m_Death );
}
}
if (harrower == null)
return;
public void Clear( ChampionSkullBrazier brazier )
{
if ( brazier != null )
{
Effects.SendBoltEffect( brazier );
Clear(m_Power);
Clear(m_Enlightenment);
Clear(m_Venom);
Clear(m_Pain);
Clear(m_Greed);
Clear(m_Death);
}
}
if ( brazier.Skull != null )
brazier.Skull.Delete();
}
}
public void Clear(ChampionSkullBrazier brazier)
{
if (brazier != null)
{
Effects.SendBoltEffect(brazier);
public bool Validate( ChampionSkullBrazier brazier )
{
return ( brazier != null && brazier.Skull != null && !brazier.Skull.Deleted );
}
brazier.Skull?.Delete();
}
}
public ChampionSkullPlatform( Serial serial ) : base( serial )
{
}
public bool Validate(ChampionSkullBrazier brazier)
{
return brazier?.Skull != null && !brazier.Skull.Deleted;
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write( (int) 0 ); // version
writer.Write(0); // version
writer.Write( m_Power );
writer.Write( m_Enlightenment );
writer.Write( m_Venom );
writer.Write( m_Pain );
writer.Write( m_Greed );
writer.Write( m_Death );
}
writer.Write(m_Power);
writer.Write(m_Enlightenment);
writer.Write(m_Venom);
writer.Write(m_Pain);
writer.Write(m_Greed);
writer.Write(m_Death);
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
m_Power = reader.ReadItem() as ChampionSkullBrazier;
m_Enlightenment = reader.ReadItem() as ChampionSkullBrazier;
m_Venom = reader.ReadItem() as ChampionSkullBrazier;
m_Pain = reader.ReadItem() as ChampionSkullBrazier;
m_Greed = reader.ReadItem() as ChampionSkullBrazier;
m_Death = reader.ReadItem() as ChampionSkullBrazier;
switch (version)
{
case 0:
{
m_Power = reader.ReadItem() as ChampionSkullBrazier;
m_Enlightenment = reader.ReadItem() as ChampionSkullBrazier;
m_Venom = reader.ReadItem() as ChampionSkullBrazier;
m_Pain = reader.ReadItem() as ChampionSkullBrazier;
m_Greed = reader.ReadItem() as ChampionSkullBrazier;
m_Death = reader.ReadItem() as ChampionSkullBrazier;
break;
}
}
}
}
break;
}
}
}
}
}

View file

@ -1,15 +1,12 @@
using System;
using Server;
namespace Server.Engines.CannedEvil
{
public enum ChampionSkullType
{
Power,
Enlightenment,
Venom,
Pain,
Greed,
Death
}
public enum ChampionSkullType
{
Power,
Enlightenment,
Venom,
Pain,
Greed,
Death
}
}

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more