first commit

This commit is contained in:
Beyhan Oğur
2026-09-03 04:45:36 +03:00
commit d5f52cc3d3
1038 changed files with 169579 additions and 0 deletions
@@ -0,0 +1,597 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using ClassicAssist.Data;
using ClassicAssist.Data.Autoloot;
using ClassicAssist.Data.Regions;
using ClassicAssist.Misc;
using ClassicAssist.Shared.Resources;
using ClassicAssist.Shared.UI.ViewModels.Autoloot;
using ClassicAssist.UI.Misc;
using ClassicAssist.UI.ViewModels;
using ClassicAssist.UO.Data;
using ClassicAssist.UO.Network;
using ClassicAssist.UO.Network.PacketFilter;
using ClassicAssist.UO.Network.Packets;
using ClassicAssist.UO.Objects;
using Microsoft.Scripting.Utils;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using ReactiveUI;
using UOC = ClassicAssist.Shared.UO.Commands;
namespace ClassicAssist.Shared.UI.ViewModels.Agents
{
public class AutolootViewModel : BaseViewModel, ISettingProvider
{
private const int LOOT_TIMEOUT = 5000;
private readonly object _autolootLock = new object();
private readonly IObservable<bool> _entrySelected;
private readonly IObservable<bool> _itemSelected;
private readonly string _propertiesFile = Path.Combine( Engine.StartupPath ?? Environment.CurrentDirectory,
"Data", "Properties.json" );
private readonly string _propertiesFileCustom =
Path.Combine( Engine.StartupPath ?? Environment.CurrentDirectory, "Data", "Properties.Custom.json" );
private ICommand _clipboardCopyCommand;
private ICommand _clipboardPasteCommand;
private ObservableCollection<PropertyEntry> _constraints = new ObservableCollection<PropertyEntry>();
private int _containerSerial;
private ICommand _defineCustomPropertiesCommand;
private bool _disableInGuardzone;
private bool _enabled;
private ICommand _insertCommand;
private ICommand _insertConstraintCommand;
private ICommand _insertMatchAnyCommand;
private ObservableCollectionEx<AutolootEntry> _items = new ObservableCollectionEx<AutolootEntry>();
private ICommand _removeCommand;
private ICommand _removeConstraintCommand;
private ICommand _removeSingleConstraintCommand;
private RelayCommand _resetContainerCommand;
private AutolootEntry _selectedItem;
private ObservableCollection<AutolootConstraintEntry> _selectedProperties =
new ObservableCollection<AutolootConstraintEntry>();
private AutolootConstraintEntry _selectedProperty;
private ICommand _selectHueCommand;
private ICommand _setContainerCommand;
public AutolootViewModel()
{
if ( !File.Exists( _propertiesFile ) )
{
return;
}
LoadProperties();
LoadCustomProperties();
AutolootHelpers.SetAutolootContainer = serial => ContainerSerial = serial;
IncomingPacketHandlers.CorpseContainerDisplayEvent += OnCorpseEvent;
AutolootManager.GetInstance().GetEntries = () => _items.ToList();
_entrySelected = this.WhenAnyValue( e => e.SelectedItem, selector: e => e != null );
_itemSelected = this.WhenAnyValue( e => e.SelectedProperty, selector: e => e != null );
}
public ICommand ClipboardCopyCommand =>
_clipboardCopyCommand ?? ( _clipboardCopyCommand = new RelayCommand( ClipboardCopy, o => true ) );
public ICommand ClipboardPasteCommand =>
_clipboardPasteCommand ?? ( _clipboardPasteCommand = new RelayCommand( ClipboardPaste, o => true ) );
public ObservableCollection<PropertyEntry> Constraints
{
get => _constraints;
set => SetProperty( ref _constraints, value );
}
public int ContainerSerial
{
get => _containerSerial;
set => SetProperty( ref _containerSerial, value );
}
public ICommand DefineCustomPropertiesCommand =>
_defineCustomPropertiesCommand ??
( _defineCustomPropertiesCommand = new RelayCommand( DefineCustomProperties, o => true ) );
public bool DisableInGuardzone
{
get => _disableInGuardzone;
set => SetProperty( ref _disableInGuardzone, value );
}
public bool Enabled
{
get => _enabled;
set => SetProperty( ref _enabled, value );
}
public ICommand InsertCommand =>
_insertCommand ?? ( _insertCommand = ReactiveCommand.CreateFromTask( Insert ) );
public ICommand InsertConstraintCommand =>
_insertConstraintCommand ?? ( _insertConstraintCommand =
ReactiveCommand.Create<PropertyEntry>( InsertConstraint, _entrySelected ) );
public ICommand InsertMatchAnyCommand =>
_insertMatchAnyCommand ?? ( _insertMatchAnyCommand = new RelayCommand( InsertMatchAny, o => true ) );
public ObservableCollectionEx<AutolootEntry> Items
{
get => _items;
set => SetProperty( ref _items, value );
}
public ICommand RemoveCommand =>
_removeCommand ??
( _removeCommand = ReactiveCommand.CreateFromTask<AutolootEntry>( Remove, _entrySelected ) );
public ICommand RemoveConstraintCommand =>
_removeConstraintCommand ?? ( _removeConstraintCommand =
ReactiveCommand.Create<IEnumerable<AutolootConstraintEntry>>( RemoveConstraint, _itemSelected ) );
public ICommand RemoveSingleConstraintCommand =>
_removeSingleConstraintCommand ?? ( _removeSingleConstraintCommand =
ReactiveCommand.Create<AutolootConstraintEntry>( RemoveSingleConstraint, _itemSelected ) );
public ICommand ResetContainerCommand => _resetContainerCommand = new RelayCommand( ResetContainer, o => true );
public AutolootEntry SelectedItem
{
get => _selectedItem;
set => SetProperty( ref _selectedItem, value );
}
public ObservableCollection<AutolootConstraintEntry> SelectedProperties
{
get => _selectedProperties;
set => SetProperty( ref _selectedProperties, value );
}
public AutolootConstraintEntry SelectedProperty
{
get => _selectedProperty;
set => SetProperty( ref _selectedProperty, value );
}
public ICommand SelectHueCommand =>
_selectHueCommand ?? ( _selectHueCommand =
ReactiveCommand.CreateFromTask<AutolootEntry>( SelectHue, _entrySelected ) );
public ICommand SetContainerCommand =>
_setContainerCommand ?? ( _setContainerCommand = new RelayCommandAsync( SetContainer, o => true ) );
public void Serialize( JObject json )
{
if ( json == null )
{
return;
}
JObject autolootObj = new JObject
{
{ "Enabled", Enabled },
{ "DisableInGuardzone", DisableInGuardzone },
{ "Container", ContainerSerial }
};
JArray itemsArray = new JArray();
foreach ( AutolootEntry entry in Items )
{
JObject entryObj = new JObject
{
{ "Name", entry.Name },
{ "ID", entry.ID },
{ "Autoloot", entry.Autoloot },
{ "Rehue", entry.Rehue },
{ "RehueHue", entry.RehueHue },
{ "Enabled", entry.Enabled }
};
if ( entry.Constraints != null )
{
JArray constraintsArray = new JArray();
foreach ( AutolootConstraintEntry constraint in entry.Constraints )
{
JObject constraintObj = new JObject
{
{ "Name", constraint.Property.Name },
{ "Operator", constraint.Operator.ToString() },
{ "Value", constraint.Value }
};
constraintsArray.Add( constraintObj );
}
entryObj.Add( "Properties", constraintsArray );
}
itemsArray.Add( entryObj );
}
autolootObj.Add( "Items", itemsArray );
json.Add( "Autoloot", autolootObj );
}
public void Deserialize( JObject json, Options options )
{
Items.Clear();
if ( json?["Autoloot"] == null )
{
return;
}
JToken config = json["Autoloot"];
Enabled = config["Enabled"]?.ToObject<bool>() ?? true;
DisableInGuardzone = config["DisableInGuardzone"]?.ToObject<bool>() ?? false;
ContainerSerial = config["Container"]?.ToObject<int>() ?? 0;
if ( config["Items"] != null )
{
JToken items = config["Items"];
foreach ( JToken token in items )
{
AutolootEntry entry = new AutolootEntry
{
Name = token["Name"]?.ToObject<string>() ?? "Unknown",
ID = token["ID"]?.ToObject<int>() ?? 0,
Autoloot = token["Autoloot"]?.ToObject<bool>() ?? false,
Rehue = token["Rehue"]?.ToObject<bool>() ?? false,
RehueHue = token["RehueHue"]?.ToObject<int>() ?? 0,
Enabled = token["Enabled"]?.ToObject<bool>() ?? true
};
if ( token["Properties"] != null )
{
List<AutolootConstraintEntry> constraintsList = new List<AutolootConstraintEntry>();
// ReSharper disable once LoopCanBeConvertedToQuery
foreach ( JToken constraintToken in token["Properties"] )
{
string constraintName = constraintToken["Name"]?.ToObject<string>() ?? "Unknown";
PropertyEntry propertyEntry = Constraints.FirstOrDefault( c => c.Name == constraintName );
if ( propertyEntry == null )
{
continue;
}
AutolootConstraintEntry constraintObj = new AutolootConstraintEntry
{
Property = propertyEntry,
Operator = constraintToken["Operator"]?.ToObject<AutolootOperator>() ??
AutolootOperator.Equal,
Value = constraintToken["Value"]?.ToObject<int>() ?? 0
};
constraintsList.Add( constraintObj );
}
entry.Constraints.AddRange( constraintsList );
}
Items.Add( entry );
}
}
}
private void RemoveSingleConstraint( AutolootConstraintEntry obj )
{
SelectedItem?.Constraints.Remove( obj );
}
private void LoadCustomProperties()
{
if ( !File.Exists( _propertiesFileCustom ) )
{
return;
}
JsonSerializer serializer = new JsonSerializer();
using ( StreamReader sr = new StreamReader( _propertiesFileCustom ) )
{
using ( JsonTextReader reader = new JsonTextReader( sr ) )
{
PropertyEntry[] constraints = serializer.Deserialize<PropertyEntry[]>( reader );
foreach ( PropertyEntry constraint in constraints )
{
Constraints.AddSorted( constraint );
}
}
}
}
private void LoadProperties()
{
JsonSerializer serializer = new JsonSerializer();
using ( StreamReader sr = new StreamReader( _propertiesFile ) )
{
using ( JsonTextReader reader = new JsonTextReader( sr ) )
{
PropertyEntry[] constraints = serializer.Deserialize<PropertyEntry[]>( reader );
foreach ( PropertyEntry constraint in constraints )
{
Constraints.AddSorted( constraint );
}
}
}
}
private void ClipboardPaste( object obj )
{
string text = Engine.UIInvoker.GetClipboardText();
try
{
IEnumerable<AutolootConstraintEntry> entries =
JsonConvert.DeserializeObject<IEnumerable<AutolootConstraintEntry>>( text );
if ( entries == null )
{
return;
}
foreach ( AutolootConstraintEntry entry in entries )
{
if ( !SelectedItem.Constraints.Contains( entry ) )
{
SelectedItem?.Constraints.Add( entry );
}
}
}
catch ( Exception )
{
// ignored
}
}
private static void ClipboardCopy( object obj )
{
if ( !( obj is IList<AutolootConstraintEntry> entries ) )
{
return;
}
string text = JsonConvert.SerializeObject( entries );
Engine.UIInvoker.SetClipboardText( text );
}
public void OnCorpseEvent( int serial )
{
if ( !Enabled )
{
return;
}
lock ( _autolootLock )
{
Item item = Engine.Items.GetItem( serial );
if ( item == null || item.ID != 0x2006 )
{
return;
}
PacketWaitEntry we = Engine.PacketWaitEntries.Add(
new PacketFilterInfo( 0x3C, new[] { PacketFilterConditions.IntAtPositionCondition( serial, 19 ) } ),
PacketDirection.Incoming );
we.Lock.WaitOne( 2000 );
IEnumerable<Item> items = Engine.Items.GetItem( serial )?.Container?.GetItems();
if ( items == null )
{
return;
}
if ( Engine.Features.HasFlag( FeatureFlags.AOS ) )
{
Engine.SendPacketToServer( new BatchQueryProperties( items.Select( i => i.Serial ).ToArray() ) );
Thread.Sleep( 1000 );
}
List<Item> lootItems = new List<Item>();
// If change logic, also change in DebugAutolootViewModel
foreach ( AutolootEntry entry in Items )
{
if ( !entry.Enabled )
{
continue;
}
IEnumerable<Item> matchItems = AutolootHelpers.AutolootFilter( items, entry );
if ( matchItems == null )
{
continue;
}
foreach ( Item matchItem in matchItems )
{
if ( entry.Rehue )
{
Engine.SendPacketToClient( new ContainerContentUpdate( matchItem.Serial, matchItem.ID,
matchItem.Direction, matchItem.Count, matchItem.X, matchItem.Y, matchItem.Grid,
matchItem.Owner, entry.RehueHue ) );
}
if ( DisableInGuardzone &&
Engine.Player.GetRegion().Attributes.HasFlag( RegionAttributes.Guarded ) )
{
continue;
}
if ( entry.Autoloot )
{
lootItems.Add( matchItem );
}
}
}
foreach ( Item lootItem in lootItems.Distinct() )
{
int containerSerial = ContainerSerial;
if ( containerSerial == 0 || Engine.Items.GetItem( containerSerial ) == null )
{
containerSerial = Engine.Player.GetLayer( Layer.Backpack );
}
UOC.SystemMessage( string.Format( Strings.Autolooting___0__, lootItem.Name ), 61 );
Task t = ActionPacketQueue.EnqueueDragDrop( lootItem.Serial, lootItem.Count, containerSerial,
QueuePriority.Medium, true, true );
t.Wait( LOOT_TIMEOUT );
}
}
}
private void RemoveConstraint( object obj )
{
if ( !( obj is IEnumerable<AutolootConstraintEntry> constraints ) )
{
return;
}
foreach ( AutolootConstraintEntry constraintEntry in constraints.ToList() )
{
SelectedItem?.Constraints.Remove( constraintEntry );
}
}
private void InsertConstraint( object obj )
{
if ( !( obj is PropertyEntry propertyEntry ) )
{
return;
}
List<AutolootConstraintEntry> constraints =
new List<AutolootConstraintEntry>( SelectedItem.Constraints )
{
new AutolootConstraintEntry { Property = propertyEntry }
};
SelectedItem.Constraints = new ObservableCollection<AutolootConstraintEntry>( constraints );
}
private void DefineCustomProperties( object obj )
{
Engine.UIInvoker.InvokeDialog<CustomPropertiesViewModel>( "CustomPropertiesWindow" );
Constraints.Clear();
LoadProperties();
LoadCustomProperties();
}
private void ResetContainer( object obj )
{
ContainerSerial = 0;
}
private async Task SetContainer( object arg )
{
int serial = await UOC.GetTargeSerialAsync( Strings.Target_container___ );
if ( serial == 0 )
{
UOC.SystemMessage( Strings.Invalid_or_unknown_object_id );
return;
}
ContainerSerial = serial;
}
private void InsertMatchAny( object obj )
{
AutolootEntry entry = new AutolootEntry
{
Name = Strings.Any, ID = -1, Constraints = new ObservableCollection<AutolootConstraintEntry>()
};
Items.Add( entry );
}
private async Task Insert( CancellationToken cancellationToken )
{
int serial = await UOC.GetTargeSerialAsync( Strings.Target_object___ );
if ( serial == 0 )
{
UOC.SystemMessage( Strings.Invalid_or_unknown_object_id );
return;
}
Item item = Engine.Items.GetItem( serial );
if ( item == null )
{
UOC.SystemMessage( Strings.Cannot_find_item___ );
return;
}
AutolootEntry entry = new AutolootEntry
{
Name = TileData.GetStaticTile( item.ID ).Name,
ID = item.ID,
Constraints = new ObservableCollection<AutolootConstraintEntry>()
};
Items.Add( entry );
}
private async Task Remove( object arg )
{
if ( !( arg is AutolootEntry entry ) )
{
return;
}
Items.Remove( entry );
await Task.CompletedTask;
}
private static async Task SelectHue( object obj )
{
if ( !( obj is AutolootEntry entry ) )
{
return;
}
int hue = await Engine.UIInvoker.GetHueAsync();
entry.RehueHue = hue;
}
}
}
@@ -0,0 +1,174 @@
using System.Collections.ObjectModel;
using System.Reactive;
using System.Threading.Tasks;
using System.Windows.Input;
using ClassicAssist.Data;
using ClassicAssist.Data.Counters;
using ClassicAssist.Misc;
using ClassicAssist.Shared.Resources;
using ClassicAssist.Shared.UO;
using ClassicAssist.UI.ViewModels;
using ClassicAssist.UO.Data;
using ClassicAssist.UO.Objects;
using Newtonsoft.Json.Linq;
using ReactiveUI;
namespace ClassicAssist.Shared.UI.ViewModels.Agents
{
public class CountersTabViewModel : BaseViewModel, ISettingProvider
{
private ICommand _insertEntryCommand;
private ObservableCollection<CountersAgentEntry> _items = new ObservableCollection<CountersAgentEntry>();
private ICommand _recountCommand;
private ICommand _removeEntryCommand;
private CountersAgentEntry _selectedItem;
private bool _warn = true;
private int _warnAmount;
public CountersTabViewModel()
{
CountersManager manager = CountersManager.GetInstance();
manager.Items = Items;
manager.RecountAll = Recount;
}
public ICommand InsertEntryCommand =>
_insertEntryCommand ?? ( _insertEntryCommand = new RelayCommandAsync( InsertEntry, o => true ) );
public ObservableCollection<CountersAgentEntry> Items
{
get => _items;
set => SetProperty( ref _items, value );
}
public ICommand RecountCommand => _recountCommand ?? ( _recountCommand = ReactiveCommand.Create( Recount ) );
public ICommand RemoveEntryCommand =>
_removeEntryCommand ?? ( _removeEntryCommand = ReactiveCommand.Create<CountersAgentEntry>( RemoveEntry,
this.WhenAnyValue( e => e.SelectedItem, selector: e => e != null ) ) );
public CountersAgentEntry SelectedItem
{
get => _selectedItem;
set => SetProperty( ref _selectedItem, value );
}
public bool Warn
{
get => _warn;
set => SetProperty( ref _warn, value );
}
public int WarnAmount
{
get => _warnAmount;
set => SetProperty( ref _warnAmount, value );
}
public void Serialize( JObject json )
{
JObject options = new JObject { { "Warn", Warn }, { "WarnAmount", WarnAmount } };
JArray items = new JArray();
foreach ( CountersAgentEntry entry in Items )
{
JObject entryObj = new JObject
{
{ "Name", entry.Name }, { "Graphic", entry.Graphic }, { "Color", entry.Color }
};
items.Add( entryObj );
}
options.Add( "Items", items );
json?.Add( "Counters", options );
}
public void Deserialize( JObject json, Options options )
{
Items.Clear();
if ( json?["Counters"] == null )
{
return;
}
Warn = json["Counters"]["Warn"]?.ToObject<bool>() ?? false;
WarnAmount = json["Counters"]["WarnAmount"]?.ToObject<int>() ?? 0;
foreach ( JToken token in json["Counters"]["Items"] )
{
if ( token != null )
{
Items.Add( new CountersAgentEntry
{
Name = token["Name"].ToObject<string>() ?? "Unknown",
Graphic = token["Graphic"].ToObject<int>(),
Color = token["Color"].ToObject<int>()
} );
}
}
}
private void RemoveEntry( object obj )
{
if ( !( obj is CountersAgentEntry entry ) )
{
return;
}
Items.Remove( entry );
}
private void Recount()
{
foreach ( CountersAgentEntry item in Items )
{
int count = item.Count;
item.Recount();
if ( Warn && item.Count <= WarnAmount && count > WarnAmount )
{
Commands.SystemMessage(
string.Format( Strings.Counter___0___amount_is_now__1____, item.Name, item.Count ), 61 );
}
}
}
private async Task InsertEntry( object arg )
{
int serial = await Commands.GetTargeSerialAsync( Strings.Target_object___ );
if ( serial == 0 )
{
Commands.SystemMessage( Strings.Invalid_or_unknown_object_id );
return;
}
Item item = Engine.Items.GetItem( serial );
if ( item == null )
{
Commands.SystemMessage( Strings.Cannot_find_item___ );
return;
}
string name = TileData.GetStaticTile( item.ID ).Name;
if ( string.IsNullOrEmpty( name ) )
{
name = item.Name;
}
CountersAgentEntry entry = new CountersAgentEntry { Name = name, Graphic = item.ID, Color = item.Hue };
entry.Recount();
Items.Add( entry );
}
}
}
@@ -0,0 +1,394 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using ClassicAssist.Data;
using ClassicAssist.Data.Dress;
using ClassicAssist.Data.Hotkeys;
using ClassicAssist.Misc;
using ClassicAssist.Shared.Resources;
using ClassicAssist.Shared.UO;
using ClassicAssist.UI.ViewModels;
using ClassicAssist.UO.Data;
using ClassicAssist.UO.Objects;
using Newtonsoft.Json.Linq;
using ReactiveUI;
namespace ClassicAssist.Shared.UI.ViewModels.Agents
{
public class DressTabViewModel : HotkeyEntryViewModel<DressAgentEntry>, ISettingProvider
{
private readonly IObservable<bool> _entrySelected;
private readonly DressManager _manager;
private readonly Layer[] _validLayers =
{
Layer.Arms, Layer.Bracelet, Layer.Cloak, Layer.Earrings, Layer.Gloves, Layer.Helm, Layer.InnerLegs,
Layer.InnerTorso, Layer.MiddleTorso, Layer.Neck, Layer.OneHanded, Layer.OuterLegs, Layer.OuterTorso,
Layer.Pants, Layer.Ring, Layer.Shirt, Layer.Shoes, Layer.Talisman, Layer.TwoHanded, Layer.Waist
};
private ICommand _addDressItemCommand;
private ICommand _changeDressType;
private ICommand _clearDressItemsCommand;
private ICommand _dressAllItemsCommand;
private ICommand _importItemsCommand;
private bool _isDressingOrUndressing;
private readonly IObservable<bool> _itemSelected;
private bool _moveConflictingItems;
private ICommand _newDressEntryCommand;
private ICommand _removeDressEntryCommand;
private ICommand _removeDressItemCommand;
private DressAgentItem _selectedDressItem;
private DressAgentEntry _selectedItem;
private ICommand _setUndressContainerCommand;
private ICommand _undressAllItemsCommand;
private ICommand _undressItemsCommand;
private bool _useUo3DPackets;
public DressTabViewModel() : base( Strings.Dress )
{
_manager = DressManager.GetInstance();
_manager.Items = Items;
_entrySelected = this.WhenAnyValue( e => e.SelectedItem, selector: e => e != null );
_itemSelected = this.WhenAnyValue( e => e.SelectedDressItem, selector: e => e != null );
}
public ICommand AddDressItemCommand =>
_addDressItemCommand ?? ( _addDressItemCommand = new RelayCommandAsync( AddDressItem, o => true ) );
//TODO UI
public ICommand ChangeDressTypeCommand =>
_changeDressType ??
( _changeDressType = new RelayCommand( ChangeDressType, o => SelectedDressItem != null ) );
public ICommand ClearDressItemsCommand =>
_clearDressItemsCommand ?? ( _clearDressItemsCommand =
ReactiveCommand.Create<DressAgentEntry>( ClearDressItems, _entrySelected ) );
public ICommand DressAllItemsCommand =>
_dressAllItemsCommand ?? ( _dressAllItemsCommand =
ReactiveCommand.CreateFromTask<DressAgentEntry>( DressAllItems,
_entrySelected.Merge( this.WhenAnyValue( e => e.IsDressingOrUndressing, e => !e ) ) ) );
public ICommand ImportItemsCommand =>
_importItemsCommand ?? ( _importItemsCommand =
ReactiveCommand.Create<DressAgentEntry>( ImportItems, _entrySelected ) );
public bool IsDressingOrUndressing
{
get => _isDressingOrUndressing;
set => SetProperty( ref _isDressingOrUndressing, value );
}
public bool MoveConflictingItems
{
get => _moveConflictingItems;
set => SetProperty( ref _moveConflictingItems, value );
}
public ICommand NewDressEntryCommand =>
_newDressEntryCommand ?? ( _newDressEntryCommand = new RelayCommand( NewDressEntry, o => true ) );
public ICommand RemoveDressEntryCommand =>
_removeDressEntryCommand ?? ( _removeDressEntryCommand =
ReactiveCommand.Create<DressAgentEntry>( RemoveDressEntry, _entrySelected ) );
public ICommand RemoveDressItemCommand =>
_removeDressItemCommand ?? ( _removeDressItemCommand =
ReactiveCommand.Create<DressAgentItem>( RemoveDressItem, _itemSelected ) );
public DressAgentItem SelectedDressItem
{
get => _selectedDressItem;
set => SetProperty( ref _selectedDressItem, value );
}
public DressAgentEntry SelectedItem
{
get => _selectedItem;
set => SetProperty( ref _selectedItem, value );
}
public ICommand SetUndressContainerCommand =>
_setUndressContainerCommand ?? ( _setUndressContainerCommand =
ReactiveCommand.CreateFromTask<DressAgentEntry>( SetUndressContainer, _entrySelected ) );
public ICommand UndressAllItemsCommand =>
_undressAllItemsCommand ?? ( _undressAllItemsCommand = ReactiveCommand.CreateFromTask( UndressAllItems,
this.WhenAnyValue( e => e.IsDressingOrUndressing, e => !e ) ) );
public ICommand UndressItemsCommand =>
_undressItemsCommand ?? ( _undressItemsCommand =
ReactiveCommand.CreateFromTask<DressAgentEntry>( UndressItems,
this.WhenAnyValue( e => e.IsDressingOrUndressing, e => !e ) ) );
public bool UseUO3DPackets
{
get => _useUo3DPackets;
set
{
SetProperty( ref _useUo3DPackets, value );
if ( _manager != null )
{
_manager.UseUO3DPackets = value;
}
}
}
public void Serialize( JObject json )
{
JObject dress = new JObject
{
{
"Options",
new JObject { ["MoveConflictingItems"] = MoveConflictingItems, ["UseUO3DPackets"] = UseUO3DPackets }
}
};
JArray dressEntries = new JArray();
foreach ( DressAgentEntry dae in Items )
{
JObject djson = new JObject();
SetJsonValue( djson, "Name", dae.Name );
SetJsonValue( djson, "UndressContainer", dae.UndressContainer );
SetJsonValue( djson, "PassToUO", dae.PassToUO );
SetJsonValue( djson, "Keys", dae.Hotkey.ToJObject() );
JArray items = new JArray();
if ( dae.Items != null )
{
foreach ( DressAgentItem dressAgentItem in dae.Items )
{
JObject item = new JObject
{
{ "Layer", (int) dressAgentItem.Layer },
{ "Serial", dressAgentItem.Serial },
{ "ID", dressAgentItem.ID },
{ "Type", (int) dressAgentItem.Type }
};
items.Add( item );
}
}
djson.Add( "Items", items );
dressEntries.Add( djson );
}
dress.Add( "Entries", dressEntries );
json?.Add( "Dress", dress );
}
public void Deserialize( JObject json, Options options )
{
Items.Clear();
if ( json?["Dress"] == null )
{
return;
}
JToken dress = json["Dress"];
MoveConflictingItems = GetJsonValue( dress["Options"], "MoveConflictingItems", false );
UseUO3DPackets = _manager.UseUO3DPackets = GetJsonValue( dress["Options"], "UseUO3DPackets", false );
foreach ( JToken entry in dress["Entries"] )
{
DressAgentEntry dae = new DressAgentEntry
{
Name = GetJsonValue( entry, "Name", string.Empty ),
UndressContainer = GetJsonValue( entry, "UndressContainer", 0 ),
PassToUO = GetJsonValue( entry, "PassToUO", true ),
Hotkey = new ShortcutKeys( entry["Keys"] )
};
dae.Action = async hks => await DressAllItems( dae );
List<DressAgentItem> items = new List<DressAgentItem>();
if ( entry["Items"] != null )
{
items.AddRange( entry["Items"].Select( itemEntry => new DressAgentItem
{
Layer = GetJsonValue( itemEntry, "Layer", Layer.Invalid ),
Serial = GetJsonValue( itemEntry, "Serial", 0 ),
ID = GetJsonValue( itemEntry, "ID", -1 ),
Type = GetJsonValue( itemEntry, "Type", DressAgentItemType.Serial )
} ) );
}
dae.Items = new List<DressAgentItem>( items );
Items.Add( dae );
}
}
private async Task UndressItems( object arg )
{
if ( !( arg is DressAgentEntry dae ) )
{
return;
}
try
{
IsDressingOrUndressing = true;
await dae.Undress();
}
finally
{
IsDressingOrUndressing = false;
}
}
private static async Task SetUndressContainer( object obj )
{
if ( !( obj is DressAgentEntry entry ) )
{
return;
}
int serial = await Commands.GetTargeSerialAsync( Strings.Select_undress_container___ );
if ( serial <= 0 )
{
Commands.SystemMessage( Strings.Invalid_container___ );
return;
}
entry.UndressContainer = serial;
}
private static void ClearDressItems( object obj )
{
if ( !( obj is DressAgentEntry dae ) )
{
return;
}
dae.Items = new List<DressAgentItem>();
}
private void RemoveDressItem( object obj )
{
if ( !( obj is DressAgentItem removeItem ) )
{
return;
}
if ( !SelectedItem.Items.Contains( removeItem ) )
{
return;
}
List<DressAgentItem> list = SelectedItem.Items.ToList();
list.Remove( removeItem );
SelectedItem.Items = list;
}
private static async Task AddDressItem( object arg )
{
if ( !( arg is DressAgentEntry dae ) )
{
return;
}
int serial = await Commands.GetTargeSerialAsync( Strings.Target_clothing_item___ );
Item item = Engine.Items.GetItem( serial );
if ( item == null )
{
Commands.SystemMessage( Strings.Cannot_find_item___ );
return;
}
if ( item.Layer == Layer.Invalid )
{
Commands.SystemMessage( Strings.The_item_needs_to_be_equipped___ );
return;
}
dae.AddOrReplaceDressItem( item );
}
private async Task UndressAllItems( CancellationToken cancellationToken )
{
IsDressingOrUndressing = true;
await _manager.UndressAll( cancellationToken );
IsDressingOrUndressing = false;
}
private void NewDressEntry( object obj )
{
int count = Items.Count;
DressAgentEntry dae =
new DressAgentEntry { Name = $"Dress-{count + 1}", Items = new List<DressAgentItem>() };
dae.Action = async hks => await DressAllItems( dae );
Items.Add( dae );
}
private void RemoveDressEntry( object obj )
{
if ( !( obj is DressAgentEntry dae ) )
{
return;
}
dae.Hotkey = ShortcutKeys.Default;
Items.Remove( dae );
}
private async Task DressAllItems( object obj )
{
if ( !( obj is DressAgentEntry dae ) )
{
return;
}
IsDressingOrUndressing = true;
await _manager.DressAllItems( dae, MoveConflictingItems );
IsDressingOrUndressing = false;
}
private void ImportItems( object obj )
{
if ( !( obj is DressAgentEntry dae ) )
{
return;
}
_manager.ImportItems( dae );
}
public bool IsValidLayer( Layer layer )
{
return _validLayers.Any( l => l == layer );
}
private static void ChangeDressType( object obj )
{
if ( !( obj is DressAgentItem dai ) )
{
return;
}
dai.Type = dai.Type == DressAgentItemType.Serial ? DressAgentItemType.ID : DressAgentItemType.Serial;
}
}
}
@@ -0,0 +1,133 @@
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using ClassicAssist.Data;
using ClassicAssist.Data.Friends;
using ClassicAssist.Data.Macros.Commands;
using ClassicAssist.Misc;
using ClassicAssist.UI.ViewModels;
using Newtonsoft.Json.Linq;
using ReactiveUI;
namespace ClassicAssist.Shared.UI.ViewModels.Agents
{
public class FriendsTabViewModel : BaseViewModel, ISettingProvider
{
private ICommand _addFriendCommand;
private ICommand _changeRehueOption;
private Options _options;
private ICommand _removeFriendCommand;
private FriendEntry _selectedItem;
private ICommand _selectHueCommand;
public ICommand AddFriendCommand =>
_addFriendCommand ?? ( _addFriendCommand = new RelayCommandAsync( AddFriend, o => true ) );
public ICommand ChangeRehueOption =>
_changeRehueOption ?? ( _changeRehueOption = new RelayCommand( ChangeRehue, o => true ) );
public Options Options
{
get => _options;
set => SetProperty( ref _options, value );
}
public ICommand RemoveFriendCommand =>
_removeFriendCommand ?? ( _removeFriendCommand = ReactiveCommand.CreateFromTask<FriendEntry>( RemoveFriend,
this.WhenAnyValue( e => e.SelectedItem, selector: e => e != null ) ) );
//new RelayCommandAsync( RemoveFriend, o => SelectedItem != null ) );
public FriendEntry SelectedItem
{
get => _selectedItem;
set => SetProperty( ref _selectedItem, value );
}
public ICommand SelectHueCommand =>
_selectHueCommand ?? ( _selectHueCommand = ReactiveCommand.CreateFromTask( SelectHue,
this.WhenAnyValue( e => e.Options.RehueFriends, selector: e => e ) ) );
public void Serialize( JObject json )
{
JObject config = new JObject
{
["IncludePartyMembersInFriends"] = Options.IncludePartyMembersInFriends,
["PreventAttackingFriendsInWarMode"] = Options.PreventAttackingFriendsInWarMode,
["PreventTargetingFriendsWithHarmful"] = Options.PreventTargetingFriendsWithHarmful
};
JArray friends = new JArray();
foreach ( FriendEntry friend in Options.Friends )
{
friends.Add( new JObject { { "Name", friend.Name }, { "Serial", friend.Serial } } );
}
config.Add( "Items", friends );
json?.Add( "Friends", config );
}
public void Deserialize( JObject json, Options options )
{
Options = options;
Options.Friends.Clear();
if ( json?["Friends"] == null )
{
return;
}
JToken config = json["Friends"];
Options.IncludePartyMembersInFriends = config["IncludePartyMembersInFriends"]?.ToObject<bool>() ?? true;
Options.PreventAttackingFriendsInWarMode =
config["PreventAttackingFriendsInWarMode"]?.ToObject<bool>() ?? true;
Options.PreventTargetingFriendsWithHarmful =
config["PreventTargetingFriendsWithHarmful"]?.ToObject<bool>() ?? false;
if ( config["Items"] == null )
{
return;
}
foreach ( JToken token in config["Items"] )
{
Options.Friends.Add( new FriendEntry
{
Name = token["Name"].ToObject<string>(), Serial = token["Serial"].ToObject<int>()
} );
}
}
private static void ChangeRehue( object obj )
{
MainCommands.Resync();
}
private static async Task SelectHue( CancellationToken token )
{
int hue = await Engine.UIInvoker.GetHueAsync();
Options.CurrentOptions.RehueFriendsHue = hue;
MainCommands.Resync();
}
private static async Task AddFriend( object arg )
{
await Task.Run( () => MobileCommands.AddFriend() );
}
private static Task RemoveFriend( object arg )
{
if ( !( arg is FriendEntry fe ) )
{
return Task.CompletedTask;
}
MobileCommands.RemoveFriend( fe.Serial );
return Task.CompletedTask;
}
}
}
@@ -0,0 +1,246 @@
using System.Reactive;
using System.Threading.Tasks;
using System.Windows.Input;
using ClassicAssist.Data;
using ClassicAssist.Data.Hotkeys;
using ClassicAssist.Data.Organizer;
using ClassicAssist.Misc;
using ClassicAssist.Shared.Resources;
using ClassicAssist.Shared.UO;
using ClassicAssist.UI.ViewModels;
using ClassicAssist.UO.Data;
using ClassicAssist.UO.Objects;
using Newtonsoft.Json.Linq;
using ReactiveUI;
namespace ClassicAssist.Shared.UI.ViewModels.Agents
{
public class OrganizerTabViewModel : HotkeyEntryViewModel<OrganizerEntry>, ISettingProvider
{
private readonly OrganizerManager _manager;
private ReactiveCommand<OrganizerEntry, Unit> _insertItemCommand;
private bool _isOrganizing;
private ICommand _newOrganizerEntryCommand;
private ReactiveCommand<OrganizerEntry, Unit> _organizeCommand;
private ReactiveCommand<OrganizerItem, Unit> _removeItemCommand;
private ReactiveCommand<OrganizerEntry, Unit> _removeOrganizerAgentEntryCommand;
private OrganizerEntry _selectedItem;
private OrganizerItem _selectedOrganizerItem;
private ReactiveCommand<OrganizerEntry, Unit> _setContainersCommand;
public OrganizerTabViewModel() : base( Strings.Organizer )
{
_manager = OrganizerManager.GetInstance();
_manager.Items = Items;
}
public ReactiveCommand<OrganizerEntry, Unit> InsertItemCommand =>
_insertItemCommand ?? ( _insertItemCommand = ReactiveCommand.CreateFromTask<OrganizerEntry>( InsertItem,
this.WhenAnyValue( e => e.SelectedItem, e => e.IsOrganizing, ( e, f ) => e != null && !f ) ) );
public bool IsOrganizing
{
get => _isOrganizing;
set
{
SetProperty( ref _isOrganizing, value );
NotifyPropertyChanged( nameof( PlayStopButtonText ) );
}
}
public ICommand NewOrganizerEntryCommand =>
_newOrganizerEntryCommand ??
( _newOrganizerEntryCommand = new RelayCommand( NewOrganizerEntry, o => !IsOrganizing ) );
public ReactiveCommand<OrganizerEntry, Unit> OrganizeCommand =>
_organizeCommand ?? ( _organizeCommand = ReactiveCommand.CreateFromTask<OrganizerEntry>( Organize,
this.WhenAnyValue( e => e.SelectedItem, selector: e => e != null ) ) );
public string PlayStopButtonText => IsOrganizing ? Strings.Stop : Strings.Play;
public ReactiveCommand<OrganizerItem, Unit> RemoveItemCommand =>
_removeItemCommand ?? ( _removeItemCommand = ReactiveCommand.Create<OrganizerItem>( RemoveItem,
this.WhenAnyValue( e => e.IsOrganizing, e => e.SelectedOrganizerItem, ( e, f ) => !e && f != null ) ) );
public ReactiveCommand<OrganizerEntry, Unit> RemoveOrganizerAgentEntryCommand =>
_removeOrganizerAgentEntryCommand ?? ( _removeOrganizerAgentEntryCommand =
ReactiveCommand.Create<OrganizerEntry>( RemoveOrganizerAgentEntry,
this.WhenAnyValue( e => e.SelectedItem, selector: e => e != null ) ) );
public OrganizerEntry SelectedItem
{
get => _selectedItem;
set => SetProperty( ref _selectedItem, value );
}
public OrganizerItem SelectedOrganizerItem
{
get => _selectedOrganizerItem;
set => SetProperty( ref _selectedOrganizerItem, value );
}
public ReactiveCommand<OrganizerEntry, Unit> SetContainersCommand =>
_setContainersCommand ?? ( _setContainersCommand =
ReactiveCommand.CreateFromTask<OrganizerEntry>( _manager.SetContainers,
this.WhenAnyValue( e => e.SelectedItem, f => f.IsOrganizing, ( e, f ) => e != null && !f ) ) );
//new RelayCommandAsync( _manager.SetContainers, o => SelectedItem != null && !IsOrganizing ) );
public void Serialize( JObject json )
{
JArray organizer = new JArray();
foreach ( OrganizerEntry organizerEntry in Items )
{
JObject entryObj = new JObject();
SetJsonValue( entryObj, "Name", organizerEntry.Name );
SetJsonValue( entryObj, "Stack", organizerEntry.Stack );
SetJsonValue( entryObj, "SourceContainer", organizerEntry.SourceContainer );
SetJsonValue( entryObj, "DestinationContainer", organizerEntry.DestinationContainer );
SetJsonValue( entryObj, "Keys", organizerEntry.Hotkey.ToJObject() );
SetJsonValue( entryObj, "Complete", organizerEntry.Complete );
JArray itemsArray = new JArray();
foreach ( OrganizerItem organizerItem in organizerEntry.Items )
{
JObject itemsObj = new JObject();
SetJsonValue( itemsObj, "Item", organizerItem.Item );
SetJsonValue( itemsObj, "ID", organizerItem.ID );
SetJsonValue( itemsObj, "Hue", organizerItem.Hue );
SetJsonValue( itemsObj, "Amount", organizerItem.Amount );
itemsArray.Add( itemsObj );
}
entryObj.Add( "Items", itemsArray );
organizer.Add( entryObj );
}
json?.Add( "Organizer", organizer );
}
public void Deserialize( JObject json, Options options )
{
Items.Clear();
if ( json?["Organizer"] == null )
{
return;
}
foreach ( JToken token in json["Organizer"] )
{
OrganizerEntry entry = new OrganizerEntry
{
Name = GetJsonValue( token, "Name", "Organizer" ),
Stack = GetJsonValue( token, "Stack", true ),
SourceContainer = GetJsonValue( token, "SourceContainer", 0 ),
DestinationContainer = GetJsonValue( token, "DestinationContainer", 0 ),
Hotkey = new ShortcutKeys( token["Keys"] ),
Complete = GetJsonValue( token, "Complete", false )
};
entry.Action = hks => Task.Run( async () => await _manager.Organize( entry ) );
entry.IsRunning = () => IsOrganizing;
foreach ( JToken itemToken in token["Items"] )
{
OrganizerItem item = new OrganizerItem
{
Item = GetJsonValue( itemToken, "Item", string.Empty ),
ID = GetJsonValue( itemToken, "ID", 0 ),
Hue = GetJsonValue( itemToken, "Hue", -1 ),
Amount = GetJsonValue( itemToken, "Amount", -1 )
};
entry.Items.Add( item );
}
Items.Add( entry );
}
}
private async Task Organize( object arg )
{
if ( !( arg is OrganizerEntry entry ) )
{
return;
}
IsOrganizing = true;
await _manager.Organize( entry );
IsOrganizing = false;
}
private void NewOrganizerEntry( object obj )
{
int count = Items.Count + 1;
OrganizerEntry entry = new OrganizerEntry
{
Name = $"Organizer-{count}",
Action = hks => Task.Run( async () => await _manager.Organize( SelectedItem ) ),
IsRunning = () => IsOrganizing
};
Items.Add( entry );
}
private void RemoveOrganizerAgentEntry( object obj )
{
if ( !( obj is OrganizerEntry entry ) )
{
return;
}
Items.Remove( entry );
}
private void RemoveItem( object obj )
{
if ( !( obj is OrganizerItem item ) )
{
return;
}
SelectedItem.Items.Remove( item );
}
private static async Task InsertItem( object arg )
{
if ( !( arg is OrganizerEntry entry ) )
{
return;
}
int serial = await Commands.GetTargeSerialAsync( Strings.Target_new_item___ );
if ( serial <= 0 )
{
Commands.SystemMessage( Strings.Invalid_or_unknown_object_id );
return;
}
Item item = Engine.Items.GetItem( serial );
if ( item == null )
{
Commands.SystemMessage( Strings.Cannot_find_item___ );
return;
}
OrganizerItem organizerItem = new OrganizerItem
{
Item = TileData.GetStaticTile( item.ID ).Name, ID = item.ID, Hue = item.Hue, Amount = -1
};
entry.Items.Add( organizerItem );
}
}
}
@@ -0,0 +1,279 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using ClassicAssist.Data;
using ClassicAssist.Data.Scavenger;
using ClassicAssist.Misc;
using ClassicAssist.Shared.Resources;
using ClassicAssist.UI.ViewModels;
using ClassicAssist.UO.Data;
using ClassicAssist.UO.Network;
using ClassicAssist.UO.Objects;
using Newtonsoft.Json.Linq;
using ReactiveUI;
using UOC = ClassicAssist.Shared.UO.Commands;
namespace ClassicAssist.Shared.UI.ViewModels.Agents
{
public class ScavengerTabViewModel : BaseViewModel, ISettingProvider
{
private const int SCAVENGER_DISTANCE = 2;
private readonly List<int> _ignoreList;
private readonly object _scavengeLock = new object();
private ICommand _clearAllCommand;
private int _containerSerial;
private bool _enabled;
private ICommand _insertCommand;
private ObservableCollection<ScavengerEntry> _items = new ObservableCollection<ScavengerEntry>();
private ICommand _removeCommand;
private ScavengerEntry _selectedItem;
private ICommand _setContainerCommand;
public ScavengerTabViewModel()
{
ScavengerManager manager = ScavengerManager.GetInstance();
manager.Items = Items;
manager.CheckArea = () => Task.Run( CheckArea );
_ignoreList = new List<int>();
}
public ICommand ClearAllCommand =>
_clearAllCommand ?? ( _clearAllCommand = ReactiveCommand.CreateFromTask( ClearAll ) );
public int ContainerSerial
{
get => _containerSerial;
set => SetProperty( ref _containerSerial, value );
}
public bool Enabled
{
get => _enabled;
set => SetProperty( ref _enabled, value );
}
public ICommand InsertCommand =>
_insertCommand ?? ( _insertCommand = new RelayCommandAsync( Insert, o => true ) );
public ObservableCollection<ScavengerEntry> Items
{
get => _items;
set => SetProperty( ref _items, value );
}
public ICommand RemoveCommand =>
_removeCommand ?? ( _removeCommand = ReactiveCommand.CreateFromTask<ScavengerEntry>( Remove,
this.WhenAnyValue( e => e.SelectedItem, selector: e => e != null ) ) );
public ScavengerEntry SelectedItem
{
get => _selectedItem;
set => SetProperty( ref _selectedItem, value );
}
public ICommand SetContainerCommand =>
_setContainerCommand ?? ( _setContainerCommand = new RelayCommandAsync( SetContainer, o => true ) );
public void Serialize( JObject json )
{
Engine.Items.CollectionChanged -= ItemsOnCollectionChanged;
if ( json == null )
{
return;
}
JObject scavengerObj = new JObject { { "Enabled", Enabled }, { "Container", ContainerSerial } };
JArray itemsArray = new JArray();
foreach ( ScavengerEntry entry in Items )
{
itemsArray.Add( new JObject
{
{ "Graphic", entry.Graphic },
{ "Name", entry.Name },
{ "Hue", entry.Hue },
{ "Enabled", entry.Enabled }
} );
}
scavengerObj.Add( "Items", itemsArray );
json.Add( "Scavenger", scavengerObj );
}
public void Deserialize( JObject json, Options options )
{
Engine.Items.CollectionChanged += ItemsOnCollectionChanged;
Items.Clear();
if ( json?["Scavenger"] == null )
{
return;
}
JToken config = json["Scavenger"];
Enabled = config["Enabled"]?.ToObject<bool>() ?? true;
ContainerSerial = config["Container"]?.ToObject<int>() ?? 0;
if ( config["Items"] == null )
{
return;
}
foreach ( JToken token in config["Items"] )
{
ScavengerEntry entry = new ScavengerEntry
{
Graphic = token["Graphic"]?.ToObject<int>() ?? 0,
Name = token["Name"]?.ToObject<string>() ?? "Unknown",
Hue = token["Hue"]?.ToObject<int>() ?? 0,
Enabled = token["Enabled"]?.ToObject<bool>() ?? true
};
bool alreadyExists = Items.Any( s => s.Graphic == entry.Graphic && s.Hue == entry.Hue );
if ( !alreadyExists )
{
Items.Add( entry );
}
}
}
private void ItemsOnCollectionChanged( int totalcount, bool added, Item[] items )
{
if ( !added || !Enabled )
{
return;
}
bool hasNearby = items.Any( i => i.Distance <= SCAVENGER_DISTANCE );
if ( hasNearby )
{
CheckArea();
}
}
public void CheckArea()
{
if ( !Enabled || Engine.Player == null )
{
return;
}
List<Item> scavengerItems = new List<Item>();
if ( Engine.Player.WeightMax - Engine.Player.Weight <= 25 )
{
return;
}
lock ( _scavengeLock )
{
foreach ( ScavengerEntry entry in Items )
{
if ( !entry.Enabled )
{
continue;
}
Item[] matches = Engine.Items.SelectEntities( i =>
i.Distance <= SCAVENGER_DISTANCE && i.Owner == 0 && i.ID == entry.Graphic &&
( entry.Hue == -1 || i.Hue == entry.Hue ) && !_ignoreList.Contains( i.Serial ) );
if ( matches == null )
{
continue;
}
scavengerItems.AddRange( matches );
}
if ( scavengerItems.Count == 0 )
{
return;
}
Item container = Engine.Items.GetItem( _containerSerial ) ?? Engine.Player.Backpack;
if ( container == null )
{
return;
}
foreach ( Item scavengerItem in scavengerItems.Where( scavengerItem =>
scavengerItem.Distance <= SCAVENGER_DISTANCE ).Distinct() )
{
_ignoreList.Add( scavengerItem.Serial );
UOC.SystemMessage( string.Format( Strings.Scavenging___0__, scavengerItem.Name ?? "Unknown" ), 61 );
ActionPacketQueue.EnqueueDragDrop( scavengerItem.Serial, scavengerItem.Count, container.Serial,
QueuePriority.Low, true ).Wait();
}
}
}
private async Task Insert( object arg )
{
int serial = await UOC.GetTargeSerialAsync( Strings.Target_object___ );
if ( serial == 0 )
{
UOC.SystemMessage( Strings.Invalid_or_unknown_object_id );
return;
}
Item item = Engine.Items.GetItem( serial );
if ( item == null )
{
UOC.SystemMessage( Strings.Cannot_find_item___ );
return;
}
string tiledataName = TileData.GetStaticTile( item.ID ).Name ?? "Unknown";
ScavengerEntry entry =
new ScavengerEntry { Enabled = true, Graphic = item.ID, Hue = item.Hue, Name = tiledataName };
Items.Add( entry );
}
private async Task Remove( object arg )
{
if ( !( arg is ScavengerEntry entry ) )
{
return;
}
Items.Remove( entry );
await Task.CompletedTask;
}
private async Task ClearAll( CancellationToken cancellationToken )
{
Items.Clear();
await Task.CompletedTask;
}
private async Task SetContainer( object arg )
{
int serial = await UOC.GetTargeSerialAsync( Strings.Select_destination_container___ );
if ( serial == 0 )
{
UOC.SystemMessage( Strings.Invalid_container___ );
return;
}
ContainerSerial = serial;
}
}
}
@@ -0,0 +1,238 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using ClassicAssist.Data;
using ClassicAssist.Data.Macros;
using ClassicAssist.Data.Macros.Commands;
using ClassicAssist.Data.Vendors;
using ClassicAssist.Misc;
using ClassicAssist.Shared.Resources;
using ClassicAssist.UI.ViewModels;
using ClassicAssist.UO.Data;
using ClassicAssist.UO.Network;
using ClassicAssist.UO.Objects;
using Newtonsoft.Json.Linq;
using ReactiveUI;
using UOC = ClassicAssist.Shared.UO.Commands;
namespace ClassicAssist.Shared.UI.ViewModels.Agents
{
public class VendorBuyTabViewModel : BaseViewModel, ISettingProvider
{
private bool _enabled;
private bool _includeBackpackAmount;
private bool _includePurchasedAmount;
private ICommand _insertCommand;
private ObservableCollection<VendorBuyAgentEntry> _items = new ObservableCollection<VendorBuyAgentEntry>();
private ICommand _removeCommand;
private VendorBuyAgentEntry _selectedItem;
public VendorBuyTabViewModel()
{
IncomingPacketHandlers.VendorBuyDisplayEvent += OnVendorBuyDisplayEvent;
}
public bool Enabled
{
get => _enabled;
set => SetProperty( ref _enabled, value );
}
public bool IncludeBackpackAmount
{
get => _includeBackpackAmount;
set => SetProperty( ref _includeBackpackAmount, value );
}
public bool IncludePurchasedAmount
{
get => _includePurchasedAmount;
set => SetProperty( ref _includePurchasedAmount, value );
}
public ICommand InsertCommand =>
_insertCommand ?? ( _insertCommand = ReactiveCommand.CreateFromTask( Insert ) );
public ObservableCollection<VendorBuyAgentEntry> Items
{
get => _items;
set => SetProperty( ref _items, value );
}
public ICommand RemoveCommand =>
_removeCommand ?? ( _removeCommand = ReactiveCommand.Create<VendorBuyAgentEntry>( Remove,
this.WhenAnyValue( e => e.SelectedItem, selector: e => e != null ) ) );
public VendorBuyAgentEntry SelectedItem
{
get => _selectedItem;
set => SetProperty( ref _selectedItem, value );
}
public void Serialize( JObject json )
{
if ( json == null )
{
return;
}
JObject config = new JObject
{
{ "Enabled", Enabled },
{ "IncludeBackpackAmount", IncludeBackpackAmount },
{ "IncludePurchasedAmount", IncludePurchasedAmount }
};
JArray itemObj = new JArray();
foreach ( VendorBuyAgentEntry entry in Items )
{
JObject entryObj = new JObject
{
{ "Enabled", entry.Enabled },
{ "Name", entry.Name },
{ "Graphic", entry.Graphic },
{ "Hue", entry.Hue },
{ "Amount", entry.Amount },
{ "MaxPrice", entry.MaxPrice }
};
itemObj.Add( entryObj );
}
config.Add( "Items", itemObj );
json.Add( "VendorBuy", config );
}
public void Deserialize( JObject json, Options options )
{
Items.Clear();
if ( json?["VendorBuy"] == null )
{
return;
}
JToken config = json["VendorBuy"];
Enabled = config["Enabled"]?.ToObject<bool>() ?? false;
IncludeBackpackAmount = config["IncludeBackpackAmount"]?.ToObject<bool>() ?? false;
IncludePurchasedAmount = config["IncludePurchasedAmount"]?.ToObject<bool>() ?? false;
foreach ( JToken token in config["Items"] )
{
VendorBuyAgentEntry vbae = new VendorBuyAgentEntry
{
Enabled = token["Enabled"]?.ToObject<bool>() ?? false,
Name = token["Name"]?.ToObject<string>() ?? "Unknown",
Graphic = token["Graphic"]?.ToObject<int>() ?? 0,
Hue = token["Hue"]?.ToObject<int>() ?? 0,
Amount = token["Amount"]?.ToObject<int>() ?? 0,
MaxPrice = token["MaxPrice"]?.ToObject<int>() ?? 0
};
Items.Add( vbae );
}
}
private void OnVendorBuyDisplayEvent( int serial, ShopListEntry[] entries )
{
if ( !Enabled )
{
return;
}
IEnumerable<VendorBuyAgentEntry> items = Items.Where( i => i.Enabled );
List<ShopListEntry> buyList = new List<ShopListEntry>();
foreach ( VendorBuyAgentEntry entry in items )
{
IEnumerable<ShopListEntry> matches = entries.Where( i =>
i.Item.ID == entry.Graphic && ( entry.Hue == -1 || i.Item.Hue == entry.Hue ) &&
( entry.MaxPrice == -1 || i.Price <= entry.MaxPrice ) );
foreach ( ShopListEntry match in matches )
{
if ( entry.Amount != -1 )
{
if ( match.Amount > entry.Amount )
{
match.Amount = entry.Amount;
}
if ( IncludeBackpackAmount )
{
int currentAmount = ObjectCommands.CountType( entry.Graphic, "backpack", entry.Hue );
if ( currentAmount + match.Amount > entry.Amount )
{
match.Amount = entry.Amount - currentAmount;
}
}
}
if ( match.Amount > 0 )
{
buyList.Add( match );
}
}
}
if ( buyList.Count > 0 )
{
UOC.VendorBuy( serial, buyList.ToArray() );
}
if ( !MacroManager.QuietMode && buyList.Count == 0 )
{
UOC.SystemMessage( Strings.Buy_Agent__No_matches_found_ );
}
}
private async Task Insert( CancellationToken cancellationToken )
{
int serial = await UOC.GetTargeSerialAsync( Strings.Target_object___ );
if ( serial == 0 )
{
UOC.SystemMessage( Strings.Invalid_or_unknown_object_id );
return;
}
Item item = Engine.Items.GetItem( serial );
if ( item == null )
{
UOC.SystemMessage( Strings.Cannot_find_item___ );
return;
}
string name = TileData.GetStaticTile( item.ID ).Name ?? item.Name;
Items.Add( new VendorBuyAgentEntry
{
Enabled = true,
Name = name,
Graphic = item.ID,
Amount = -1,
Hue = item.Hue,
MaxPrice = -1
} );
}
private void Remove( object obj )
{
if ( !( obj is VendorBuyAgentEntry entry ) )
{
return;
}
Items.Remove( entry );
}
}
}
@@ -0,0 +1,201 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using ClassicAssist.Data;
using ClassicAssist.Data.Vendors;
using ClassicAssist.Misc;
using ClassicAssist.Shared.Resources;
using ClassicAssist.UI.ViewModels;
using ClassicAssist.UO.Data;
using ClassicAssist.UO.Network;
using ClassicAssist.UO.Objects;
using Newtonsoft.Json.Linq;
using ReactiveUI;
using UOC = ClassicAssist.Shared.UO.Commands;
namespace ClassicAssist.Shared.UI.ViewModels.Agents
{
public class VendorSellTabViewModel : BaseViewModel, ISettingProvider
{
private ICommand _insertCommand;
private ObservableCollection<VendorSellAgentEntry> _items = new ObservableCollection<VendorSellAgentEntry>();
private ICommand _removeCommand;
private VendorSellAgentEntry _selectedItem;
public VendorSellTabViewModel()
{
IncomingPacketHandlers.VendorSellDisplayEvent += OnVendorSellDisplayEvent;
}
public ICommand InsertCommand =>
_insertCommand ?? ( _insertCommand = ReactiveCommand.CreateFromTask( Insert ) );
public ObservableCollection<VendorSellAgentEntry> Items
{
get => _items;
set => SetProperty( ref _items, value );
}
public ICommand RemoveCommand =>
_removeCommand ?? ( _removeCommand = ReactiveCommand.Create<VendorSellAgentEntry>( Remove,
this.WhenAnyValue( e => e.SelectedItem, selector: e => e != null ) ) );
public VendorSellAgentEntry SelectedItem
{
get => _selectedItem;
set => SetProperty( ref _selectedItem, value );
}
public void Serialize( JObject json )
{
if ( json == null )
{
return;
}
JArray itemsObj = new JArray();
foreach ( VendorSellAgentEntry item in Items )
{
JObject itemObj = new JObject
{
{ "Enabled", item.Enabled },
{ "Graphic", item.Graphic },
{ "Hue", item.Hue },
{ "Amount", item.Amount },
{ "MinPrice", item.MinPrice },
{ "Name", item.Name }
};
itemsObj.Add( itemObj );
}
JObject config = new JObject { { "Items", itemsObj } };
json.Add( "VendorSell", config );
}
public void Deserialize( JObject json, Options options )
{
Items.Clear();
if ( json?["VendorSell"] == null )
{
return;
}
JToken config = json["VendorSell"];
foreach ( JToken items in config?["Items"] )
{
VendorSellAgentEntry vsae = new VendorSellAgentEntry
{
Enabled = items["Enabled"]?.ToObject<bool>() ?? true,
Graphic = items["Graphic"]?.ToObject<int>() ?? 0,
Hue = items["Hue"]?.ToObject<int>() ?? 0,
Amount = items["Amount"]?.ToObject<int>() ?? -1,
MinPrice = items["MinPrice"]?.ToObject<int>() ?? 0,
Name = items["Name"]?.ToObject<string>() ?? string.Empty
};
Items.Add( vsae );
}
}
private void Remove( object arg )
{
if ( !( arg is VendorSellAgentEntry entry ) )
{
return;
}
Items.Remove( entry );
}
private void OnVendorSellDisplayEvent( int serial, SellListEntry[] entries )
{
List<SellListEntry> sellList = new List<SellListEntry>();
foreach ( SellListEntry entry in entries )
{
VendorSellAgentEntry match = Items.FirstOrDefault( i =>
i.Graphic == entry.ID && ( i.Hue == -1 || i.Hue == entry.Hue ) && entry.Price >= i.MinPrice &&
i.Enabled );
if ( match != null && match.Amount != -1 )
{
entry.Amount = Math.Min( match.Amount, entry.Amount );
}
if ( match != null )
{
sellList.Add( entry );
}
}
if ( sellList.Count > 0 )
{
Sell( serial, sellList.ToArray() );
}
}
public static void Sell( int vendorSerial, SellListEntry[] entries )
{
if ( entries == null || entries.Length == 0 )
{
return;
}
int len = 9 + entries.Length * 6;
PacketWriter pw = new PacketWriter( len );
pw.Write( (byte) 0x9F );
pw.Write( (short) len );
pw.Write( vendorSerial );
pw.Write( (short) entries.Length );
foreach ( SellListEntry entry in entries )
{
pw.Write( entry.Serial );
pw.Write( (short) entry.Amount );
}
Engine.SendPacketToServer( pw );
}
private async Task Insert( CancellationToken cancellationToken )
{
int serial = await UOC.GetTargeSerialAsync( Strings.Target_object___ );
if ( serial == 0 )
{
UOC.SystemMessage( Strings.Invalid_or_unknown_object_id );
return;
}
Item item = Engine.Items.GetItem( serial );
if ( item == null )
{
UOC.SystemMessage( Strings.Cannot_find_item___ );
return;
}
string name = TileData.GetStaticTile( item.ID ).Name ?? item.Name;
Items.Add( new VendorSellAgentEntry
{
Enabled = true,
Name = name,
Graphic = item.ID,
Hue = item.Hue,
Amount = -1,
MinPrice = 0
} );
}
}
}