Skip to content
This repository has been archived by the owner on Feb 13, 2023. It is now read-only.

Commit

Permalink
Merge pull request #18 from idietmoran/dev
Browse files Browse the repository at this point in the history
fixed race condition between threads
  • Loading branch information
Stateford authored Nov 19, 2017
2 parents ad3fb78 + aaa7fc7 commit 7d0cec2
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 28 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
/full release/
/Output/
/src/config/
/src/gui/

.gitmodules
packages.config
Expand Down
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
# Changelog
All notable changes to this project will be documented in this file.

## [1.0.3]
### Added
- All button: opens all party members in the browser
### Fixed
- Race conditions for threads

## [1.0.1]
## Added
### Added
- Checks for updates

## [1.0.0]
### Added
- Cross-world party support for DX9

## [0.0.6]
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
### DISCLAIMER
This program reads from process memory. Use at your own risk!

### Dependencies
- [CPPRESTSDK](https://github.com/Microsoft/cpprestsdk)

#### DESCRIPTION
This program reads the names of party members by memory and opens their username in a search page in your default browser.

Expand Down
49 changes: 48 additions & 1 deletion src/arch/arch.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#include "arch.h"
/*
* Abstract class that is a base for x64, and x86. contains shared methods
* for each derived class
*/

#include "arch.h"
#include <thread>

bool Arch::x64 = false;

Expand Down Expand Up @@ -107,4 +112,46 @@ std::vector<Player*> Arch::getFilteredAlliesCW()
bool Arch::getCrossWorldStatus()
{
return inCrossWorldParty_;
}

// opens all users in the web broswer in parallel
void Arch::openAll(int partySize)
{
if (getCrossWorldStatus())
{
// this will be garbage collected automatically thanks to RAII
std::vector<std::thread*> threads;
// create new threads
for (int i = 0; i < partySize; i++)
{
threads.push_back(new std::thread([=]
{
filteredAlliesCW_[i]->openBrowser();
}));
}

// join all threads
for(auto &p : threads)
{
p->join();
}
}
else
{
// this will be garbage collected automatically thanks to RAII
std::vector<std::thread*> threads;
// create new threads
for (int i = 0; i < partySize; i++)
{
threads.push_back(new std::thread([=]
{
filteredAllies_[i]->openBrowser();
}));
}
// join all threads
for(auto &p : threads)
{
p->join();
}
}
}
1 change: 1 addition & 0 deletions src/arch/arch.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,6 @@ class Arch
std::vector<Player*> getFilteredAllies();
std::vector<Player*> getFilteredAlliesCW();
bool getCrossWorldStatus();
void openAll(int);
};

13 changes: 11 additions & 2 deletions src/arch/x64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@
#include "x64.h"
#include <iostream>

// constructor
x64::x64(Process* proc)
{
numberOfPartyMembers_ = new Offset({ 0x1807FB8, 0x38, 0x10, 0x208, 0x20 });
// get window name
exe_ = new Module("ffxiv_dx11.exe");
// memory offests for dx11 number of party members
numberOfPartyMembers_ = new Offset({ 0x1807FB8, 0x38, 0x10, 0x208, 0x20 });

// if dx11 (64-bit) set static x64 true
if (exe_->getModule(proc))
{
Arch::x64 = true;
Expand All @@ -18,6 +22,7 @@ x64::x64(Process* proc)
createAllies(proc);
}

// destructor
x64::~x64()
{
deleteAllies();
Expand All @@ -27,19 +32,21 @@ x64::~x64()
numberOfPartyMembers_ = nullptr;
}

// create allies
void x64::createAllies(Process* proc)
{
// dx11 64-bit offsets
allies_.push_back(new YOU(0x1828AE1));
allies_.push_back(new Ally(0x184A170));
allies_.push_back(new Ally(0x1849F50));
allies_.push_back(new Ally(0x184AC10));
allies_.push_back(new Ally(0x184A5B0));
allies_.push_back(new Ally(0x184A9F0));
allies_.push_back(new Ally(0x184A7D0));
allies_.push_back(new Ally(0x184AC10));
allies_.push_back(new Ally(0x184A390));
allies_.push_back(new Ally(0x184AE30));

// create crossworld allies
alliesCW_.push_back(allies_[0]); // YOU
DWORD64 address = exe_->getAddress();
address += 0x017E6620;
Expand All @@ -55,11 +62,13 @@ void x64::createAllies(Process* proc)
}
}

