atom0s
8 years ago
7 changed files with 1318 additions and 0 deletions
@ -0,0 +1,94 @@ |
|||||||
|
|
||||||
|
#pragma once |
||||||
|
|
||||||
|
#ifndef __COMMANDPARSE_H_INCLUDED__ |
||||||
|
#define __COMMANDPARSE_H_INCLUDED__ |
||||||
|
|
||||||
|
#include <Windows.h> |
||||||
|
#include <string> |
||||||
|
|
||||||
|
#define VALIDATE_COMMAND( s, c ) \ |
||||||
|
if (_strnicmp( s + 1, c, strlen( c ) ) != 0) \ |
||||||
|
return false; |
||||||
|
|
||||||
|
#define HANDLE_ARGUMENT( a, b ) \ |
||||||
|
if (a[1] == b) |
||||||
|
|
||||||
|
/**
|
||||||
|
* GetCommandArgs |
||||||
|
* @param1 : The command to parse for arguments. |
||||||
|
* @param2 : Array of strings to store the found arguments. |
||||||
|
* @returns : Number of arguments found within the command. |
||||||
|
* |
||||||
|
* This function mimics the *nix command 'strsep' to locate and |
||||||
|
* parse strings with inline-quotes. |
||||||
|
* |
||||||
|
* Thanks to: |
||||||
|
* http://stackoverflow.com/questions/9659697/parse-string-into-array-based-on-spaces-or-double-quotes-strings
|
||||||
|
* |
||||||
|
* Modified for Ashita needs with plugin commands. |
||||||
|
* |
||||||
|
*/ |
||||||
|
int __stdcall GetCommandArgs( const char* pszCommand, std::string* args ) |
||||||
|
{ |
||||||
|
enum { |
||||||
|
NONE, |
||||||
|
IN_WORD, |
||||||
|
IN_STRING, |
||||||
|
} state = NONE; |
||||||
|
|
||||||
|
char szCurrentArgument[ 255 ] = { 0 }; |
||||||
|
char szCurrentChar = 0; |
||||||
|
char *pszStart = 0; |
||||||
|
int nArgCount = 0; |
||||||
|
|
||||||
|
for (const char* p = pszCommand; *p != '\0' || state != NONE; ++p) |
||||||
|
{ |
||||||
|
szCurrentChar = (unsigned char)*p; |
||||||
|
switch (state) |
||||||
|
{ |
||||||
|
case NONE: |
||||||
|
{ |
||||||
|
if (isspace( szCurrentChar )) |
||||||
|
continue; |
||||||
|
if (szCurrentChar == '"') |
||||||
|
{ |
||||||
|
state = IN_STRING; |
||||||
|
pszStart = (char*)( p + 1 ); |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
state = IN_WORD; |
||||||
|
pszStart = (char*)p; |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
case IN_STRING: |
||||||
|
if (szCurrentChar == '"') |
||||||
|
{ |
||||||
|
strncpy_s( szCurrentArgument, pszStart, p - pszStart ); |
||||||
|
args[nArgCount] = std::string( szCurrentArgument ); |
||||||
|
nArgCount++; |
||||||
|
|
||||||
|
state = NONE; |
||||||
|
} |
||||||
|
continue; |
||||||
|
|
||||||
|
case IN_WORD: |
||||||
|
if (isspace( szCurrentChar ) || *++p == '\0') |
||||||
|
{ |
||||||
|
strncpy_s( szCurrentArgument, pszStart, p - pszStart ); |
||||||
|
args[nArgCount] = std::string( szCurrentArgument ); |
||||||
|
nArgCount++; |
||||||
|
|
||||||
|
state = NONE; |
||||||
|
} |
||||||
|
*--p; |
||||||
|
continue; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return nArgCount; |
||||||
|
} |
||||||
|
|
||||||
|
#endif // __COMMANDPARSE_H_INCLUDED__
|
@ -0,0 +1,966 @@ |
|||||||
|
#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<std::string> 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<unsigned char>& 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 |
@ -0,0 +1,85 @@ |
|||||||
|
#ifndef __ASHITA_WATCHEXP_H_INCLUDED__ |
||||||
|
#define __ASHITA_WATCHEXP_H_INCLUDED__ |
||||||
|
|
||||||
|
#if defined (_MSC_VER) && (_MSC_VER >= 1020) |
||||||
|
#pragma once |
||||||
|
#endif |
||||||
|
|
||||||
|
#include "G:\Code\git.ashita.atom0s.com\Ashita v3\Ashita-src\build\plugins\ADK\Ashita.h" |
||||||
|
#include <tuple> |
||||||
|
#include <stdint.h> |
||||||
|
#include <regex> |
||||||
|
#include <time.h> |
||||||
|
#include <string> |
||||||
|
#include <sstream> |
||||||
|
#include <vector> |
||||||
|
|
||||||
|
plugininfo_t* g_PluginInformation = nullptr; |
||||||
|
|
||||||
|
int AbysseaZoneIDs[] = { 15,45,132,215,216,217,218,253,254,255 }; |
||||||
|
int DynamisZoneIDs[] = { 39,40,41,42,134,135,185,186,187,188 }; |
||||||
|
|
||||||
|
class WatchEXP : IPlugin |
||||||
|
{ |
||||||
|
WatchEXP(const WatchEXP & cpy); |
||||||
|
WatchEXP & operator=(WatchEXP & rhs); |
||||||
|
|
||||||
|
IAshitaCore* m_AshitaCore; |
||||||
|
DWORD m_PluginId; |
||||||
|
IDirect3DDevice8* m_Direct3DDevice; |
||||||
|
|
||||||
|
public: |
||||||
|
WatchEXP(void); |
||||||
|
virtual ~WatchEXP(void); |
||||||
|
|
||||||
|
public: |
||||||
|
plugininfo_t GetPluginInfo(void) override; |
||||||
|
|
||||||
|
private: |
||||||
|
IFontObject* m_ExpObj; |
||||||
|
|
||||||
|
char TextObjectBuffer[MAX_PATH]; |
||||||
|
|
||||||
|
time_t m_AbyTimeStart, m_DynTimeStart, m_BaseTimeEXP, m_BaseTimeCR, m_resetTime; |
||||||
|
|
||||||
|
SIZE m_ExpObjSize; |
||||||
|
int font_size, m_reset_min; |
||||||
|
int m_CurrentZoneID, m_LastZoneRecorded; |
||||||
|
char font_name[128]; |
||||||
|
char m_Dyna_Crm, m_Dyna_Azr, m_Dyna_Amb, m_Dyna_Alab, m_Dyna_Obs; |
||||||
|
std::string hexColor; |
||||||
|
unsigned int m_vTime; |
||||||
|
unsigned int m_DynaTime; |
||||||
|
unsigned int m_xpKill, m_xpTotal, m_xpTest; |
||||||
|
unsigned int m_crKill, m_crTotal; |
||||||
|
unsigned int m_prl, m_gld, m_slv, m_ebn, m_azr, m_rby, m_amb; |
||||||
|
unsigned char backTrans; |
||||||
|
bool m_IsInAbyssea, m_IsInDynamis, show_XP_M_always, m_autoreset; |
||||||
|
public: |
||||||
|
bool Initialize(IAshitaCore* core, ILogManager* log, uint32_t id) override; |
||||||
|
void Release(void) override; |
||||||
|
bool HandleCommand(const char* pszCommand, int nCommandType) override; |
||||||
|
bool HandleIncomingText(int16_t mode, const char* message, int16_t* modifiedMode, char* modifiedMessage, bool blocked) override; |
||||||
|
bool Direct3DInitialize(IDirect3DDevice8* lpDevice) override; |
||||||
|
void Direct3DRelease(void) override; |
||||||
|
void Direct3DRender(void) override; |
||||||
|
|
||||||
|
void GetConfig(void); |
||||||
|
|
||||||
|
float returnProjectedEXPperHour(unsigned int expIntoLevel); |
||||||
|
float returnProjectedCRUORperHour(unsigned int expIntoLevel); |
||||||
|
void doAbysseaZoneTimings(); |
||||||
|
void doDynamisZoneTimings(); |
||||||
|
void doDynamisKItemCheck(); |
||||||
|
void doEXPCalculations(); |
||||||
|
bool isInAbyssea(int zoneID); |
||||||
|
bool isInDynamis(int zoneID); |
||||||
|
void makeComma(int n, char *p, int count); |
||||||
|
int convertFromHex(std::string hex); |
||||||
|
void hextodec(std::string hex, std::vector<unsigned char>& rgb); |
||||||
|
void convertTrans(unsigned char& trans); |
||||||
|
void checkResetTime(); |
||||||
|
std::string ScrubChat(const char* chat_line); |
||||||
|
}; |
||||||
|
|
||||||
|
#endif |
Loading…
Reference in new issue