Files
ClassicAssist.Avalonia/ClassicAssist.Shared/UI/ViewModels/AboutControlViewModel.cs
T
Beyhan Oğur d5f52cc3d3 first commit
2026-09-03 04:45:36 +03:00

298 lines
9.2 KiB
C#

using System;
using System.Diagnostics;
using System.IO;
using System.Reactive.Linq;
using System.Reflection;
using System.Timers;
using System.Windows.Input;
using ClassicAssist.Shared.Resources;
using ClassicAssist.Shared;
using ClassicAssist.UO.Data;
using ClassicAssist.UO.Network;
using ClassicAssist.UO.Network.PacketFilter;
using ClassicAssist.UO.Network.Packets;
using ClassicAssist.UO.Objects;
using ReactiveUI;
namespace ClassicAssist.UI.ViewModels
{
public class AboutControlViewModel : BaseViewModel
{
private ICommand _checkForUpdatesCommand;
private bool _connected;
private DateTime _connectedTime;
private int _itemCount;
private int _lastTargetSerial;
private double _latency;
private ICommand _launchHomepageCommand;
private int _mobileCount;
private ICommand _openPayPalCommand;
private Timer _pingTimer;
private string _playerName;
private int _playerSerial;
private string _playerStatus;
private string _shardFeatures;
private string _shardName = "Unknown";
private ICommand _showItemsCommand;
private Timer _timer;
public AboutControlViewModel()
{
Assembly assembly = Assembly.GetExecutingAssembly();
Version version = assembly.GetName().Version;
Version = $"{version.Major}.{version.Minor}.{version.Build}.{version.Revision}";
BuildDate = $"{GetBuildDateTime( assembly ).ToLongDateString()}";
Engine.ConnectedEvent += OnConnectedEvent;
Engine.DisconnectedEvent += OnDisconnectedEvent;
Engine.PlayerInitializedEvent += PlayerInitializedEvent;
Engine.Items.CollectionChanged += ItemsOnCollectionChanged;
Engine.Mobiles.CollectionChanged += MobilesOnCollectionChanged;
IncomingPacketHandlers.MobileUpdatedEvent += OnMobileUpdatedEvent;
}
public string BuildDate { get; set; }
public ICommand CheckForUpdatesCommand =>
_checkForUpdatesCommand ?? ( _checkForUpdatesCommand = new RelayCommand( CheckForUpdates, o => true ) );
public bool Connected
{
get => _connected;
set => SetProperty( ref _connected, value );
}
public DateTime ConnectedTime
{
get => _connectedTime;
set => SetProperty( ref _connectedTime, value );
}
public int ItemCount
{
get => _itemCount;
set => SetProperty( ref _itemCount, value );
}
public int LastTargetSerial
{
get => _lastTargetSerial;
set => SetProperty( ref _lastTargetSerial, value );
}
public double Latency
{
get => _latency;
set => SetProperty( ref _latency, value );
}
public ICommand LaunchHomepageCommand =>
_launchHomepageCommand ?? ( _launchHomepageCommand = new RelayCommand( LaunchHomepage, o => true ) );
public int MobileCount
{
get => _mobileCount;
set => SetProperty( ref _mobileCount, value );
}
public ICommand OpenPayPalCommand =>
_openPayPalCommand ?? ( _openPayPalCommand = new RelayCommand( OpenPayPal, o => true ) );
public string PlayerName
{
get => _playerName;
set => SetProperty( ref _playerName, value );
}
public int PlayerSerial
{
get => _playerSerial;
set => SetProperty( ref _playerSerial, value );
}
public string PlayerStatus
{
get => _playerStatus;
set => SetProperty( ref _playerStatus, value );
}
public string Product { get; } = Strings.ProductName;
public string ShardFeatures
{
get => _shardFeatures;
set => SetProperty( ref _shardFeatures, value );
}
public string ShardName
{
get => _shardName;
set => SetProperty( ref _shardName, value );
}
public ICommand ShowItemsCommand =>
_showItemsCommand ?? ( _showItemsCommand = ReactiveCommand.Create( ShowItems,
this.WhenAnyValue( e => e.Connected ).ObserveOn( RxApp.MainThreadScheduler ) ) );
public string Version { get; set; }
private static void OpenPayPal( object obj )
{
Process.Start( "https://www.paypal.me/reeeetus" );
}
private void LastTargetChangedEvent( int serial )
{
LastTargetSerial = serial;
}
private void OnMobileUpdatedEvent( Mobile mobile )
{
if ( mobile.Serial == Engine.Player?.Serial )
{
PlayerInitializedEvent( Engine.Player );
}
}
private static void LaunchHomepage( object obj )
{
Process.Start( "https://github.com/Reetus/ClassicAssist" );
}
private void MobilesOnCollectionChanged( int totalcount, bool added, Mobile[] mobiles )
{
MobileCount = totalcount;
}
private void ItemsOnCollectionChanged( int totalcount, bool added, Item[] items )
{
ItemCount = Engine.Items.GetTotalItemCount();
}
private static void ShowItems()
{
Item[] e = ItemCollection.GetAllItems( Engine.Items.GetItems() );
Engine.UIInvoker?.Invoke( "EntityCollectionViewer", new[] { (object) new ItemCollection( 0 ) { e } } );
}
private void PlayerInitializedEvent( PlayerMobile player )
{
PlayerSerial = player.Serial;
PlayerName = player.Name;
PlayerStatus = player.Status.ToString();
ShardFeatures = Engine.Features.ToString();
player.LastTargetChangedEvent += LastTargetChangedEvent;
player.MobileStatusUpdated += OnMobileStatusUpdated;
ShardName = Engine.CurrentShard?.Name ?? "Unknown";
}
private void OnMobileStatusUpdated( MobileStatus oldstatus, MobileStatus newstatus )
{
PlayerStatus = newstatus.ToString();
}
private void OnDisconnectedEvent()
{
Connected = false;
_timer?.Stop();
}
private static void CheckForUpdates( object obj )
{
string updaterPath = Path.Combine( Engine.StartupPath ?? Environment.CurrentDirectory,
"ClassicAssist.Updater.exe" );
Version version = null;
if ( System.Version.TryParse(
FileVersionInfo.GetVersionInfo( Assembly.GetExecutingAssembly().Location ).ProductVersion,
out Version v ) )
{
version = v;
}
if ( !File.Exists( updaterPath ) )
{
return;
}
ProcessStartInfo psi = new ProcessStartInfo( updaterPath,
$"--pid {Process.GetCurrentProcess().Id} --path {Engine.StartupPath}" + ( version != null
? $" --version {version}"
: "" ) ) { UseShellExecute = false };
Process.Start( psi );
}
private void OnConnectedEvent()
{
Connected = true;
ConnectedTime = DateTime.Now;
_timer = new Timer( 1000 ) { AutoReset = true };
_timer.Elapsed += ( sender, args ) => { NotifyPropertyChanged( nameof( ConnectedTime ) ); };
_timer.Start();
_pingTimer = new Timer( 3000 ) { AutoReset = true };
_pingTimer.Elapsed += ( sender, args ) => PingServer();
_pingTimer.Start();
}
private void PingServer()
{
_pingTimer.Interval = 30000;
Random random = new Random();
byte value = (byte) random.Next( 1, byte.MaxValue );
Stopwatch sw = new Stopwatch();
sw.Start();
PacketWaitEntry we = Engine.PacketWaitEntries.Add(
new PacketFilterInfo( 0x73, new[] { new PacketFilterCondition( 1, new[] { value }, 1 ) } ),
PacketDirection.Incoming, true );
Engine.SendPacketToServer( new Ping( value ) );
bool result = we.Lock.WaitOne( 5000 );
sw.Stop();
if ( result )
{
Latency = sw.ElapsedMilliseconds;
}
}
internal static DateTime GetBuildDateTime( Assembly assembly )
{
try
{
var location = assembly?.Location;
if ( string.IsNullOrEmpty( location ) )
{
return DateTime.MinValue;
}
var productVersion = FileVersionInfo.GetVersionInfo( location ).ProductVersion;
if ( System.Version.TryParse( productVersion, out Version version ) && version != null )
{
DateTime buildDateTime =
new DateTime( 2020, 7, 3 ).Add( new TimeSpan( TimeSpan.TicksPerDay * version.Build ) );
return buildDateTime;
}
}
catch
{
// ignored
}
return DateTime.MinValue;
}
}
}