Skip to content

Commit

Permalink
Merge pull request #40 from youbetterdont/feature/get-item-name-cache-2
Browse files Browse the repository at this point in the history
Item name and map action cache
  • Loading branch information
planqi authored Mar 17, 2020
2 parents 0ba3802 + 9d2f76b commit 5503716
Show file tree
Hide file tree
Showing 19 changed files with 484 additions and 59 deletions.
1 change: 1 addition & 0 deletions BH/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,5 @@ set(DRAWING_SOURCES "Drawing/Hook.cpp"

set(SOURCE_FILES ${SOURCE_FILES} ${MODULE_SOURCES} ${DRAWING_SOURCES})
add_library(BH ${SOURCE_FILES})
target_include_directories(BH PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/cpp-lru-cache/include)
target_link_libraries(BH ${STORM_LIBRARY} Shlwapi)
6 changes: 4 additions & 2 deletions BH/Common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,13 @@ int StringToNumber(std::string str) {
return ret;
}

// This function prints at most 151 characters (152 including null)
// TODO: Fix this so this limitation
void PrintText(DWORD Color, char *szText, ...) {
char szBuffer[152] = {0};
va_list Args;
va_start(Args, szText);
vsprintf_s(szBuffer, 152, szText, Args);
vsnprintf_s(szBuffer, 152, _TRUNCATE, szText, Args);
va_end(Args);
wchar_t Buffer[0x130];
MultiByteToWideChar(CODE_PAGE, 1, szBuffer, 152, Buffer, 304);
Expand Down Expand Up @@ -461,4 +463,4 @@ char *commaprint(unsigned long n)
} while (n != 0);

return p;
}
}
14 changes: 9 additions & 5 deletions BH/Drawing/UI/UI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,10 @@ void UI::OnDraw() {
}
}