// get the number of party members
void x64::updateNumberOfPartyMembers(Process* proc, int &partyMembers)
{
ReadProcessMemory(proc->getHandle(), (void*)(numberOfPartyMembers_->getMemoryAddress64(proc, exe_)), &partyMembers, sizeof(int), 0);
}

// check if currently crossworld party
void x64::checkCrossWorldParty(Process* proc)
{
ReadProcessMemory(proc->getHandle(), (void*)(exe_->getAddress() + 0x1848F0C), &inCrossWorldParty_, 1, 0);
Expand Down
10 changes: 6 additions & 4 deletions src/arch/x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include "x86.h"
#include <iostream>


// constructor
x86::x86(Process* proc)
{
// handle error when getting invalid module
Expand All @@ -24,7 +24,7 @@ x86::x86(Process* proc)
createAllies(proc);
}


// destructor
x86::~x86()
{
deleteAllies();
Expand All @@ -34,6 +34,7 @@ x86::~x86()
numberOfPartyMembers_ = nullptr;
}

// create allies
void x86::createAllies(Process* proc)
{
// dx9 32-bit offsets
Expand All @@ -47,7 +48,7 @@ void x86::createAllies(Process* proc)
allies_.push_back(new Ally(0x117B6F0));
allies_.push_back(new Ally(0x117B910));


// create crossworld allies
alliesCW_.push_back(allies_[0]); // YOU

DWORD address = exe_->getAddress();
Expand All @@ -64,12 +65,13 @@ void x86::createAllies(Process* proc)

}


// get the number of party members
void x86::updateNumberOfPartyMembers(Process *proc, int &partyMembers)
{
ReadProcessMemory(proc->getHandle(), (void*)(numberOfPartyMembers_->getMemoryAddress(proc, exe_)), &partyMembers, sizeof(int), 0);
}

// check if currently crossworld party
void x86::checkCrossWorldParty(Process* proc)
{
// do nothing for the time being
Expand Down
67 changes: 51 additions & 16 deletions src/menu.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "menu.h"
#include <iostream>
#include <thread>
#include <chrono>

// constructor
Menu::Menu()
Expand All @@ -20,21 +21,22 @@ Menu::~Menu()
void Menu::displayAllies()
{
// update play characters names
fflogs_->arch_->updateNames(fflogs_->ffxiv_, fflogs_->partyMembers_);


//fflogs_->arch_->updateNames(fflogs_->ffxiv_, fflogs_->partyMembers_);
int partyMembers = fflogs_->partyMembers_;

// if currentMenuSelection is greater than the number of party members
// set currentMenuSelection equal to number of party members so the
// cursor doesn't go off screen
if(currentMenuSelection_ > fflogs_->partyMembers_)
{
currentMenuSelection_ = fflogs_->partyMembers_ - 1;
currentMenuSelection_ = fflogs_->partyMembers_;
}

SetConsoleTextAttribute(hConsole_, 7);
// display title
std::cout << "FFXIV Party Logs\n";
std::cout << "--------------------";

if(fflogs_->arch_->getCrossWorldStatus())
{
SetConsoleTextAttribute(hConsole_, 13);
Expand Down Expand Up @@ -80,12 +82,18 @@ void Menu::displayAllies()
fflogs_->arch_->getFilteredAllies()[i]->display();
}
}
SetConsoleTextAttribute(hConsole_, 7);

if(currentMenuSelection_ == partyMembers)
{
SetConsoleTextAttribute(hConsole_, 23);
}
std::cout << "ALL" << std::endl;

// this prevents the colors from breaking
SetConsoleTextAttribute(hConsole_, 7);
}


void Menu::redraw()
{
system("CLS");
Expand All @@ -94,15 +102,19 @@ void Menu::redraw()

void Menu::alliesMenu(DWORD &mode, INPUT_RECORD &event, HANDLE &hstdin)
{
system("CLS");

mu_.lock(); // lock the thread
system("CLS"); // clear the screen
// display allies
displayAllies();
// set previous values
prevPartySize_ = fflogs_->partyMembers_;
prevCrossWorldStatus_ = fflogs_->arch_->getCrossWorldStatus();
mu_.unlock(); // unlock the thread

while(live_)
{
fflogs_->arch_->updateNames(fflogs_->ffxiv_, fflogs_->partyMembers_);

mu_.lock(); // lock the thread

// checks if party size changes, or party changes to crossworld and displays the changes
if(prevPartySize_ != fflogs_->partyMembers_ || prevCrossWorldStatus_ != fflogs_->arch_->getCrossWorldStatus())
Expand All @@ -115,7 +127,7 @@ void Menu::alliesMenu(DWORD &mode, INPUT_RECORD &event, HANDLE &hstdin)
// checks if console is currently focused
bool isConsoleWindowFocussed = (GetConsoleWindow() == GetForegroundWindow());


// checks key states
if(GetAsyncKeyState(VK_ESCAPE) & 0x1 && isConsoleWindowFocussed)
{
live_ = false;
Expand All @@ -132,7 +144,7 @@ void Menu::alliesMenu(DWORD &mode, INPUT_RECORD &event, HANDLE &hstdin)

if(GetAsyncKeyState(VK_DOWN) & 0x1 && isConsoleWindowFocussed)
{
if (currentMenuSelection_ < fflogs_->partyMembers_ - 1)
if (currentMenuSelection_ < fflogs_->partyMembers_)
{
currentMenuSelection_++;
redraw();
Expand All @@ -141,7 +153,14 @@ void Menu::alliesMenu(DWORD &mode, INPUT_RECORD &event, HANDLE &hstdin)

if(GetAsyncKeyState(VK_RETURN) & 0x1 && isConsoleWindowFocussed)
{
if(fflogs_->arch_->getCrossWorldStatus())

if(currentMenuSelection_ == fflogs_->partyMembers_)
{
// TODO: code here for ALL
fflogs_->arch_->openAll(fflogs_->partyMembers_);
}

else if(fflogs_->arch_->getCrossWorldStatus())
{
fflogs_->arch_->getFilteredAlliesCW()[currentMenuSelection_]->openBrowser();
}
Expand All @@ -150,21 +169,37 @@ void Menu::alliesMenu(DWORD &mode, INPUT_RECORD &event, HANDLE &hstdin)
fflogs_->arch_->getFilteredAllies()[currentMenuSelection_]->openBrowser();
}
}
Sleep(1);
mu_.unlock(); // unlock the thread
std::this_thread::sleep_for(std::chrono::nanoseconds(2));
}
}

void Menu::start()
{
system("CLS");
system("CLS"); // clear the screen
// initalize variables to contain input
DWORD mode;
INPUT_RECORD event;
HANDLE hstdin = GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(hstdin, &mode);
SetConsoleMode(hstdin, 0);

std::thread t1([=, &mode, &event, &hstdin] { alliesMenu(mode, event, hstdin); });

// thread to update the menu
std::thread t1([=, &mode, &event, &hstdin]{ alliesMenu(mode, event, hstdin); });
// thread to get names
std::thread t2([=] {
while (true)
{
mu_.lock(); // lock the thread
// update names
fflogs_->arch_->updateNames(fflogs_->ffxiv_, fflogs_->partyMembers_);
mu_.unlock(); // unlock the thread
// sleep the thread
std::this_thread::sleep_for(std::chrono::nanoseconds(2));
}
});

t2.join();
t1.join();
}
3 changes: 3 additions & 0 deletions src/menu.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include <shared_mutex>

#include "ffxiv.h"
class Menu
{
Expand All @@ -12,6 +14,7 @@ class Menu
HANDLE hConsole_;
HANDLE hstdin_;
bool prevCrossWorldStatus_;
std::shared_timed_mutex mu_;
public:
Menu();
~Menu();
Expand Down
3 changes: 0 additions & 3 deletions src/player/player.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@ class Player
char name_[80];
virtual void display() = 0;
virtual void updateName(Process*, Module*) = 0;
bool characterCheck();
void charRequest(std::wstring, std::vector<std::wstring>, std::wstring, std::wstring&, int&);
bool getCharId();
void parseJson(std::wstring*&);
void parseSearch(std::wstring&);
void openBrowser();
bool compare(Player*);
Expand Down
Loading

0 comments on commit 7d0cec2

Please sign in to comment.