remoteadmin system changes
This commit is contained in:
parent
28f3bd15b2
commit
ff10a7cfb8
4 changed files with 265 additions and 51 deletions
|
|
@ -9,6 +9,8 @@ namespace Server.RemoteAdmin
|
|||
{
|
||||
public class AdminNetwork
|
||||
{
|
||||
private const string ProtocolVersion = "2";
|
||||
|
||||
private static ArrayList m_Auth = new ArrayList();
|
||||
private static bool m_NewLine = true;
|
||||
private static StringBuilder m_ConsoleData = new StringBuilder();
|
||||
|
|
@ -39,11 +41,9 @@ namespace Server.RemoteAdmin
|
|||
}
|
||||
|
||||
m_ConsoleData.Append( outStr );
|
||||
if ( m_ConsoleData.Length >= 4096 )
|
||||
m_ConsoleData.Remove( 0, 2048 );
|
||||
RoughTrimConsoleData();
|
||||
|
||||
for (int i=0;i<m_Auth.Count;i++)
|
||||
((NetState)m_Auth[i]).Send( new ConsoleData( str ) );
|
||||
SendToAll( outStr );
|
||||
}
|
||||
|
||||
public static void OnConsoleChar( char ch )
|
||||
|
|
@ -54,22 +54,17 @@ namespace Server.RemoteAdmin
|
|||
outStr = String.Format( "[{0}]: {1}", DateTime.Now.ToString( DateFormat ), ch );
|
||||
|
||||
m_ConsoleData.Append( outStr );
|
||||
|
||||
for (int i=0;i<m_Auth.Count;i++)
|
||||
((NetState)m_Auth[i]).Send( new ConsoleData( outStr ) );
|
||||
SendToAll( outStr );
|
||||
|
||||
m_NewLine = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ConsoleData.Append( ch );
|
||||
|
||||
for (int i=0;i<m_Auth.Count;i++)
|
||||
((NetState)m_Auth[i]).Send( new ConsoleData( ch ) );
|
||||
SendToAll( ch );
|
||||
}
|
||||
|
||||
if ( m_ConsoleData.Length >= 4096 )
|
||||
m_ConsoleData.Remove( 0, 2048 );
|
||||
RoughTrimConsoleData();
|
||||
}
|
||||
|
||||
public static void OnConsoleLine( string line )
|
||||
|
|
@ -81,15 +76,43 @@ namespace Server.RemoteAdmin
|
|||
outStr = String.Format( "{0}{1}", line, Console.Out.NewLine );
|
||||
|
||||
m_ConsoleData.Append( outStr );
|
||||
if ( m_ConsoleData.Length >= 4096 )
|
||||
m_ConsoleData.Remove( 0, 2048 );
|
||||
RoughTrimConsoleData();
|
||||
|
||||
for (int i=0;i<m_Auth.Count;i++)
|
||||
((NetState)m_Auth[i]).Send( new ConsoleData( outStr ) );
|
||||
SendToAll( outStr );
|
||||
|
||||
m_NewLine = true;
|
||||
}
|
||||
|
||||
static void SendToAll( string outStr )
|
||||
{
|
||||
SendToAll( new ConsoleData( outStr ) );
|
||||
}
|
||||
|
||||
static void SendToAll( char ch )
|
||||
{
|
||||
SendToAll( new ConsoleData( ch ) );
|
||||
}
|
||||
|
||||
static void SendToAll( ConsoleData packet )
|
||||
{
|
||||
packet.Acquire();
|
||||
for ( int i = 0; i < m_Auth.Count; i++ )
|
||||
((NetState)m_Auth[i]).Send( packet );
|
||||
packet.Release();
|
||||
}
|
||||
|
||||
static void RoughTrimConsoleData()
|
||||
{
|
||||
if ( m_ConsoleData.Length >= 4096 )
|
||||
m_ConsoleData.Remove( 0, 2048 );
|
||||
}
|
||||
|
||||
static void TightTrimConsoleData()
|
||||
{
|
||||
if ( m_ConsoleData.Length > 1024 )
|
||||
m_ConsoleData.Remove( 0, m_ConsoleData.Length - 1024 );
|
||||
}
|
||||
|
||||
public static void OnReceive( NetState state, PacketReader pvSrc )
|
||||
{
|
||||
byte cmd = pvSrc.ReadByte();
|
||||
|
|
@ -97,9 +120,14 @@ namespace Server.RemoteAdmin
|
|||
{
|
||||
Authenticate( state, pvSrc );
|
||||
}
|
||||
else if ( cmd == 0xFE )
|
||||
{
|
||||
state.Send( new CompactServerInfo() );
|
||||
state.Dispose();
|
||||
}
|
||||
else if ( cmd == 0xFF )
|
||||
{
|
||||
string statStr = String.Format( ", Name={0}, Age={1}, Clients={2}, Items={3}, Chars={4}, Mem={5}K", Server.Misc.ServerList.ServerName, (int)(DateTime.Now-Server.Items.Clock.ServerStart).TotalHours, NetState.Instances.Count, World.Items.Count, World.Mobiles.Count, (int)(System.GC.GetTotalMemory(false)/1024) );
|
||||
string statStr = String.Format( ", Name={0}, Age={1}, Clients={2}, Items={3}, Chars={4}, Mem={5}K, Ver={6}", Server.Misc.ServerList.ServerName, (int)(DateTime.Now - Server.Items.Clock.ServerStart).TotalHours, NetState.Instances.Count, World.Items.Count, World.Mobiles.Count, (int)(System.GC.GetTotalMemory( false ) / 1024), ProtocolVersion );
|
||||
state.Send( new UOGInfo( statStr ) );
|
||||
state.Dispose();
|
||||
}
|
||||
|
|
@ -147,7 +175,7 @@ namespace Server.RemoteAdmin
|
|||
else if ( !a.CheckPassword( pw ) )
|
||||
{
|
||||
state.Send( new Login( LoginResponse.BadPass ) );
|
||||
Console.WriteLine( "ADMIN: Invalid password '{0}' for user '{1}' from {2}", pw, user, state );
|
||||
Console.WriteLine( "ADMIN: Invalid password for user '{0}' from {1}", user, state );
|
||||
DelayedDisconnect( state );
|
||||
}
|
||||
else if ( a.AccessLevel < AccessLevel.Administrator || a.Banned )
|
||||
|
|
@ -164,6 +192,7 @@ namespace Server.RemoteAdmin
|
|||
a.LastLogin = DateTime.Now;
|
||||
|
||||
state.Send( new Login( LoginResponse.OK ) );
|
||||
TightTrimConsoleData();
|
||||
state.Send( Compress( new ConsoleData( m_ConsoleData.ToString() ) ) );
|
||||
m_Auth.Add( state );
|
||||
}
|
||||
|
|
@ -194,7 +223,7 @@ namespace Server.RemoteAdmin
|
|||
|
||||
if ( length > 100 && length < 60000 )
|
||||
{
|
||||
byte[] dest = new byte[(int)(length*1.001)+1];
|
||||
byte[] dest = new byte[(int)(length * 1.001) + 10];
|
||||
int destSize = dest.Length;
|
||||
|
||||
ZLibError error = Compression.Pack( dest, ref destSize, source, length, ZLibQuality.Default );
|
||||
|
|
|
|||
|
|
@ -70,6 +70,8 @@ namespace Server.RemoteAdmin
|
|||
|
||||
foreach ( Account a in Accounts.GetAccounts() )
|
||||
{
|
||||
if ( !CanAccessAccount( state.Account, a ) ) continue;
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case AcctSearchType.Username:
|
||||
|
|
@ -106,20 +108,36 @@ namespace Server.RemoteAdmin
|
|||
}
|
||||
}
|
||||
|
||||
static bool CanAccessAccount( IAccount beholder, IAccount beheld )
|
||||
{
|
||||
return beholder.AccessLevel == AccessLevel.Owner || beheld.AccessLevel < beholder.AccessLevel; // Cannot see accounts of equal or greater access level unless Owner
|
||||
}
|
||||
|
||||
private static void RemoveAccount( NetState state, PacketReader pvSrc )
|
||||
{
|
||||
if ( state.Account.AccessLevel < AccessLevel.Administrator )
|
||||
{
|
||||
state.Send( new MessageBoxMessage( "You do not have permission to delete accounts.", "Account Access Exception" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
IAccount a = Accounts.GetAccount( pvSrc.ReadString() );
|
||||
|
||||
if ( a == null )
|
||||
{
|
||||
state.Send( new MessageBoxMessage( "The account could not be found (and thus was not deleted).", "Account Not Found" ) );
|
||||
}
|
||||
else if ( !CanAccessAccount( state.Account, a ) )
|
||||
{
|
||||
state.Send( new MessageBoxMessage( "You cannot delete an account with an access level greater than or equal to your own.", "Account Access Exception" ) );
|
||||
}
|
||||
else if ( a == state.Account )
|
||||
{
|
||||
state.Send( new MessageBoxMessage( "You may not delete your own account.", "Not Allowed" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoteAdminLogging.WriteLine( state, "Deleted Account {0}", a );
|
||||
a.Delete();
|
||||
state.Send( new MessageBoxMessage( "The requested account (and all it's characters) has been deleted.", "Account Deleted" ) );
|
||||
}
|
||||
|
|
@ -127,47 +145,96 @@ namespace Server.RemoteAdmin
|
|||
|
||||
private static void UpdateAccount( NetState state, PacketReader pvSrc )
|
||||
{
|
||||
if ( state.Account.AccessLevel < AccessLevel.Administrator )
|
||||
{
|
||||
state.Send( new MessageBoxMessage( "You do not have permission to edit accounts.", "Account Access Exception" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
string username = pvSrc.ReadString();
|
||||
string pass = pvSrc.ReadString();
|
||||
|
||||
Account a = Accounts.GetAccount( username ) as Account;
|
||||
|
||||
if ( a == null )
|
||||
a = new Account( username, pass );
|
||||
else if ( pass != "(hidden)" )
|
||||
a.SetPassword( pass );
|
||||
|
||||
if ( a != state.Account )
|
||||
if ( a != null && !CanAccessAccount( state.Account, a ) )
|
||||
{
|
||||
a.AccessLevel = (AccessLevel)pvSrc.ReadByte();
|
||||
a.Banned = pvSrc.ReadBoolean();
|
||||
state.Send( new MessageBoxMessage( "You cannot edit an account with an access level greater than or equal to your own.", "Account Access Exception" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
pvSrc.ReadInt16();//skip both
|
||||
state.Send( new MessageBoxMessage( "Warning: When editing your own account, account status and accesslevel cannot be changed.", "Editing Own Account" ) );
|
||||
}
|
||||
|
||||
ArrayList list = new ArrayList();
|
||||
ushort length = pvSrc.ReadUInt16();
|
||||
bool invalid = false;
|
||||
for (int i=0;i<length;i++)
|
||||
{
|
||||
string add = pvSrc.ReadString();
|
||||
if ( Utility.IsValidIP( add ) )
|
||||
list.Add( add );
|
||||
bool CreatedAccount = false;
|
||||
bool UpdatedPass = false;
|
||||
bool oldbanned = a == null ? false : a.Banned;
|
||||
AccessLevel oldAcessLevel = a == null ? 0 : a.AccessLevel;
|
||||
|
||||
if ( a == null )
|
||||
{
|
||||
a = new Account( username, pass );
|
||||
CreatedAccount = true;
|
||||
}
|
||||
else if ( pass != "(hidden)" )
|
||||
{
|
||||
a.SetPassword( pass );
|
||||
UpdatedPass = true;
|
||||
}
|
||||
|
||||
if ( a != state.Account )
|
||||
{
|
||||
AccessLevel newAccessLevel = (AccessLevel)pvSrc.ReadByte();
|
||||
if ( a.AccessLevel != newAccessLevel )
|
||||
{
|
||||
if ( newAccessLevel >= state.Account.AccessLevel )
|
||||
state.Send( new MessageBoxMessage( "Warning: You may not set an access level greater than or equal to your own.", "Account Access Level update denied." ) );
|
||||
else
|
||||
a.AccessLevel = newAccessLevel;
|
||||
}
|
||||
bool newBanned = pvSrc.ReadBoolean();
|
||||
if ( newBanned != a.Banned )
|
||||
{
|
||||
oldbanned = a.Banned;
|
||||
a.Banned = newBanned;
|
||||
a.Comments.Add( new AccountComment( state.Account.Username, newBanned ? "Banned via Remote Admin" : "Unbanned via Remote Admin" ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
invalid = true;
|
||||
}
|
||||
|
||||
if ( list.Count > 0 )
|
||||
a.IPRestrictions = (string[])list.ToArray( typeof( string ) );
|
||||
else
|
||||
a.IPRestrictions = new string[0];
|
||||
{
|
||||
pvSrc.ReadInt16();//skip both
|
||||
state.Send( new MessageBoxMessage( "Warning: When editing your own account, Account Status and Access Level cannot be changed.", "Editing Own Account" ) );
|
||||
}
|
||||
|
||||
if ( invalid )
|
||||
state.Send( new MessageBoxMessage( "Warning: one or more of the IP Restrictions you specified was not valid.", "Invalid IP Restriction" ) );
|
||||
state.Send( new MessageBoxMessage( "Account updated successfully.", "Account Updated" ) );
|
||||
ArrayList list = new ArrayList();
|
||||
ushort length = pvSrc.ReadUInt16();
|
||||
bool invalid = false;
|
||||
for (int i=0;i<length;i++)
|
||||
{
|
||||
string add = pvSrc.ReadString();
|
||||
if ( Utility.IsValidIP( add ) )
|
||||
list.Add( add );
|
||||
else
|
||||
invalid = true;
|
||||
}
|
||||
|
||||
if ( list.Count > 0 )
|
||||
a.IPRestrictions = (string[])list.ToArray( typeof( string ) );
|
||||
else
|
||||
a.IPRestrictions = new string[0];
|
||||
|
||||
if ( invalid )
|
||||
state.Send( new MessageBoxMessage( "Warning: one or more of the IP Restrictions you specified was not valid.", "Invalid IP Restriction" ) );
|
||||
|
||||
if ( CreatedAccount )
|
||||
RemoteAdminLogging.WriteLine( state, "Created account {0} with Access Level {1}", a.Username, a.AccessLevel );
|
||||
else
|
||||
{
|
||||
string changes = string.Empty;
|
||||
if ( UpdatedPass ) changes += " Password Changed.";
|
||||
if ( oldAcessLevel != a.AccessLevel ) changes = string.Format( "{0} Access level changed from {1} to {2}.", changes, oldAcessLevel, a.AccessLevel );
|
||||
if ( oldbanned != a.Banned ) changes += a.Banned ? " Banned." : " Unbanned.";
|
||||
RemoteAdminLogging.WriteLine( state, "Updated account {0}:{1}", a.Username, changes );
|
||||
}
|
||||
|
||||
state.Send( new MessageBoxMessage( "Account updated successfully.", "Account Updated" ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ namespace Server.RemoteAdmin
|
|||
m_Stream.Write( (int) Core.ScriptItems );
|
||||
|
||||
m_Stream.Write( (uint)(DateTime.Now - Clock.ServerStart).TotalSeconds );
|
||||
m_Stream.Write( (uint) GC.GetTotalMemory( false ) );
|
||||
m_Stream.Write( (uint) GC.GetTotalMemory( false ) ); // TODO: uint not sufficient for TotalMemory (long). Fix protocol.
|
||||
m_Stream.WriteAsciiNull( netVer );
|
||||
m_Stream.WriteAsciiNull( os );
|
||||
}
|
||||
|
|
@ -110,7 +110,7 @@ namespace Server.RemoteAdmin
|
|||
m_Stream.WriteAsciiNull( pwToSend );
|
||||
m_Stream.Write( (byte)a.AccessLevel );
|
||||
m_Stream.Write( a.Banned );
|
||||
unchecked { m_Stream.Write( (uint)a.LastLogin.Ticks ); }
|
||||
unchecked { m_Stream.Write( (uint)a.LastLogin.Ticks ); } // TODO: This doesn't work, uint.MaxValue is only 7 minutes of ticks. Fix protocol.
|
||||
|
||||
m_Stream.Write( (ushort)a.LoginIPs.Length );
|
||||
for (int i=0;i<a.LoginIPs.Length;i++)
|
||||
|
|
@ -123,6 +123,23 @@ namespace Server.RemoteAdmin
|
|||
}
|
||||
}
|
||||
|
||||
public sealed class CompactServerInfo : Packet
|
||||
{
|
||||
public CompactServerInfo() : base( 0x51 )
|
||||
{
|
||||
EnsureCapacity( 1 + 2 + (4 * 4) + 8 );
|
||||
|
||||
m_Stream.Write( (int)NetState.Instances.Count - 1 ); // Clients
|
||||
m_Stream.Write( (int)World.Items.Count ); // Items
|
||||
m_Stream.Write( (int)World.Mobiles.Count ); // Mobiles
|
||||
m_Stream.Write( (uint)(DateTime.Now - Clock.ServerStart).TotalSeconds ); // Age (seconds)
|
||||
|
||||
long memory = GC.GetTotalMemory( false );
|
||||
m_Stream.Write( (uint)(memory >> 32) ); // Memory high bytes
|
||||
m_Stream.Write( (uint)memory ); // Memory low bytes
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class UOGInfo : Packet
|
||||
{
|
||||
public UOGInfo( string str ) : base( 0x52, str.Length+6 ) // 'R'
|
||||
|
|
|
|||
101
Scripts/Engines/RemoteAdmin/RemoteAdminLogging.cs
Normal file
101
Scripts/Engines/RemoteAdmin/RemoteAdminLogging.cs
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using Server;
|
||||
using Server.Accounting;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.RemoteAdmin
|
||||
{
|
||||
public class RemoteAdminLogging
|
||||
{
|
||||
const string LogBaseDirectory = "Logs";
|
||||
const string LogSubDirectory = "RemoteAdmin";
|
||||
|
||||
private static StreamWriter m_Output;
|
||||
private static bool m_Enabled = true;
|
||||
|
||||
public static bool Enabled { get { return m_Enabled; } set { m_Enabled = value; } }
|
||||
|
||||
public static StreamWriter Output { get { return m_Output; } }
|
||||
|
||||
private static bool Initialized = false;
|
||||
public static void LazyInitialize()
|
||||
{
|
||||
if ( Initialized || !m_Enabled ) return;
|
||||
Initialized = true;
|
||||
|
||||
if ( !Directory.Exists( LogBaseDirectory ) )
|
||||
Directory.CreateDirectory( LogBaseDirectory );
|
||||
|
||||
string directory = Path.Combine( LogBaseDirectory, LogSubDirectory );
|
||||
|
||||
if ( !Directory.Exists( directory ) )
|
||||
Directory.CreateDirectory( directory );
|
||||
|
||||
try
|
||||
{
|
||||
m_Output = new StreamWriter( Path.Combine( directory, String.Format( LogSubDirectory + "{0}.log", DateTime.Now.ToString( "yyyyMMdd" ) ) ), true );
|
||||
|
||||
m_Output.AutoFlush = true;
|
||||
|
||||
m_Output.WriteLine( "##############################" );
|
||||
m_Output.WriteLine( "Log started on {0}", DateTime.Now );
|
||||
m_Output.WriteLine();
|
||||
}
|
||||
catch
|
||||
{
|
||||
Utility.PushColor( ConsoleColor.Red );
|
||||
Console.WriteLine( "RemoteAdminLogging: Failed to initialize LogWriter." );
|
||||
Utility.PopColor();
|
||||
m_Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static object Format( object o )
|
||||
{
|
||||
o = Commands.CommandLogging.Format( o );
|
||||
if ( o == null )
|
||||
return "(null)";
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
public static void WriteLine( NetState state, string format, params object[] args )
|
||||
{
|
||||
for ( int i = 0; i < args.Length; i++ )
|
||||
args[i] = Commands.CommandLogging.Format( args[i] );
|
||||
|
||||
WriteLine( state, String.Format( format, args ) );
|
||||
}
|
||||
|
||||
public static void WriteLine( NetState state, string text )
|
||||
{
|
||||
LazyInitialize();
|
||||
|
||||
if ( !m_Enabled ) return;
|
||||
|
||||
try
|
||||
{
|
||||
Account acct = state.Account as Account;
|
||||
string name = acct == null ? "(UNKNOWN)" : acct.Username;
|
||||
string accesslevel = acct == null ? "NoAccount" : acct.AccessLevel.ToString();
|
||||
string statestr = state == null ? "NULLSTATE" : state.ToString();
|
||||
|
||||
m_Output.WriteLine( "{0}: {1}: {2}: {3}", DateTime.Now, statestr, name, text );
|
||||
|
||||
string path = Core.BaseDirectory;
|
||||
|
||||
Commands.CommandLogging.AppendPath( ref path, LogBaseDirectory );
|
||||
Commands.CommandLogging.AppendPath( ref path, LogSubDirectory );
|
||||
Commands.CommandLogging.AppendPath( ref path, accesslevel );
|
||||
path = Path.Combine( path, String.Format( "{0}.log", name ) );
|
||||
|
||||
using ( StreamWriter sw = new StreamWriter( path, true ) )
|
||||
sw.WriteLine( "{0}: {1}: {2}", DateTime.Now, statestr, text );
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue