Skip to content

Commit

Permalink
Adding Basic Give/Remove GP Commands
Browse files Browse the repository at this point in the history
  • Loading branch information
benrick committed May 7, 2020
1 parent e83eb6b commit d6919f8
Show file tree
Hide file tree
Showing 10 changed files with 320 additions and 2 deletions.
87 changes: 87 additions & 0 deletions src/InteractiveSeven.Core/Diagnostics/Memory/GpAccessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using InteractiveSeven.Core.FinalFantasy;
using InteractiveSeven.Core.Settings;
using Microsoft.Extensions.Logging;
using System;

namespace InteractiveSeven.Core.Diagnostics.Memory
{
public class GpAccessor : IGpAccessor
{
private readonly IMemoryAccessor _memoryAccessor;
private readonly ILogger<GpAccessor> _logger;
private ApplicationSettings Settings => ApplicationSettings.Instance;
private static readonly object Padlock = new object();

public GpAccessor(IMemoryAccessor memoryAccessor, ILogger<GpAccessor> logger)
{
_memoryAccessor = memoryAccessor;
_logger = logger;
}

public ushort GetGp()
{
try
{
lock (Padlock)
{
var buffer = new byte[Addresses.Gp.NumBytes];
_memoryAccessor.ReadMem(Settings.ProcessName, Addresses.Gp.Address, buffer);
return BitConverter.ToUInt16(buffer);
}
}
catch (Exception e)
{
_logger.LogError(e, "Error setting player GP.");
}

return 0;
}

public void AddGp(in ushort amount)
{
try
{
lock (Padlock)
{
var buffer = new byte[Addresses.Gp.NumBytes];
_memoryAccessor.ReadMem(Settings.ProcessName, Addresses.Gp.Address, buffer);
ushort currentBalance = BitConverter.ToUInt16(buffer);
currentBalance += amount;
_memoryAccessor.WriteMem(Settings.ProcessName, Addresses.Gp.Address,
BitConverter.GetBytes(currentBalance));
}
}
catch (Exception e)
{
_logger.LogError(e, "Error adding GP to player.");
}
}

public void RemoveGp(ushort amount)
{
try
{
lock (Padlock)
{
var buffer = new byte[Addresses.Gp.NumBytes];
_memoryAccessor.ReadMem(Settings.ProcessName, Addresses.Gp.Address, buffer);
ushort currentBalance = BitConverter.ToUInt16(buffer);
if (currentBalance >= amount)
{
currentBalance -= amount;
}
else
{
currentBalance = 0;
}
_memoryAccessor.WriteMem(Settings.ProcessName, Addresses.Gp.Address,
BitConverter.GetBytes(currentBalance));
}
}
catch (Exception e)
{
_logger.LogError(e, "Error adding GP to player.");
}
}
}
}
9 changes: 9 additions & 0 deletions src/InteractiveSeven.Core/Diagnostics/Memory/IGpAccessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace InteractiveSeven.Core.Diagnostics.Memory
{
public interface IGpAccessor
{
ushort GetGp();
void AddGp(in ushort amount);
void RemoveGp(ushort amount);
}
}
6 changes: 6 additions & 0 deletions src/InteractiveSeven.Core/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ public static int SafeIntParse(this string text)
return result;
}

public static ushort SafeUshortParse(this string text)
{
ushort.TryParse(text, out ushort result);
return result;
}

public static string NoAt(this string text) => text.TrimStart('@');
}
}
1 change: 1 addition & 0 deletions src/InteractiveSeven.Core/FinalFantasy/Addresses.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public static class Addresses
public static readonly MemLoc MenuBotRightSave = new MemLoc(0x91EFE1, 3); // order red, green, blue

public static readonly MemLoc Gil = new MemLoc(0xDC08B4, 4); // 4 bytes
public static readonly MemLoc Gp = new MemLoc(0xDC0A26, 2); // Max of 10,000?
public static readonly MemLoc GameMoment = new MemLoc(0xDC08DC, 2);

