Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Item name and map action cache #40

Merged
merged 31 commits into from
Mar 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
afced0b
Initial commit
lamerman Jun 20, 2013
a494e92
Initial commit
Jun 20, 2013
faac6a8
Update README.md
lamerman Jun 21, 2013
6942a00
Exception is thrown when element is not found in the cache
Jun 21, 2013
9cbdff8
Executable deleted from repository (uploaded by mistake)
lamerman Oct 25, 2013
484e412
License added
lamerman Feb 26, 2015
6d1ec39
Google testing framework added. Tests refactored
Jun 25, 2015
f9ef239
Merge pull request #7 from lamerman/better-tests
lamerman Jun 25, 2015
190a960
Update README.md
lamerman Jun 25, 2015
1ad7b09
Travis config added
Jun 25, 2015
dc0db57
Merge pull request #8 from lamerman/travis-ci
lamerman Jun 25, 2015
734802a
Fix use after free
assafnativ May 4, 2016
68bfdfe
Merge pull request #12 from assafnativ/nativ/fix_use_after_free
lamerman May 16, 2016
01b513a
Fix tests
lamerman Aug 21, 2016
55b6b15
Merge pull request #14 from lamerman/fix-tests
lamerman Aug 21, 2016
9724c2d
Fix redeclared as different kind of symbol issue
lamerman Aug 21, 2016
9e71725
Merge pull request #15 from lamerman/tests-names-fix
lamerman Aug 21, 2016
24ba9a3
Fix wrong namespace name in comment
kainjow May 22, 2017
de1c4a0
Merge pull request #20 from kainjow/patch-1
lamerman May 23, 2017
99af823
Fix bug that caused UI.ini file to be written each time the mouse was…
youbetterdont Mar 7, 2020
d774da7
fixed mistake in cmake command in readme
youbetterdont Mar 8, 2020
1f9346e
Add 'ThirdParty/cpp-lru-cache/' from commit 'de1c4a03569bf3bd540e7f55…
youbetterdont Mar 8, 2020
5888bd6
* Item name cache implemented. Item names are looked up from cache wh…
youbetterdont Mar 8, 2020
4936acd
Refactored the caching code. Should be much easier to insert it other…
youbetterdont Mar 11, 2020
917fec6
Removed some commented code. Reset Cache on initialize/uninitialize r…
youbetterdont Mar 12, 2020
2998122
Switched to using flags to detect when to trigger cache updates.
youbetterdont Mar 12, 2020
839e2fc
Added map action lookup cache for items on automap.
youbetterdont Mar 12, 2020
d26eb75
Disabled debug printing
youbetterdont Mar 12, 2020
5cfda08
Increased cache size to 100
youbetterdont Mar 13, 2020
59acf33
Merge branch 'master' into feature/get-item-name-cache-2
planqi Mar 17, 2020
9d2f76b
the iterator is gone
planqi Mar 17, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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