#include "WatchEXP.h" #include "CommandParse.h" WatchEXP::WatchEXP(void) : m_AshitaCore(nullptr) , m_PluginId(0) , m_Direct3DDevice(nullptr) , m_ExpObj(nullptr) , m_AbyTimeStart(0) , m_DynTimeStart(0) , m_BaseTimeEXP(0) , m_BaseTimeCR(0) , m_resetTime(NULL) , font_size(0) , m_reset_min(0) , m_CurrentZoneID(0) , m_LastZoneRecorded(0) , m_Dyna_Crm('X') , m_Dyna_Azr('X') , m_Dyna_Amb('X') , m_Dyna_Alab('X') , m_Dyna_Obs('X') , m_vTime(0) , m_DynaTime(0) , m_xpKill(0) , m_xpTotal(0) , m_xpTest(0) , m_crKill(0) , m_crTotal(0) , m_prl(0) , m_gld(0) , m_slv(0) , m_ebn(0) , m_azr(0) , m_rby(0) , m_amb(0) , backTrans(0) , m_IsInAbyssea(false) , m_IsInDynamis(false) , show_XP_M_always(false) , m_autoreset(false) { } WatchEXP::~WatchEXP(void) { } plugininfo_t WatchEXP::GetPluginInfo(void) { return *g_PluginInformation; } bool WatchEXP::Initialize(IAshitaCore* core, ILogManager* log, uint32_t id) { // Store the variables we are passed.. this->m_AshitaCore = core; this->m_PluginId = id; this->GetConfig(); return true; } void WatchEXP::Release(void) { } bool WatchEXP::HandleCommand(const char* pszCommand, int nCommandType) { if (pszCommand == nullptr) return false; if (_strnicmp(pszCommand, "/wexp", 4) == 0) { std::vector args; Ashita::Commands::GetCommandArgs(pszCommand, &args); if (args[1] == "reset") { m_crTotal = 0, m_xpTotal = 0, m_xpKill = 0, m_crKill = 0; m_BaseTimeEXP = time(nullptr), m_BaseTimeCR = time(nullptr); m_AshitaCore->GetChatManager()->Write("WatchEXP was reset!"); return true; } if (args[1] == "config") { this->GetConfig(); m_ExpObj->SetFontFamily(font_name); m_ExpObj->SetFontHeight(font_size); return true; } } return false; } //bool WatchEXP::HandleNewChatLine(short sMode, char* pszChatLine) bool WatchEXP::HandleIncomingText(int16_t sMode, const char* pszChatLine, int16_t* modifiedMode, char* modifiedMessage, bool blocked) { std::string data; std::vector< std::string > temp; data = ScrubChat(pszChatLine); //Holds matches std::smatch m; #pragma region Search Pattern //Regex Searches std::regex xp_inc("gains\\s\\d+\\s(experience|limit)\\spoints"); std::regex xp_chain("EXP\\schain\\s\\d+\\s\\w+\\sgains\\s\\d+\\sexperience\\spoints"); std::regex cru_inc("obtained\\s\\d+\\scruor", std::regex_constants::icase); std::regex vis_wear("Your\\svisitant\\sstatus\\swill\\swear\\soff\\sin\\s\\d+\\sminutes"); std::regex vis_inc("Your\\svisitant\\sstatus\\shas\\sbeen\\sextended\\sby\\s\\d+\\sminutes"); std::regex vis_exit("Exiting\\sin\\s\\d+\\sminutes"); std::regex vis_pegs("Visitant\\sLight\\sIntensity\\sPearlescent\\s\\d+\\sEbon\\s\\d+\\sGolden\\s\\d+\\sSilvery\\s\\d+"); std::regex vis_azram("Azure\\s\\d+\\sRuby\\s\\d+\\sAmber\\s\\d+"); std::regex light_pearl("body\\semits\\sa\\sfaint\\spearlescent\\slight"); std::regex light_azure("body\\semits\\sa\\sfeeble\\sazure\\slight"); std::regex light_ruby("body\\semits\\sa\\sfeeble\\sruby\\slight"); std::regex light_amber("body\\semits\\sa\\sfeeble\\samber\\slight"); std::regex light_gold("body\\semits\\sa\\sfaint\\sgolden\\slight"); std::regex light_silver("body\\semits\\sa\\sfaint\\ssilvery\\slight"); std::regex light_ebon("body\\semits\\sa\\sfaint\\sebon\\slight"); std::regex dyn_start("sands"); std::regex dyn_start2("hourglass"); std::regex dyn_extend("Dynamis"); std::regex dyn_extend2("extended"); std::regex dyn_expelled("expelled"); //Used to get all the numbers std::regex get_number("\\d+"); if (sMode == 121) { if (std::regex_search(data, xp_chain)) { std::sregex_token_iterator start(data.begin(), data.end(), get_number, 0), end; while (start != end) { temp.push_back(*start); ++start; } if (temp.size() >= 1) m_xpKill = std::stoi(temp[temp.size() - 1]); else m_xpKill = 0; m_xpTotal += m_xpKill; } } if (sMode == 131) { if (std::regex_search(data, xp_inc)) { std::sregex_token_iterator start(data.begin(), data.end(), get_number, 0), end; temp.clear(); while (start != end) { temp.push_back(*start); ++start; } if (temp.size() >= 1) m_xpKill = std::stoi(temp[temp.size() - 1]); else m_xpKill = 0; m_xpTotal += m_xpKill; } } else if (sMode == 633) { if (std::regex_search(data, cru_inc)) { std::sregex_token_iterator start(data.begin(), data.end(), get_number, 0), end; temp.clear(); while (start != end) { temp.push_back(*start); ++start; } if (temp.size() >= 1) m_crKill = std::stoi(temp[temp.size() - 1]); else m_crKill = 0; m_crTotal += m_crKill; } else if (std::regex_search(data, vis_inc)) { m_vTime += 10; } } else if (sMode == 653) { if ((std::regex_search(data, dyn_expelled)) && (std::regex_search(data, dyn_extend))) { std::regex_search(data, m, get_number); m_DynaTime = std::stoi(m.str()); m_DynTimeStart = time(nullptr); } } else if (sMode == 658) { if ((std::regex_search(data, dyn_extend)) && (std::regex_search(data, dyn_extend2))) { std::regex_search(data, m, get_number); m_DynaTime += std::stoi(m.str()); m_DynTimeStart = time(nullptr); } } else if (sMode == 660) { if ((std::regex_search(data, dyn_start)) && (std::regex_search(data, dyn_start2))) { std::regex_search(data, m, get_number); m_DynaTime = std::stoi(m.str()); } if (std::regex_search(data, vis_exit)) { std::regex_search(data, m, get_number); m_vTime = std::stoi(m.str()); } else if (std::regex_search(data, cru_inc)) { std::regex_search(data, m, get_number); m_crKill = std::stoi(m.str()); m_crTotal += m_crKill; } else if (std::regex_search(data, vis_wear)) { std::regex_search(data, m, get_number); m_vTime = std::stoi(m.str()); m_AbyTimeStart = time(nullptr); } else if (std::regex_search(data, vis_pegs)) { std::sregex_token_iterator start(data.begin(), data.end(), get_number, 0), end; while (start != end) { temp.push_back(*start); ++start; } //Corrects Pearlescent Values m_prl = std::stoi(temp[0]); //Corrects Ebon Values m_ebn = std::stoi(temp[1]); //Corrects Gold Values m_gld = std::stoi(temp[2]); //Corrects Silvery Values m_slv = std::stoi(temp[3]); } else if (std::regex_search(data, vis_azram)) { std::sregex_token_iterator start(data.begin(), data.end(), get_number, 0), end; while (start != end) { temp.push_back(*start); ++start; } //Corrects Azure Values m_azr = std::stoi(temp[0]); //Corrects Ruby Values m_rby = std::stoi(temp[1]); //Corrects Amber Values m_amb = std::stoi(temp[2]); } else if (std::regex_search(data, light_pearl)) { //checks to ensure value does not exceed 230 if (m_prl + 5 > 230) { m_prl = 230; } else { m_prl += 5; } } else if (std::regex_search(data, light_gold)) { //checks to ensure value does not exceed 200 if (m_gld + 5 > 200) { m_gld = 200; } else { m_gld += 5; } } else if (std::regex_search(data, light_silver)) { //checks to ensure value does not exceed 200 if (m_slv + 5 > 200) { m_slv = 200; } else { m_slv += 5; } } else if (std::regex_search(data, light_ebon)) { //checks to ensure value does not exceed 200 if (m_ebn + 1 > 200) { m_ebn = 200; } else { m_ebn += 1; } } else if (std::regex_search(data, light_azure)) { //checks to ensure value does not exceed 255 if (m_azr + 8 > 255) { m_azr = 255; } else { m_azr += 8; } } else if (std::regex_search(data, light_ruby)) { //checks to ensure value does not exceed 255 if (m_rby + 8 > 255) { m_rby = 255; } else { m_rby += 8; } } else if (std::regex_search(data, light_amber)) { //checks to ensure value does not exceed 255 if (m_amb + 8 > 255) { m_amb = 255; } else { m_amb += 8; } } } #pragma endregion return false; } bool WatchEXP::Direct3DInitialize(IDirect3DDevice8* lpDevice) { this->m_Direct3DDevice = lpDevice; m_ExpObj = m_AshitaCore->GetFontManager()->Create("EXP_ID"); m_ExpObj->SetText("0/0"); m_ExpObj->SetFontFamily(font_name); m_ExpObj->SetFontHeight(font_size); m_ExpObj->SetColor(0xFFFFFFFF); m_ExpObj->SetBold(false); m_ExpObj->SetVisibility(true); m_ExpObj->SetPositionX(100); m_ExpObj->SetPositionY(100); m_ExpObj->SetVisibility(false); m_ExpObj->GetBackground()->SetVisibility(true); m_ExpObj->GetBackground()->SetColor(0x80000000); m_BaseTimeEXP = time(nullptr); m_BaseTimeCR = time(nullptr); return true; } void WatchEXP::Direct3DRelease(void) { m_AshitaCore->GetFontManager()->Delete("EXP_ID"); } void WatchEXP::Direct3DRender(void) { doEXPCalculations(); doAbysseaZoneTimings(); doDynamisZoneTimings(); checkResetTime(); } __declspec(dllexport) double __stdcall GetInterfaceVersion(void) { return ASHITA_INTERFACE_VERSION; } __declspec(dllexport) void __stdcall CreatePluginInfo(plugininfo_t* info) { g_PluginInformation = info; strcpy_s(info->Author, sizeof(info->Author), "Praenuntiae (ported by Vicrelant)"); strcpy_s(info->Name, sizeof(info->Name), "WatchEXP"); info->InterfaceVersion = ASHITA_INTERFACE_VERSION; info->PluginVersion = 3.0f; info->Priority = 0; } __declspec(dllexport) IPlugin* __stdcall CreatePlugin(void) { return (IPlugin*)new WatchEXP(); } #pragma region GetConfig void WatchEXP::GetConfig() { auto iConfigResult = false; auto iTemp = 0; iConfigResult = m_AshitaCore->GetConfigurationManager()->Load("WatchEXP", "WatchEXP"); if (iConfigResult != 0) { auto szBuffer = m_AshitaCore->GetConfigurationManager()->get_string("WatchEXP", "font_name"); strcpy_s(font_name, szBuffer); font_size = m_AshitaCore->GetConfigurationManager()->get_int32("WatchEXP", "font_size", 11); show_XP_M_always = m_AshitaCore->GetConfigurationManager()->get_bool("WatchEXP", "show_both_xp_and_merits_when_capped", false); m_reset_min = m_AshitaCore->GetConfigurationManager()->get_int32("WatchEXP", "auto_reset_time", 45); m_autoreset = m_AshitaCore->GetConfigurationManager()->get_bool("WatchEXP", "auto_reset_enabled", false); } else if (iConfigResult == 0) { m_AshitaCore->GetConfigurationManager()->set_value("WatchEXP", "font_name", "Arial"); m_AshitaCore->GetConfigurationManager()->set_value("WatchEXP", "font_size", "11"); m_AshitaCore->GetConfigurationManager()->set_value("WatchEXP", "show_both_xp_and_merits_when_capped", "true"); m_AshitaCore->GetConfigurationManager()->set_value("WatchEXP", "auto_reset_time", "45"); m_AshitaCore->GetConfigurationManager()->set_value("WatchEXP", "auto_reset_enabled", "false"); m_AshitaCore->GetConfigurationManager()->Save("WatchEXP", "WatchEXP"); strcpy_s(font_name, "Arial"); font_size = 11; show_XP_M_always = false; m_reset_min = 45; m_autoreset = false; } } #pragma endregion #pragma region doEXPCalculations void WatchEXP::doEXPCalculations() { char *p; char expIntoLVL[10] = "", expForLVL[10] = "", expTillLVL[10] = "", lmtIntoLVL[10] = "", lmtTillLVL[10] = "", xpTotal[40] = "", crTotal[40] = ""; m_IsInAbyssea = isInAbyssea(m_AshitaCore->GetDataManager()->GetParty()->GetMemberZone(0)); m_IsInDynamis = isInDynamis(m_AshitaCore->GetDataManager()->GetParty()->GetMemberZone(0)); // get the EXP info unsigned short expIN = m_AshitaCore->GetDataManager()->GetPlayer()->GetExpCurrent(); unsigned short expMAX = m_AshitaCore->GetDataManager()->GetPlayer()->GetExpNeeded(); unsigned short expLEFT = expMAX - expIN; // get the Merit info unsigned short lmtIN = m_AshitaCore->GetDataManager()->GetPlayer()->GetLimitPoints(); unsigned short lmtMAX = 10000; unsigned short lmtLEFT = lmtMAX - lmtIN; p = expIntoLVL; makeComma(expIN, p, 0); _strrev(expIntoLVL); p = expForLVL; makeComma(expMAX, p, 0); _strrev(expForLVL); p = expTillLVL; makeComma(expLEFT, p, 0); _strrev(expTillLVL); p = lmtIntoLVL; makeComma(lmtIN, p, 0); _strrev(lmtIntoLVL); p = lmtTillLVL; makeComma(lmtLEFT, p, 0); _strrev(lmtTillLVL); p = xpTotal; makeComma(m_xpTotal, p, 0); _strrev(xpTotal); p = crTotal; makeComma(m_crTotal, p, 0); _strrev(crTotal); if (m_AshitaCore->GetDataManager()->GetPlayer()->GetMainJobLevel() < 75) { if (m_IsInDynamis) { sprintf_s(TextObjectBuffer, MAX_PATH, " %s/%s(%s) XP:%s(%u) %.1fk/hr Alb:%c Amb:%c Azr:%c Crm:%c Obn:%c Time Remaining: %d ", expIntoLVL, expForLVL, expTillLVL, xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal), m_Dyna_Alab, m_Dyna_Amb, m_Dyna_Azr, m_Dyna_Crm, m_Dyna_Obs, m_DynaTime); } else if (m_IsInAbyssea) { sprintf_s(TextObjectBuffer, MAX_PATH, " %s/%s(%s) XP:%s(%u) %.1fk/hr Cruor:%s(%u) %.1fk/hr Prl:%u Gld:%u Slv:%u Ebn:%u Azr:%u Rby:%u Amb:%u V.Time: %d ", expIntoLVL, expForLVL, expTillLVL, xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal), crTotal, m_crKill, returnProjectedCRUORperHour(m_crTotal), m_prl, m_gld, m_slv, m_ebn, m_azr, m_rby, m_amb, m_vTime); } else { sprintf_s(TextObjectBuffer, MAX_PATH, " %s/%s(%s) XP:%s(%u) %.1fk/hr ", expIntoLVL, expForLVL, expTillLVL, xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal)); } } if ((!show_XP_M_always) && (m_AshitaCore->GetDataManager()->GetPlayer()->GetMainJobLevel() >= 75)) { unsigned char isMeritMode = m_AshitaCore->GetDataManager()->GetPlayer()->GetLimitMode(); if ((expLEFT == 1) || (isMeritMode == 224)) { if (m_IsInDynamis) { sprintf_s(TextObjectBuffer, MAX_PATH, " %s/10,000(%s)[%i] XP:%s(%u) %.1fk/hr Alb:%c Amb:%c Azr:%c Crm:%c Obn:%c Time Remaining: %d ", lmtIntoLVL, lmtTillLVL, (int)m_AshitaCore->GetDataManager()->GetPlayer()->GetMeritPoints(), xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal), m_Dyna_Alab, m_Dyna_Amb, m_Dyna_Azr, m_Dyna_Crm, m_Dyna_Obs, m_DynaTime); } else if (m_IsInAbyssea) { sprintf_s(TextObjectBuffer, MAX_PATH, " %s/10,000(%s)[%i] XP:%s(%u) %.1fk/hr Cruor:%s(%u) %.1fk/hr Prl:%u Gld:%u Slv:%u Ebn:%u Azr:%u Rby:%u Amb:%u V.Time: %d ", lmtIntoLVL, lmtTillLVL, (int)m_AshitaCore->GetDataManager()->GetPlayer()->GetMeritPoints(), xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal), crTotal, m_crKill, returnProjectedCRUORperHour(m_crTotal), m_prl, m_gld, m_slv, m_ebn, m_azr, m_rby, m_amb, m_vTime); } else { sprintf_s(TextObjectBuffer, MAX_PATH, " %s/10,000(%s)[%i] XP:%s(%u) %.1fk/hr ", lmtIntoLVL, lmtTillLVL, (int)m_AshitaCore->GetDataManager()->GetPlayer()->GetMeritPoints(), xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal)); } } else { if (m_IsInDynamis) { sprintf_s(TextObjectBuffer, MAX_PATH, " %s/%s(%s) XP:%s(%u) %.1fk/hr Alb:%c Amb:%c Azr:%c Crm:%c Obn:%c Time Remaining: %d ", expIntoLVL, expForLVL, expTillLVL, xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal), m_Dyna_Alab, m_Dyna_Amb, m_Dyna_Azr, m_Dyna_Crm, m_Dyna_Obs, m_DynaTime); } else if (m_IsInAbyssea) { sprintf_s(TextObjectBuffer, MAX_PATH, " %s/%s(%s) XP:%s(%u) %.1fk/hr Cruor:%s(%u) %.1fk/hr Prl:%u Gld:%u Slv:%u Ebn:%u Azr:%u Rby:%u Amb:%u V.Time: %d ", expIntoLVL, expForLVL, expTillLVL, xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal), crTotal, m_crKill, returnProjectedCRUORperHour(m_crTotal), m_prl, m_gld, m_slv, m_ebn, m_azr, m_rby, m_amb, m_vTime); } else { sprintf_s(TextObjectBuffer, MAX_PATH, " %s/%s(%s) XP:%s(%u) %.1fk/hr ", expIntoLVL, expForLVL, expTillLVL, xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal)); } } } if ((show_XP_M_always) && (m_AshitaCore->GetDataManager()->GetPlayer()->GetMainJobLevel() >= 75)) { if (m_IsInDynamis) { sprintf_s(TextObjectBuffer, MAX_PATH, " %s/%s(%s) %s/10,000(%s)[%i] XP:%s(%u) %.1fk/hr Alb:%c Amb:%c Azr:%c Crm:%c Obn:%c Time Remaining: %d ", expIntoLVL, expForLVL, expTillLVL, lmtIntoLVL, lmtTillLVL, (int)m_AshitaCore->GetDataManager()->GetPlayer()->GetMeritPoints(), xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal), m_Dyna_Alab, m_Dyna_Amb, m_Dyna_Azr, m_Dyna_Crm, m_Dyna_Obs, m_DynaTime); } else if (m_IsInAbyssea) { sprintf_s(TextObjectBuffer, MAX_PATH, " %s/%s(%s) %s/10,000(%s)[%i] XP:%s(%u) %.1fk/hr Cruor:%s(%u) %.1fk/hr Prl:%u Gld:%u Slv:%u Ebn:%u Azr:%u Rby:%u Amb:%u V.Time: %d ", expIntoLVL, expForLVL, expTillLVL, lmtIntoLVL, lmtTillLVL, (int)m_AshitaCore->GetDataManager()->GetPlayer()->GetMeritPoints(), xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal), crTotal, m_crKill, returnProjectedCRUORperHour(m_crTotal), m_prl, m_gld, m_slv, m_ebn, m_azr, m_rby, m_amb, m_vTime); } else { sprintf_s(TextObjectBuffer, MAX_PATH, " %s/%s(%s) %s/10,000(%s)[%i] XP:%s(%u) %.1fk/hr ", expIntoLVL, expForLVL, expTillLVL, lmtIntoLVL, lmtTillLVL, (int)m_AshitaCore->GetDataManager()->GetPlayer()->GetMeritPoints(), xpTotal, m_xpKill, returnProjectedEXPperHour(m_xpTotal)); } } // double check the size of the text if (m_ExpObjSize.cy == 0) { int window_y = m_AshitaCore->GetConfigurationManager()->get_int32("boot_config", "window_y", 600); m_ExpObj->GetTextSize(&m_ExpObjSize); m_ExpObj->SetPositionX(15.0f); m_ExpObj->SetPositionY((float)(window_y - m_ExpObjSize.cy)); } // set the object information m_ExpObj->SetText(TextObjectBuffer); m_ExpObj->SetVisibility(true); } #pragma endregion #pragma region returnProjectedEXPperHour float WatchEXP::returnProjectedEXPperHour(unsigned int expIntoLevel) { float changeInTime = (float(time(nullptr) - m_BaseTimeEXP)); float changeInTimeHR = ((changeInTime / 60) / 60); if (expIntoLevel == 0) { m_BaseTimeEXP = time(nullptr); } // just in case we don't do a divide by zero if (changeInTime == 0.0f) { return 0; } return ((((float)expIntoLevel) / changeInTimeHR) / 1000); } #pragma endregion #pragma region returnProjectedCRUORperHour float WatchEXP::returnProjectedCRUORperHour(unsigned int cruorLVL) { float changeInTime = (float(time(nullptr) - m_BaseTimeCR)); float changeInTimeHR = ((changeInTime / 60) / 60); if (cruorLVL == 0) { m_BaseTimeCR = time(nullptr); } // just in case we don't do a divide by zero if (changeInTime == 0.0f) { return 0; } return ((((float)cruorLVL) / changeInTimeHR) / 1000); } #pragma endregion #pragma region isInAbyssea bool WatchEXP::isInAbyssea(int zoneID) { // look for it for (auto& x : AbysseaZoneIDs) { // Yes! if (x == zoneID) return true; } m_prl = 0, m_gld = 0, m_amb = 0, m_slv = 0, m_azr = 0, m_ebn = 0, m_rby = 0, m_vTime = 0; return false; } #pragma endregion #pragma region isInDynamis bool WatchEXP::isInDynamis(int zoneID) { // look for it for (auto& x : DynamisZoneIDs) { // Yes! if (x == zoneID) return true; } m_Dyna_Crm = 'X', m_Dyna_Azr = 'X', m_Dyna_Alab = 'X', m_Dyna_Amb = 'X', m_Dyna_Obs = 'X'; // Nope return false; } #pragma endregion #pragma region doAbysseaZoneTimings void WatchEXP::doAbysseaZoneTimings() { // check to see if we are in Abyssea m_IsInAbyssea = isInAbyssea(m_AshitaCore->GetDataManager()->GetParty()->GetMemberZone(0)); if (m_IsInAbyssea && (time(nullptr) - m_AbyTimeStart) > 60) { m_AbyTimeStart = time(nullptr); if (m_vTime != 0) { m_vTime -= 1; } } } #pragma endregion #pragma region doDynamisZoneTimings void WatchEXP::doDynamisZoneTimings() { // check to see if we are in Abyssea m_IsInDynamis = isInDynamis(m_AshitaCore->GetDataManager()->GetParty()->GetMemberZone(0)); doDynamisKItemCheck(); if (m_IsInDynamis && (time(nullptr) - m_DynTimeStart) > 60) { m_DynTimeStart = time(nullptr); if (m_DynaTime != 0) { m_DynaTime -= 1; } } } #pragma endregion #pragma region doDynamisKItemCheck void WatchEXP::doDynamisKItemCheck() { //Checks for Crimson Granule of Time if (m_AshitaCore->GetDataManager()->GetPlayer()->HasKeyItem(1545)) { m_Dyna_Crm = 'O'; } //Checks for Azure Granule of Time if (m_AshitaCore->GetDataManager()->GetPlayer()->HasKeyItem(1546)) { m_Dyna_Azr = 'O'; } //Checks for Amber Granule of Time if (m_AshitaCore->GetDataManager()->GetPlayer()->HasKeyItem(1547)) { m_Dyna_Amb = 'O'; } //Checks for Alabaster Granule of Time if (m_AshitaCore->GetDataManager()->GetPlayer()->HasKeyItem(1548)) { m_Dyna_Alab = 'O'; } //Checks for Obsidian Granule of Time if (m_AshitaCore->GetDataManager()->GetPlayer()->HasKeyItem(1549)) { m_Dyna_Obs = 'O'; } } #pragma endregion #pragma region makeComma void WatchEXP::makeComma(int n, char *p, int count) { int d; // Get least significant digit d = n % 10; // Convert to ascii character and store *p++ = d + '0'; // Remove least significant digit // Test for finished if (n /= 10) { // Not finished, increase digit count, // test for comma position count++; if (count >= 3) { // Add the comma and reset the count *p++ = ','; count = 0; } // Call this procedure to work on // remaining part of number makeComma(n, p, count); } return; } #pragma endregion #pragma region convertFromHex int WatchEXP::convertFromHex(std::string hex) { int value = 0; int a = 0; int b = hex.length() - 1; for (; b >= 0; a++, b--) { if (hex[b] >= '0' && hex[b] <= '9') { value += (hex[b] - '0') * (1 << (a * 4)); } else { switch (hex[b]) { case 'A': case 'a': value += 10 * (1 << (a * 4)); break; case 'B': case 'b': value += 11 * (1 << (a * 4)); break; case 'C': case 'c': value += 12 * (1 << (a * 4)); break; case 'D': case 'd': value += 13 * (1 << (a * 4)); break; case 'E': case 'e': value += 14 * (1 << (a * 4)); break; case 'F': case 'f': value += 15 * (1 << (a * 4)); break; default: break; } } } return value; } #pragma endregion #pragma region hextodec void WatchEXP::hextodec(std::string hex, std::vector& rgb) { std::string redString, greenString, blueString; if (hex.compare(0, 1, "#") == 0) { //If the prefix # was attached to hex, use the following code redString = hex.substr(1, 2); greenString = hex.substr(3, 2); blueString = hex.substr(5, 2); } else if (hex.compare(0, 2, "0x") == 0) { //If the prefix 0x was attached to hex, use the following code redString = hex.substr(2, 2); greenString = hex.substr(4, 2); blueString = hex.substr(6, 2); } else { //If there is no prefix attached to hex, use this code redString = hex.substr(0, 2); greenString = hex.substr(2, 2); blueString = hex.substr(4, 2); } unsigned char red = (unsigned char)(convertFromHex(redString)); unsigned char green = (unsigned char)(convertFromHex(greenString)); unsigned char blue = (unsigned char)(convertFromHex(blueString)); rgb[0] = red; rgb[1] = green; rgb[2] = blue; } #pragma endregion #pragma region convertTrans void WatchEXP::convertTrans(unsigned char& trans) { float temp1, temp2; temp1 = (float)trans; temp2 = temp1 * (float)2.55; if (temp2 > 255) { trans = (unsigned char)255; } else { trans = (unsigned char)temp2; } } #pragma endregion #pragma region checkResetTime void WatchEXP::checkResetTime() { if (time(nullptr) - m_resetTime > 60) { if (m_xpTest != m_xpTotal) { m_xpTest = m_xpTotal; m_resetTime = time(nullptr); } else if ((m_xpTest == m_xpTotal) && (m_autoreset)) { if (((time(nullptr) - m_resetTime) / 60) >= m_reset_min) { m_resetTime = time(nullptr); m_crTotal = 0, m_xpTotal = 0, m_xpKill = 0, m_crKill = 0; } } } } #pragma endregion #pragma region ScrubChat std::string WatchEXP::ScrubChat(const char* chat_line) { //strings to hold the chat data through the various scrubbing stages std::string chat_raw; std::string clean_chat_pass1; std::string clean_chat_pass2; std::string clean_chat_pass3; std::string clean_chat_final; char szClean[1024]; //regex expressions for parsing the raw chat until it's clean std::regex parse1("\\x1E\\x05|\\x1E(\\x03|\\x02|\\x01)|\\x7F\\x31|\\x1F(\\x79|\\x7F|\\x7B|\\W)"); std::regex parse2("[[:cntrl:]]|\\W\\W"); std::regex time_stamp("\\x1E\\x03((\\[\\d+(:|/)\\d+(:|/)\\d+(\\]| [AMP]+\\]))|\\[\\d+(:|/)\\d+(:|/)\\d+ - \\d+:\\d+:\\d+(\\]| [AMP]+\\]))\\x1E\\x01\\s+"); std::regex multi_space("\\s+"); memset(szClean, 0, 1024); //Cleans up any auto translate data so it can be properly parsed m_AshitaCore->GetChatManager()->ParseAutoTranslate(chat_line, szClean, 1024, false); chat_raw = chat_line; //Removes TimeStamp data from beginning of line std::regex_replace(std::back_inserter(clean_chat_pass1), chat_raw.begin(), chat_raw.end(), time_stamp, ""); //Removes some control characters from the beginning and end of the string that print as garbage std::regex_replace(std::back_inserter(clean_chat_pass2), clean_chat_pass1.begin(), clean_chat_pass1.end(), parse1, ""); //Removes any remaining control characters and replaces them with spaces std::regex_replace(std::back_inserter(clean_chat_pass3), clean_chat_pass2.begin(), clean_chat_pass2.end(), parse2, " "); //Changes any multi space areas to single spaces std::regex_replace(std::back_inserter(clean_chat_final), clean_chat_pass3.begin(), clean_chat_pass3.end(), multi_space, " "); return clean_chat_final; } #pragma endregion