public static readonly MemLoc MenuVisibility = new MemLoc(0xDC08F8, 2);
Expand Down
31 changes: 29 additions & 2 deletions src/InteractiveSeven.Core/Settings/CommandSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ public class CommandSettings : ObservableSettingsBase
{
private string[] _givePlayerGilCommandWords = { "FindGil", "GivePlayerGil" };
private string[] _removePlayerGilCommandWords = { "DropGil", "RemovePlayerGil" };
private string[] _givePlayerGpCommandWords = { "FindGp", "GivePlayerGp" };
private string[] _removePlayerGpCommandWords = { "DropGp", "RemovePlayerGp" };
private string[] _esunaCommandWords = { "Esuna", "Remedy" };
private string[] _healCommandWords = { "Heal", "Cure" };
private string[] _costsCommandWords = { "Costs", "Cost", "Price", "Prices" };
Expand Down Expand Up @@ -52,11 +54,16 @@ public CommandSettings()
("BrendanLock", () => new [] {"BrendanLock"}),
("BrendanUnlock", () => new [] {"BrendanUnlock"}),

(nameof(GiveGilCommandWords),
() => GiveGilCommandWords),
(nameof(GivePlayerGilCommandWords),
() => GivePlayerGilCommandWords),
(nameof(RemovePlayerGilCommandWords),
() => RemovePlayerGilCommandWords),

(nameof(GivePlayerGpCommandWords),
() => GivePlayerGpCommandWords),
(nameof(RemovePlayerGpCommandWords),
() => RemovePlayerGpCommandWords),

(nameof(EsunaCommandWords),
() => EsunaCommandWords),
(nameof(HealCommandWords),
Expand Down Expand Up @@ -153,6 +160,26 @@ public string[] RemovePlayerGilCommandWords
}
}

public string[] GivePlayerGpCommandWords
{
get => _givePlayerGpCommandWords;
set
{
_givePlayerGpCommandWords = RemoveAllDuplicates(value);
OnPropertyChanged();
}
}

public string[] RemovePlayerGpCommandWords
{
get => _removePlayerGpCommandWords;
set
{
_removePlayerGpCommandWords = RemoveAllDuplicates(value);
OnPropertyChanged();
}
}

public string[] EsunaCommandWords
{
get => _esunaCommandWords;
Expand Down
1 change: 1 addition & 0 deletions src/InteractiveSeven.Core/Settings/EquipmentSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,6 @@ public List<EquippableSettings> AllByName(string name, CharNames charName, Type
public List<EquippableSettings> AllArmlets { get; set; }
public List<EquippableSettings> AllAccessories { get; set; }
public PlayerGilSettings PlayerGilSettings { get; set; } = new PlayerGilSettings();
public PlayerGpSettings PlayerGpSettings { get; set; } = new PlayerGpSettings();
}
}
57 changes: 57 additions & 0 deletions src/InteractiveSeven.Core/Settings/PlayerGpSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
namespace InteractiveSeven.Core.Settings
{
public class PlayerGpSettings : ObservableSettingsBase
{
private int _giveMultiplier = 100;
private int _removeMultiplier = 100;
private bool _allowModOverride = true;
private bool _giveGpEnabled = false;
private bool _removeGpEnabled = false;

public bool GiveGpEnabled // TODO: Add to UI
{
get => _giveGpEnabled;
set
{
_giveGpEnabled = value;
OnPropertyChanged();
}
}
public bool RemoveGpEnabled // TODO: Add to UI
{
get => _removeGpEnabled;
set
{
_removeGpEnabled = value;
OnPropertyChanged();
}
}
public int GiveMultiplier // TODO: Add to UI
{
get => _giveMultiplier;
set
{
_giveMultiplier = value;
OnPropertyChanged();
}
}
public int RemoveMultiplier // TODO: Add to UI
{
get => _removeMultiplier;
set
{
_removeMultiplier = value;
OnPropertyChanged();
}
}
public bool AllowModOverride // TODO: Add to UI
{
get => _allowModOverride;
set
{
_allowModOverride = value;
OnPropertyChanged();
}
}
}
}
59 changes: 59 additions & 0 deletions src/InteractiveSeven.Twitch/Commands/GivePlayerGpCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using InteractiveSeven.Core;
using InteractiveSeven.Core.Diagnostics.Memory;
using InteractiveSeven.Core.Emitters;
using InteractiveSeven.Core.Settings;
using InteractiveSeven.Twitch.Model;
using InteractiveSeven.Twitch.Payments;
using System.Linq;
using TwitchLib.Client.Interfaces;

