Skip to content

Commit

Permalink
Added autobuy (open merchant, type .buy start 5 map to buy 5 maples
Browse files Browse the repository at this point in the history
Removed automatic scroll buying from autoSell and moved it to autoBuy (make sure to grab autoBuy.ini)
Removed strings from transmute that were flagged by some antivirus software
  • Loading branch information
nooperation committed Jul 22, 2023
1 parent 475c4b6 commit 62be42a
Show file tree
Hide file tree
Showing 11 changed files with 483 additions and 146 deletions.
172 changes: 172 additions & 0 deletions D2Hackit/Modules/autoBuy/AutoBuy.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
#include "AutoBuy.h"
#include <fstream>
#include <string>
#include <sstream>
#include "../../Core/npc.h"
#include "../../Core/npc.cpp" // TODO: Let's not do this

#define CONFIG_PATH ".\\plugin\\AutoBuy.ini"

BOOL CALLBACK FindStuffToSellCallback(LPCITEM item, LPARAM lParam);

AutoBuy::AutoBuy()
{
this->isAutomaticallyRefillTP = GetPrivateProfileInt("AutoBuy", "AutomaticallyRefillTP", false, CONFIG_PATH);
}

#pragma pack(push, 1)
struct D2GS_NPC_BUY
{
uint8_t PacketId;
uint32_t UnitId;
uint32_t ItemId;
uint32_t BuyType;
uint32_t Cost;
};
#pragma pack(pop)

bool AutoBuy::BuyItemInQuantity(DWORD dwItemID) const
{
if (!me->IsUIOpened(UI_NPCSHOP))
{
server->GameErrorf("ÿc:AutoBuyÿc0: You must first open the trade interface with a merchant");
return false;
}

const auto vendorId = server->GetInteractedNPCUniqueID();
if (vendorId == 0)
{
server->GameErrorf("ÿc:AutoBuyÿc0: No merchant found");
return false;
}

const auto vendorClassId = server->GetInteractedNPCClassID();
if (GetNpcTradeMenuID(vendorClassId) == -1)
{
server->GameErrorf("ÿc:AutoBuyÿc0: Currently selected npc is not a merchant");
return false;
}

GAMEUNIT unit;
unit.dwUnitID = vendorId;
unit.dwUnitType = UNIT_TYPE_MONSTER;
if (!server->VerifyUnit(&unit))
{
server->GameErrorf("ÿc:AutoBuyÿc0: could not verify merchant");
return FALSE;
}

D2GS_NPC_BUY packet;
packet.PacketId = 0x32;
packet.UnitId = vendorId;
packet.ItemId = dwItemID;
packet.BuyType = 0x80000000;
packet.Cost = 0;

return server->GameSendPacketToServer((uint8_t*)&packet, sizeof(packet));
}

bool AutoBuy::Start(int quantity, const std::string& itemCode)
{
if (currentState != State::Uninitialized)
{
this->Stop();
}

server->GameStringf("Attempting to buy %d %s", quantity, itemCode.c_str());

this->numTPTomesToRefill = 0;
this->itemQuantityToBuy = max(0, quantity);
this->itemCodeToBuy = itemCode;

RestockScrolls();

return true;
}

void AutoBuy::Stop()
{
if (currentState != State::Uninitialized)
{
this->itemQuantityToBuy = 0;
this->itemCodeToBuy = "";
this->numTPTomesToRefill = 0;
merchantItems.clear();

me->CleanJobs();
server->GameStringf("ÿc:AutoBuyÿc0: Done");
currentState = State::Uninitialized;
}
}

void AutoBuy::RestockScrolls()
{
if (isAutomaticallyRefillTP)
{
auto tpScrollIdIter = merchantItems.find("tsc");
if (tpScrollIdIter != merchantItems.end())
{
for (auto i = 0; i < this->numTPTomesToRefill; i++)
{
BuyItemInQuantity(tpScrollIdIter->second);
}
}
}

if (itemQuantityToBuy > 0)
{
auto customItemIdIter = merchantItems.find(itemCodeToBuy);
if (customItemIdIter != merchantItems.end())
{
for (auto i = 0; i < itemQuantityToBuy; i++)
{
BuyItemInQuantity(customItemIdIter->second);
}
}
}

this->Stop();
}

// Called when NPC is listing items up for gamble, before NPC_SESSION message
void AutoBuy::OnNpcItemList(const ITEM& merchantItem)
{
merchantItems[merchantItem.szItemCode] = merchantItem.dwItemID;
}

void AutoBuy::OnNPCShopScreenOpened()
{
merchantItems.clear();
}

void AutoBuy::ProcessInventoryItem(const ITEM* item)
{
if (item == nullptr)
{
return;
}

if (strcmp(item->szItemCode, "tbk") == 0)
{
// TODO: d2hackit doesn't update item->iQuantity, never trust it...
GAMEUNIT unit;
unit.dwUnitID = item->dwItemID;
unit.dwUnitType = UNIT_TYPE_ITEM;

auto charges = server->GetUnitStat(&unit, STAT_AMMOQUANTITY);
if (charges < 40)
{
this->numTPTomesToRefill++;
}
}

return;
}

BOOL CALLBACK FindStuffToSellCallback(LPCITEM item, LPARAM lParam)
{
auto instance = (AutoBuy *)lParam;
instance->ProcessInventoryItem(item);

return TRUE;
}
39 changes: 39 additions & 0 deletions D2Hackit/Modules/autoBuy/AutoBuy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include <queue>
#include <unordered_set>
#include <unordered_map>
#include "../../Includes/D2Client.h"

enum class State
{
Uninitialized = 0,
WaitForNPC,
};


class AutoBuy
{
public:
AutoBuy();

bool Start(int quantity, const std::string& itemCode);
void Stop();
void OnNPCShopScreenOpened();
void ProcessInventoryItem(const ITEM *item);
void OnNpcItemList(const ITEM &merchantItem);

private:
void RestockScrolls();
bool BuyItemInQuantity(DWORD dwItemID) const;

bool isAutomaticallyRefillTP = 0;
int numTPTomesToRefill = 0;

int itemQuantityToBuy = 0;
std::string itemCodeToBuy = "";

State currentState = State::Uninitialized;
std::unordered_map<std::string, std::string> targetItems;
std::unordered_map<std::string, DWORD> merchantItems;
};

BOOL CALLBACK FindStuffToSellCallback(LPCPRESETUNIT presetUnit, LPARAM lParam);
126 changes: 126 additions & 0 deletions D2Hackit/Modules/autoBuy/AutoBuy.vcxproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup>
<Diablo2Path Condition="'$(Diablo2Path)' == '' ">C:\Program Files (x86)\Diablo II</Diablo2Path>
</PropertyGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{D92FD3C9-082F-4DFB-B414-3538D1F9DFFF}</ProjectGuid>
<RootNamespace>AutoBuy</RootNamespace>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">buy</TargetName>
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.d2h</TargetExt>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">buy</TargetName>
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.d2h</TargetExt>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;AutoBuy_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<PostBuildEvent>
<Command>xcopy /Y Resources $(SolutionDir)\Publish_$(Configuration)\
xcopy /Y $(TargetPath) $(SolutionDir)\Publish_$(Configuration)\
xcopy /Y $(TargetPath) "$(Diablo2Path)\plugin\"
xcopy /Y $(TargetDir)$(TargetName).pdb "$(Diablo2Path)\plugin\"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;AutoBuy_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<PostBuildEvent>
<Command>xcopy /Y Resources $(SolutionDir)\Publish_$(Configuration)\
xcopy /Y $(TargetPath) $(SolutionDir)\Publish_$(Configuration)\</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="AutoBuy.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="AutoBuy.h" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\AutoBuy.ini" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
2 changes: 2 additions & 0 deletions D2Hackit/Modules/autoBuy/Resources/AutoBuy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[AutoBuy]
AutomaticallyRefillTP = 1
35 changes: 35 additions & 0 deletions D2Hackit/Modules/autoBuy/autoBuy.vcxproj.filters
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="AutoBuy.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="AutoBuy.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="Resources\AutoBuy.ini">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
</Project>
Loading

0 comments on commit 62be42a

Please sign in to comment.