-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
22 changed files
with
1,411 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"Author": "Chalkos", | ||
"Name": "Marketbuddy", | ||
"Description": "Helper for your day-to-day market operations", | ||
"InternalName": "Marketbuddy", | ||
"AssemblyVersion": "0.1.0.0", | ||
"RepoUrl": "https://github.com/chalkos/Marketbuddy", | ||
"ApplicableVersion": "any", | ||
"DalamudApiLevel": 3 | ||
} |
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 16 | ||
VisualStudioVersion = 16.0.29709.97 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Marketbuddy", "Marketbuddy\Marketbuddy.csproj", "{13C812E9-0D42-4B95-8646-40EEBF30636F}" | ||
EndProject | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UIDev", "UIDev\UIDev.csproj", "{4FEC9558-EB25-419F-B86E-51B8CFDA32B7}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{13C812E9-0D42-4B95-8646-40EEBF30636F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{13C812E9-0D42-4B95-8646-40EEBF30636F}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{13C812E9-0D42-4B95-8646-40EEBF30636F}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{13C812E9-0D42-4B95-8646-40EEBF30636F}.Release|Any CPU.Build.0 = Release|Any CPU | ||
{4FEC9558-EB25-419F-B86E-51B8CFDA32B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{4FEC9558-EB25-419F-B86E-51B8CFDA32B7}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{4FEC9558-EB25-419F-B86E-51B8CFDA32B7}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{4FEC9558-EB25-419F-B86E-51B8CFDA32B7}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {B17E85B1-5F60-4440-9F9A-3DDE877E8CDF} | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
using Dalamud.Plugin; | ||
using FFXIVClientStructs.FFXIV.Client.UI; | ||
using FFXIVClientStructs.FFXIV.Component.GUI; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
|
||
namespace Marketbuddy.Common | ||
{ | ||
internal static class CloseButtons | ||
{ | ||
private static Dictionary<string, int> closeButtonIndexes = new Dictionary<string, int>() | ||
{ | ||
{"ItemSearchResult", 6 }, | ||
}; | ||
|
||
internal static unsafe AtkComponentNode* getCloseButton(AtkUnitBase* addon) | ||
{ | ||
int index; | ||
string name = Encoding.UTF8.GetString(addon->Name, 16); | ||
if (name != "ItemSearchResult" || !closeButtonIndexes.TryGetValue(name, out index)) | ||
return null; | ||
|
||
AtkUldManager uldMgr = addon->WindowNode->Component->UldManager; | ||
var ret = (uldMgr.NodeListCount > index ? uldMgr.NodeList[index]->GetComponent()->OwnerNode : null); | ||
PluginLog.Information($"Got button for {name}({(UInt64)addon:X}) from nodes[{index}] with addr: {(UInt64)ret:X}"); | ||
return ret; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.Linq; | ||
using System.Reflection; | ||
using System.Runtime.InteropServices; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Dalamud.Game; | ||
using Dalamud.Game.Text.SeStringHandling; | ||
using Dalamud.Hooking; | ||
using Dalamud.Plugin; | ||
using FFXIVClientStructs.Attributes; | ||
using FFXIVClientStructs.FFXIV.Client.System.String; | ||
using FFXIVClientStructs.FFXIV.Component.GUI; | ||
using WindowsInput; | ||
using WindowsInput.Native; | ||
|
||
namespace Marketbuddy.Common | ||
{ | ||
// based on https://github.com/Caraxi/SimpleTweaksPlugin/blob/main/Helper/Common.cs | ||
// and https://github.com/daemitus/ClickLib/blob/master/ClickLib/ClickBase.cs | ||
internal unsafe class Commons : IDisposable | ||
{ | ||
public static DalamudPluginInterface PluginInterface { get; private set; } | ||
|
||
public static SigScanner Scanner => PluginInterface.TargetModuleScanner; | ||
|
||
public static List<IHookWrapper> HookList = new(); | ||
|
||
private InputSimulator InputSimulator; | ||
|
||
protected delegate void ReceiveEventDelegate(IntPtr addon, EventType evt, uint a3, IntPtr a4, IntPtr a5); | ||
|
||
public Commons(DalamudPluginInterface pluginInterface) | ||
{ | ||
PluginInterface = pluginInterface; | ||
InputSimulator = new InputSimulator(); | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
foreach (var hook in HookList.Where(hook => !hook.IsDisposed)) | ||
{ | ||
if (hook.IsEnabled) | ||
hook.Disable(); | ||
hook.Dispose(); | ||
} | ||
HookList.Clear(); | ||
} | ||
|
||
public void pressEsc() | ||
{ | ||
InputSimulator.Keyboard.KeyPress(VirtualKeyCode.ESCAPE); | ||
} | ||
|
||
public void WriteSeString(byte** startPtr, IntPtr alloc, SeString seString) | ||
{ | ||
if (startPtr == null) return; | ||
var start = *startPtr; | ||
if (start == null) return; | ||
if (start == (byte*)alloc) return; | ||
WriteSeString((byte*)alloc, seString); | ||
*startPtr = (byte*)alloc; | ||
} | ||
|
||
public SeString ReadSeString(byte** startPtr) | ||
{ | ||
if (startPtr == null) return null; | ||
var start = *startPtr; | ||
if (start == null) return null; | ||
return ReadSeString(start); | ||
} | ||
|
||
public SeString ReadSeString(byte* ptr) | ||
{ | ||
var offset = 0; | ||
while (true) | ||
{ | ||
var b = *(ptr + offset); | ||
if (b == 0) | ||
{ | ||
break; | ||
} | ||
offset += 1; | ||
} | ||
var bytes = new byte[offset]; | ||
Marshal.Copy(new IntPtr(ptr), bytes, 0, offset); | ||
return PluginInterface.SeStringManager.Parse(bytes); | ||
} | ||
|
||
public void WriteSeString(byte* dst, SeString s) | ||
{ | ||
var bytes = s.Encode(); | ||
for (var i = 0; i < bytes.Length; i++) | ||
{ | ||
*(dst + i) = bytes[i]; | ||
} | ||
*(dst + bytes.Length) = 0; | ||
} | ||
|
||
public SeString ReadSeString(Utf8String xivString) | ||
{ | ||
var len = (int)(xivString.BufUsed > int.MaxValue ? int.MaxValue : xivString.BufUsed); | ||
var bytes = new byte[len]; | ||
Marshal.Copy(new IntPtr(xivString.StringPtr), bytes, 0, len); | ||
return PluginInterface.SeStringManager.Parse(bytes); | ||
} | ||
|
||
public void WriteSeString(Utf8String xivString, SeString s) | ||
{ | ||
var bytes = s.Encode(); | ||
int i; | ||
xivString.BufUsed = 0; | ||
for (i = 0; i < bytes.Length && i < xivString.BufSize - 1; i++) | ||
{ | ||
*(xivString.StringPtr + i) = bytes[i]; | ||
xivString.BufUsed++; | ||
} | ||
*(xivString.StringPtr + i) = 0; | ||
} | ||
|
||
public static HookWrapper<T> Hook<T>(string signature, T detour, bool enable = true, int addressOffset = 0) where T : Delegate | ||
{ | ||
var addr = Scanner.ScanText(signature); | ||
PluginLog.Information("hooking function at {add}", addr); | ||
var h = new Hook<T>(addr + addressOffset, detour); | ||
var wh = new HookWrapper<T>(h); | ||
if (enable) wh.Enable(); | ||
HookList.Add(wh); | ||
return wh; | ||
} | ||
|
||
public static void OpenBrowser(string url) | ||
{ | ||
Process.Start(new ProcessStartInfo { FileName = url, UseShellExecute = true }); | ||
} | ||
protected unsafe ReceiveEventDelegate GetReceiveEventDelegate(AtkEventListener* eventListener) | ||
{ | ||
var receiveEventAddress = new IntPtr(eventListener->vfunc[2]); | ||
return Marshal.GetDelegateForFunctionPointer<ReceiveEventDelegate>(receiveEventAddress); | ||
} | ||
|
||
internal unsafe void SendClick(IntPtr arg1, EventType arg2, uint arg3, void* target) => SendClick(arg1, arg2, arg3, target, IntPtr.Zero); | ||
|
||
internal unsafe void SendClick(IntPtr arg1, EventType arg2, uint arg3, void* target, IntPtr arg5) | ||
{ | ||
var receiveEvent = GetReceiveEventDelegate((AtkEventListener*)arg1); | ||
|
||
var arg4 = Marshal.AllocHGlobal(0x40); | ||
for (var i = 0; i < 0x40; i++) | ||
Marshal.WriteByte(arg4, i, 0); | ||
|
||
Marshal.WriteIntPtr(arg4, 0x8, new IntPtr(target)); | ||
Marshal.WriteIntPtr(arg4, 0x10, arg1); | ||
|
||
if (arg5 == IntPtr.Zero) | ||
{ | ||
arg5 = Marshal.AllocHGlobal(0x40); | ||
for (var i = 0; i < 0x40; i++) | ||
Marshal.WriteByte(arg5, i, 0); | ||
} | ||
|
||
receiveEvent(arg1, arg2, arg3, arg4, arg5); | ||
|
||
Marshal.FreeHGlobal(arg4); | ||
Marshal.FreeHGlobal(arg5); | ||
} | ||
|
||
public static Task<T> StartSTATask<T>(Func<T> func) | ||
{ | ||
var tcs = new TaskCompletionSource<T>(); | ||
var thread = new Thread(() => | ||
{ | ||
try | ||
{ | ||
var result = func(); | ||
tcs.SetResult(result); | ||
} | ||
catch (Exception e) | ||
{ | ||
tcs.SetException(e); | ||
} | ||
}); | ||
thread.SetApartmentState(ApartmentState.STA); | ||
thread.Start(); | ||
return tcs.Task; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace Marketbuddy.Common | ||
{ | ||
public enum EventType : ushort | ||
{ | ||
NORMAL = 1, | ||
NORMAL_MAX = 2, | ||
MOUSE_DOWN = 3, | ||
MOUSE_UP = 4, | ||
MOUSE_MOVE = 5, | ||
MOUSE_ROLL_OVER = 6, | ||
MOUSE_ROLL_OUT = 7, | ||
MOUSE_WHEEL = 8, | ||
MOUSE_CLICK = 9, | ||
MOUSE_DOUBLE_CLICK = 10, | ||
MOUSE_MAX = 11, | ||
INPUT = 12, | ||
INPUT_KEY = 13, | ||
INPUT_MAX = 14, | ||
PAD = 15, | ||
PAD_MAX = 16, | ||
FOCUS_IN = 17, | ||
FOCUS_OUT = 18, | ||
FOCUS_MAX = 19, | ||
RESIZE = 20, | ||
RESIZE_MAX = 21, | ||
BUTTON_PRESS = 22, | ||
BUTTON_CLICK = 23, | ||
BUTTON_MAX = 24, | ||
CHANGE = 25, | ||
CHANGE_MAX = 26, | ||
SLIDER_CHANGE = 27, | ||
SLIDER_CHANGE_END = 28, | ||
LIST_ITEM_PRESS = 29, | ||
LIST_ITEM_UP = 30, | ||
LIST_ITEM_ROLL_OVER = 31, | ||
LIST_ITEM_ROLL_OUT = 32, | ||
LIST_ITEM_CLICK = 33, | ||
LIST_ITEM_DOUBLE_CLICK = 34, | ||
LIST_INDEX_CHANGE = 35, | ||
LIST_FOCUS_CHANGE = 36, | ||
LIST_ITEM_CANCEL = 37, | ||
LIST_ITEM_PICKUP_START = 38, | ||
LIST_ITEM_PICKUP_END = 39, | ||
LIST_ITEM_EXCHANGE = 40, | ||
LIST_TREE_EXPAND = 41, | ||
LIST_MAX = 42, | ||
DDL_LIST_OPEN = 43, | ||
DDL_LIST_CLOSE = 44, | ||
DD_DRAG_START = 45, | ||
DD_DRAG_END = 46, | ||
DD_DROP = 47, | ||
DD_DROP_EXCHANGE = 48, | ||
DD_DROP_NOTICE = 49, | ||
DD_ROLL_OVER = 50, | ||
DD_ROLL_OUT = 51, | ||
DD_DROP_STAGE = 52, | ||
DD_EXECUTE = 53, | ||
ICON_TEXT_ROLL_OVER = 54, | ||
ICON_TEXT_ROLL_OUT = 55, | ||
ICON_TEXT_CLICK = 56, | ||
DIALOGUE_CLOSE = 57, | ||
DIALOGUE_SUBMIT = 58, | ||
TIMER = 59, | ||
TIMER_COMPLETE = 60, | ||
SIMPLETWEEN_UPDATE = 61, | ||
SIMPLETWEEN_COMPLETE = 62, | ||
SETUP_ADDON = 63, | ||
UNIT_BASE_OVER = 64, | ||
UNIT_BASE_OUT = 65, | ||
UNIT_SCALE_CHANEGED = 66, | ||
UNIT_RESOLUTION_SCALE_CHANEGED = 67, | ||
TIMELINE_STATECHANGE = 68, | ||
WORDLINK_CLICK = 69, | ||
WORDLINK_ROLL_OVER = 70, | ||
WORDLINK_ROLL_OUT = 71, | ||
CHANGE_TEXT = 72, | ||
COMPONENT_IN = 73, | ||
COMPONENT_OUT = 74, | ||
COMPONENT_SCROLL = 75, | ||
COMPONENT_FOCUSED = 76, // Maybe | ||
} | ||
} |
Oops, something went wrong.