namespace InteractiveSeven.Twitch.Commands
{
public class GivePlayerGpCommand : BaseCommand
{
private readonly PaymentProcessor _paymentProcessor;
private readonly ITwitchClient _twitchClient;
private readonly IGpAccessor _gpAccessor;
private readonly IStatusHubEmitter _statusHubEmitter;
private PlayerGpSettings GpSettings => Settings.EquipmentSettings.PlayerGpSettings;

public GivePlayerGpCommand(PaymentProcessor paymentProcessor, ITwitchClient twitchClient,
IGpAccessor gpAccessor, IStatusHubEmitter statusHubEmitter)
: base(x => x.GivePlayerGpCommandWords,
x => x.EquipmentSettings.PlayerGpSettings.GiveGpEnabled)
{
_paymentProcessor = paymentProcessor;
_twitchClient = twitchClient;
_gpAccessor = gpAccessor;
_statusHubEmitter = statusHubEmitter;
}

public override void Execute(in CommandData commandData)
{
ushort amount = commandData.Arguments.FirstOrDefault().SafeUshortParse();

if (amount <= 0)
{
_twitchClient.SendMessage(commandData.Channel,
$"How much gp do you want to give to the player, {commandData.User.Username}?");
return;
}

int gilCost = amount * GpSettings.GiveMultiplier;
GilTransaction gilTransaction = _paymentProcessor.ProcessPayment(
commandData, gilCost, GpSettings.AllowModOverride);

if (!gilTransaction.Paid)
{
_twitchClient.SendMessage(commandData.Channel,
$"You don't have {gilCost} gil, {commandData.User.Username}.");
return;
}

_gpAccessor.AddGp(amount);
string message = $"Added {amount} GP for player.";
_twitchClient.SendMessage(commandData.Channel, message);
_statusHubEmitter.ShowEvent(message);
}
}
}
68 changes: 68 additions & 0 deletions src/InteractiveSeven.Twitch/Commands/RemovePlayerGpCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using InteractiveSeven.Core;
using InteractiveSeven.Core.Diagnostics.Memory;
using InteractiveSeven.Core.Emitters;
using InteractiveSeven.Core.Settings;
using InteractiveSeven.Twitch.Model;
using InteractiveSeven.Twitch.Payments;
using System.Linq;
using TwitchLib.Client.Interfaces;

namespace InteractiveSeven.Twitch.Commands
{
public class RemovePlayerGpCommand : BaseCommand
{
private readonly PaymentProcessor _paymentProcessor;
private readonly ITwitchClient _twitchClient;
private readonly IGpAccessor _gpAccessor;
private readonly IStatusHubEmitter _statusHubEmitter;
private PlayerGpSettings GpSettings => Settings.EquipmentSettings.PlayerGpSettings;

public RemovePlayerGpCommand(PaymentProcessor paymentProcessor, ITwitchClient twitchClient,
IGpAccessor gpAccessor, IStatusHubEmitter statusHubEmitter)
: base(x => x.RemovePlayerGpCommandWords,
x => x.EquipmentSettings.PlayerGpSettings.RemoveGpEnabled)
{
_paymentProcessor = paymentProcessor;
_twitchClient = twitchClient;
_gpAccessor = gpAccessor;
_statusHubEmitter = statusHubEmitter;
}

public override void Execute(in CommandData commandData)
{
ushort amount = commandData.Arguments.FirstOrDefault().SafeUshortParse();

if (amount <= 0)
{
_twitchClient.SendMessage(commandData.Channel,
$"How much gp do you want to take from the player, {commandData.User.Username}?");
return;
}

uint currentGp = _gpAccessor.GetGp();
if (amount > currentGp)
{
// TODO: Adjust their request to remove all gp.
_twitchClient.SendMessage(commandData.Channel,
$"Player doesn't have {amount} gp.");
return;
}

int gilCost = amount * GpSettings.RemoveMultiplier;
GilTransaction gilTransaction = _paymentProcessor.ProcessPayment(
commandData, gilCost, GpSettings.AllowModOverride);

if (!gilTransaction.Paid)
{
_twitchClient.SendMessage(commandData.Channel,
$"You don't have {gilCost} gil, {commandData.User.Username}.");
return;
}

_gpAccessor.RemoveGp(amount);
string message = $"Removed {amount} gp from player.";
_twitchClient.SendMessage(commandData.Channel, message);
_statusHubEmitter.ShowEvent(message);
}
}
}
3 changes: 3 additions & 0 deletions src/InteractiveSeven/Startup/DependencyRegistrar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public static void ConfigureServices(IServiceCollection services)
services.AddSingleton<IGameMomentAccessor, GameMomentAccessor>();
services.AddSingleton<IMenuColorAccessor, MenuColorAccessor>();
services.AddSingleton<IGilAccessor, GilAccessor>();
services.AddSingleton<IGpAccessor, GpAccessor>();
services.AddSingleton<IInventoryAccessor, InventoryAccessor>();
services.AddSingleton<IMateriaAccessor, MateriaAccessor>();
services.AddSingleton<IBattleInfoAccessor, BattleInfoAccessor>();
Expand All @@ -81,6 +82,8 @@ public static void ConfigureServices(IServiceCollection services)
services.RegisterNonBattleCommand<PauperCommand>();
services.RegisterNonBattleCommand<RemovePlayerGilCommand>();
services.RegisterNonBattleCommand<GivePlayerGilCommand>();
services.RegisterNonBattleCommand<RemovePlayerGpCommand>();
services.RegisterNonBattleCommand<GivePlayerGpCommand>();

services.RegisterTwitchCommand<PaletteCommand>();
services.RegisterTwitchCommand<RainbowCommand>();
Expand Down

0 comments on commit d6919f8

Please sign in to comment.