void UI::SetDragged(bool state) {
void UI::SetDragged(bool state, bool write_file) {
Lock();
dragged = state;
if (!state) {
if (!state && write_file) {
WritePrivateProfileString(name.c_str(), "X", to_string<unsigned int>(GetX()).c_str(), string(BH::path + "UI.ini").c_str());
WritePrivateProfileString(name.c_str(), "Y", to_string<unsigned int>(GetY()).c_str(), string(BH::path + "UI.ini").c_str());
WritePrivateProfileString(name.c_str(), "minimizedX", to_string<unsigned int>(GetMinimizedX()).c_str(), string(BH::path + "UI.ini").c_str());
Expand All @@ -186,6 +186,10 @@ void UI::SetDragged(bool state) {
Unlock();
}

void UI::SetDragged(bool state) {
SetDragged(state, false);
}

void UI::SetMinimized(bool newState) {
if (newState == minimized)
return;
Expand Down Expand Up @@ -228,7 +232,7 @@ bool UI::OnLeftClick(bool up, unsigned int mouseX, unsigned int mouseY) {
}
else
{
SetDragged(false);
SetDragged(false, true);
if(!up) {
PrintText(7, "CTRL-click to open settings" );
PrintText(7, "Shift-drag to move" );
Expand All @@ -248,7 +252,7 @@ bool UI::OnLeftClick(bool up, unsigned int mouseX, unsigned int mouseY) {
}
else
{
SetDragged(false);
SetDragged(false, true);
if( startX == mouseX && startY == mouseY && GetAsyncKeyState(VK_CONTROL) )
{
PrintText(135, "Right Click to Close" );
Expand All @@ -271,7 +275,7 @@ bool UI::OnLeftClick(bool up, unsigned int mouseX, unsigned int mouseY) {
return true;
}
SetActive(false);
SetDragged(false);
SetDragged(false, false);
return false;
}

Expand Down
3 changes: 2 additions & 1 deletion BH/Drawing/UI/UI.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ namespace Drawing {
void SetActive(bool newState) { Lock(); active = newState; Unlock(); };
void SetMinimized(bool newState);
void SetName(std::string newName) { Lock(); name = newName; Unlock(); };
void SetDragged(bool state);
void SetDragged(bool state, bool write_file); // only write config to file if write_file is true
void SetDragged(bool state); // never writes the config file
void SetZOrder(unsigned int newZ) { Lock(); zOrder = newZ; Unlock(); };

UITab* GetActiveTab() { if (!currentTab) { currentTab = (*Tabs.begin()); } return currentTab; };
Expand Down
8 changes: 8 additions & 0 deletions BH/Modules/Item/Item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include "../../D2Stubs.h"
#include "ItemDisplay.h"
#include "../../MPQInit.h"
#include "lrucache.hpp"

ItemsTxtStat* GetAllStatModifier(ItemsTxtStat* pStats, int nStats, int nStat, ItemsTxtStat* pOrigin);
ItemsTxtStat* GetItemsTxtStatByMod(ItemsTxtStat* pStats, int nStats, int nStat, int nStatParam);
Expand Down Expand Up @@ -86,6 +87,13 @@ void Item::OnLoad() {
DrawSettings();
}

void Item::OnGameJoin() {
// reset the item name cache upon joining games
// (GUIDs not unique across games)
item_name_cache.ResetCache();
map_action_cache.ResetCache();
}

void Item::LoadConfig() {
BH::config->ReadToggle("Show Ethereal", "None", true, Toggles["Show Ethereal"]);
BH::config->ReadToggle("Show Sockets", "None", true, Toggles["Show Sockets"]);
Expand Down
2 changes: 2 additions & 0 deletions BH/Modules/Item/Item.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ class Item : public Module {
void LoadConfig();
void DrawSettings();

void OnGameJoin();

void OnLoop();
void OnKey(bool up, BYTE key, LPARAM lParam, bool* block);
void OnLeftClick(bool up, int x, int y, bool* block);
Expand Down
50 changes: 47 additions & 3 deletions BH/Modules/Item/ItemDisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,15 +151,55 @@ BYTE RuneNumberFromItemCode(char *code){
return (BYTE)(((code[1] - '0') * 10) + code[2] - '0');
}

void GetItemName(UnitItemInfo *uInfo, string &name) {
for (vector<Rule*>::iterator it = RuleList.begin(); it != RuleList.end(); it++) {
// Find the item name. This code is called only when there's a cache miss
string ItemNameLookupCache::make_cached_T(UnitItemInfo *uInfo, const string &name) {
string new_name(name);
for (vector<Rule*>::const_iterator it = RuleList.begin(); it != RuleList.end(); it++) {
if ((*it)->Evaluate(uInfo, NULL)) {
SubstituteNameVariables(uInfo, name, &(*it)->action);
SubstituteNameVariables(uInfo, new_name, &(*it)->action);
if ((*it)->action.stopProcessing) {
break;
}
}
}
return new_name;
}

string ItemNameLookupCache::to_str(const string &name) {
size_t start_pos = 0;
std::string itemName(name);
while ((start_pos = itemName.find('\n', start_pos)) != std::string::npos) {
itemName.replace(start_pos, 1, " - ");
start_pos += 3;
}
return itemName;
}

vector<Action> MapActionLookupCache::make_cached_T(UnitItemInfo *uInfo) {
vector<Action> actions;
for (vector<Rule*>::const_iterator it = RuleList.begin(); it != RuleList.end(); it++) {
if ((*it)->Evaluate(uInfo, NULL)) {
actions.push_back((*it)->action);
}
}
return actions;
}

string MapActionLookupCache::to_str(const vector<Action> &actions) {
string name;
for (auto &action : actions) {
name += action.name + " ";
}
return name;
}

// least recently used cache for storing a limited number of item names
ItemNameLookupCache item_name_cache(RuleList);
MapActionLookupCache map_action_cache(MapRuleList);

void GetItemName(UnitItemInfo *uInfo, string &name) {
string new_name = item_name_cache.Get(uInfo, name);
name.assign(new_name);
}

void SubstituteNameVariables(UnitItemInfo *uInfo, string &name, Action *action) {
Expand Down Expand Up @@ -333,6 +373,8 @@ namespace ItemDisplay {

item_display_initialized = true;
rules.clear();
item_name_cache.ResetCache();
map_action_cache.ResetCache();
BH::config->ReadMapList("ItemDisplay", rules);
for (unsigned int i = 0; i < rules.size(); i++) {
string buf;
Expand Down Expand Up @@ -365,6 +407,8 @@ namespace ItemDisplay {

void UninitializeItemRules() {
item_display_initialized = false;
item_name_cache.ResetCache();
map_action_cache.ResetCache();
RuleList.clear();
MapRuleList.clear();
IgnoreRuleList.clear();
Expand Down
17 changes: 17 additions & 0 deletions BH/Modules/Item/ItemDisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "../../BH.h"
#include <cstdlib>
#include <regex>
#include "../../RuleLookupCache.h"

#define EXCEPTION_INVALID_STAT 1
#define EXCEPTION_INVALID_OPERATION 2
Expand Down Expand Up @@ -576,10 +577,26 @@ struct Rule {
}
};

class ItemNameLookupCache : public RuleLookupCache<string, const string &> {
string make_cached_T(UnitItemInfo *uInfo, const string &name) override;
string to_str(const string &name) override;

using RuleLookupCache::RuleLookupCache;
};

class MapActionLookupCache : public RuleLookupCache<vector<Action>> {
vector<Action> make_cached_T(UnitItemInfo *uInfo) override;
string to_str(const vector<Action> &actions);

using RuleLookupCache::RuleLookupCache;
};

extern vector<Rule*> RuleList;
extern vector<Rule*> MapRuleList;
extern vector<Rule*> IgnoreRuleList;
extern vector<pair<string, string>> rules;
extern ItemNameLookupCache item_name_cache;
extern MapActionLookupCache map_action_cache;

namespace ItemDisplay {
void InitializeItemRules();
Expand Down
93 changes: 46 additions & 47 deletions BH/Modules/Maphack/Maphack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,18 @@ void Maphack::ReadConfig() {
BH::config->ReadAssoc("Missile Color", missileColors);
BH::config->ReadAssoc("Monster Color", monsterColors);

TextColorMap["ÿc0"] = 0x20; // white
TextColorMap["ÿc1"] = 0x0A; // red
TextColorMap["ÿc2"] = 0x84; // green
TextColorMap["ÿc3"] = 0x97; // blue
TextColorMap["ÿc4"] = 0x0D; // gold
TextColorMap["ÿc5"] = 0xD0; // gray
TextColorMap["ÿc6"] = 0x00; // black
TextColorMap["ÿc7"] = 0x5A; // tan
TextColorMap["ÿc8"] = 0x60; // orange
TextColorMap["ÿc9"] = 0x0C; // yellow
TextColorMap["ÿc;"] = 0x9B; // purple
TextColorMap["ÿc:"] = 0x76; // dark green
TextColorMap["ÿc0"] = 0x20; // white
TextColorMap["ÿc1"] = 0x0A; // red
TextColorMap["ÿc2"] = 0x84; // green
TextColorMap["ÿc3"] = 0x97; // blue
TextColorMap["ÿc4"] = 0x0D; // gold
TextColorMap["ÿc5"] = 0xD0; // gray
TextColorMap["ÿc6"] = 0x00; // black
TextColorMap["ÿc7"] = 0x5A; // tan
TextColorMap["ÿc8"] = 0x60; // orange
TextColorMap["ÿc9"] = 0x0C; // yellow
TextColorMap["ÿc;"] = 0x9B; // purple
TextColorMap["ÿc:"] = 0x76; // dark green

BH::config->ReadAssoc("Monster Color", MonsterColors);
for (auto it = MonsterColors.cbegin(); it != MonsterColors.cend(); it++) {
Expand Down Expand Up @@ -418,8 +418,8 @@ void Maphack::OnAutomapDraw() {
}

//Determine immunities
string szImmunities[] = { "ÿc7i", "ÿc8i", "ÿc1i", "ÿc9i", "ÿc3i", "ÿc2i" };
string szResistances[] = { "ÿc7r", "ÿc8r", "ÿc1r", "ÿc9r", "ÿc3r", "ÿc2r" };
string szImmunities[] = { "ÿc7i", "ÿc8i", "ÿc1i", "ÿc9i", "ÿc3i", "ÿc2i" };
string szResistances[] = { "ÿc7r", "ÿc8r", "ÿc1r", "ÿc9r", "ÿc3r", "ÿc2r" };
DWORD dwImmunities[] = {
STAT_DMGREDUCTIONPCT,
STAT_MAGICDMGREDUCTIONPCT,
Expand All @@ -442,7 +442,7 @@ void Maphack::OnAutomapDraw() {
//Determine Enchantments
string enchantText;
if (Toggles["Monster Enchantments"].state) {
string szEnchantments[] = {"ÿc3m", "ÿc1e", "ÿc9e", "ÿc3e"};
string szEnchantments[] = {"ÿc3m", "ÿc1e", "ÿc9e", "ÿc3e"};

for (int n = 0; n < 9; n++) {
if (unit->pMonsterData->fBoss) {
Expand Down Expand Up @@ -512,33 +512,32 @@ void Maphack::OnAutomapDraw() {
uInfo.itemCode[3] = 0;
if (ItemAttributeMap.find(uInfo.itemCode) != ItemAttributeMap.end()) {
uInfo.attrs = ItemAttributeMap[uInfo.itemCode];
for (vector<Rule*>::iterator it = MapRuleList.begin(); it != MapRuleList.end(); it++) {
if ((*it)->Evaluate(&uInfo, NULL)) {
auto color = (*it)->action.colorOnMap;
auto borderColor = (*it)->action.borderColor;
auto dotColor = (*it)->action.dotColor;
auto pxColor = (*it)->action.pxColor;
auto lineColor = (*it)->action.lineColor;
xPos = unit->pItemPath->dwPosX;
yPos = unit->pItemPath->dwPosY;
automapBuffer.push_top_layer(
[color, unit, xPos, yPos, MyPos, borderColor, dotColor, pxColor, lineColor]()->void{
POINT automapLoc;
Drawing::Hook::ScreenToAutomap(&automapLoc, xPos, yPos);
if (borderColor != UNDEFINED_COLOR)
Drawing::Boxhook::Draw(automapLoc.x - 4, automapLoc.y - 4, 8, 8, borderColor, Drawing::BTHighlight);
if (color != UNDEFINED_COLOR)
Drawing::Boxhook::Draw(automapLoc.x - 3, automapLoc.y - 3, 6, 6, color, Drawing::BTHighlight);
if (dotColor != UNDEFINED_COLOR)
Drawing::Boxhook::Draw(automapLoc.x - 2, automapLoc.y - 2, 4, 4, dotColor, Drawing::BTHighlight);
if (pxColor != UNDEFINED_COLOR)
Drawing::Boxhook::Draw(automapLoc.x - 1, automapLoc.y - 1, 2, 2, pxColor, Drawing::BTHighlight);
if (lineColor != UNDEFINED_COLOR) {
Drawing::Linehook::Draw(MyPos.x, MyPos.y, automapLoc.x, automapLoc.y, lineColor);
}
});
if ((*it)->action.stopProcessing) break;
}
const vector<Action> actions = map_action_cache.Get(&uInfo);
for (auto &action : actions) {
auto color = action.colorOnMap;
auto borderColor = action.borderColor;
auto dotColor = action.dotColor;
auto pxColor = action.pxColor;
auto lineColor = action.lineColor;
xPos = unit->pItemPath->dwPosX;
yPos = unit->pItemPath->dwPosY;
automapBuffer.push_top_layer(
[color, unit, xPos, yPos, MyPos, borderColor, dotColor, pxColor, lineColor]()->void{
POINT automapLoc;
Drawing::Hook::ScreenToAutomap(&automapLoc, xPos, yPos);
if (borderColor != UNDEFINED_COLOR)
Drawing::Boxhook::Draw(automapLoc.x - 4, automapLoc.y - 4, 8, 8, borderColor, Drawing::BTHighlight);
if (color != UNDEFINED_COLOR)
Drawing::Boxhook::Draw(automapLoc.x - 3, automapLoc.y - 3, 6, 6, color, Drawing::BTHighlight);
if (dotColor != UNDEFINED_COLOR)
Drawing::Boxhook::Draw(automapLoc.x - 2, automapLoc.y - 2, 4, 4, dotColor, Drawing::BTHighlight);
if (pxColor != UNDEFINED_COLOR)
Drawing::Boxhook::Draw(automapLoc.x - 1, automapLoc.y - 1, 2, 2, pxColor, Drawing::BTHighlight);
if (lineColor != UNDEFINED_COLOR) {
Drawing::Linehook::Draw(MyPos.x, MyPos.y, automapLoc.x, automapLoc.y, lineColor);
}
});
if (action.stopProcessing) break;
}
}
else {
Expand Down Expand Up @@ -577,7 +576,7 @@ void Maphack::OnAutomapDraw() {
return;
for (list<LevelList*>::iterator it = automapLevels.begin(); it != automapLevels.end(); it++) {
if (player->pAct->dwAct == (*it)->act) {
string tombStar = ((*it)->levelId == player->pAct->pMisc->dwStaffTombLevel) ? "ÿc2*" : "ÿc4";
string tombStar = ((*it)->levelId == player->pAct->pMisc->dwStaffTombLevel) ? "ÿc2*" : "ÿc4";
POINT unitLoc;
Hook::ScreenToAutomap(&unitLoc, (*it)->x, (*it)->y);
char* name = UnicodeToAnsi(D2CLIENT_GetLevelName((*it)->levelId));
Expand Down Expand Up @@ -661,13 +660,13 @@ void Maphack::OnGamePacketRecv(BYTE *packet, bool *block) {
// if(packet[6+(packet[0]-0xa7)] == 100) {
// UnitAny* pUnit = D2CLIENT_FindServerSideUnit(*(DWORD*)&packet[2], 0);
// if(pUnit)
// PrintText(1, "Alert: ÿc4Player ÿc2%s ÿc4drank a ÿc1Health ÿc4potion!", pUnit->pPlayerData->szName);
// PrintText(1, "Alert: ÿc4Player ÿc2%s ÿc4drank a ÿc1Health ÿc4potion!", pUnit->pPlayerData->szName);
// } else if (packet[6+(packet[0]-0xa7)] == 105) {
// UnitAny* pUnit = D2CLIENT_FindServerSideUnit(*(DWORD*)&packet[2], 0);
// if(pUnit)
// if(pUnit->dwTxtFileNo == 1)
// if(D2COMMON_GetUnitState(pUnit, 30))
// PrintText(1, "Alert: ÿc4ES Sorc ÿc2%s ÿc4drank a ÿc3Mana ÿc4Potion!", pUnit->pPlayerData->szName);
// PrintText(1, "Alert: ÿc4ES Sorc ÿc2%s ÿc4drank a ÿc3Mana ÿc4Potion!", pUnit->pPlayerData->szName);
// } else if (packet[6+(packet[0]-0xa7)] == 102) {//remove portal delay
// *block = true;
// }
Expand Down Expand Up @@ -928,8 +927,8 @@ int HoverObjectPatch(UnitAny* pUnit, DWORD tY, DWORD unk1, DWORD unk2, DWORD tX,
POINT p = Texthook::GetTextSize(wTxt, 1);
int center = tX + (p.x / 2);
int y = tY - p.y;
Texthook::Draw(center, y - 12, Center, 6, White, L"ÿc7%d ÿc8%d ÿc1%d ÿc9%d ÿc3%d ÿc2%d", dwResistances[0], dwResistances[1], dwResistances[2], dwResistances[3], dwResistances[4], dwResistances[5]);
Texthook::Draw(center, y, Center, 6, White, L"ÿc%d%s", HoverMonsterColor(pUnit), wTxt);
Texthook::Draw(center, y - 12, Center, 6, White, L"ÿc7%d ÿc8%d ÿc1%d ÿc9%d ÿc3%d ÿc2%d", dwResistances[0], dwResistances[1], dwResistances[2], dwResistances[3], dwResistances[4], dwResistances[5]);
Texthook::Draw(center, y, Center, 6, White, L"ÿc%d%s", HoverMonsterColor(pUnit), wTxt);
Texthook::Draw(center, y + 8, Center, 6, White, L"%.0f%%", (hp / maxhp) * 100.0);
return 1;
}
Expand Down
Loading

0 comments on commit 5503716

Please sign in to comment.