Skip to content

Commit

Permalink
Implement EntityList view, also display when container is empty (Enti…
Browse files Browse the repository at this point in the history
…tyList, StdMap, StdVector)
  • Loading branch information
Mr-Auto committed Jun 1, 2024
1 parent 6c2d63b commit 0a284b8
Show file tree
Hide file tree
Showing 11 changed files with 350 additions and 15 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ x64dbg_plugin(${PROJECT_NAME}
include/Data/Logger.h
include/Data/StdString.h
include/Data/StdMap.h
include/Data/EntityList.h
include/Views/ViewToolbar.h
include/Views/ViewEntityDB.h
include/Views/ViewParticleDB.h
Expand All @@ -77,6 +78,7 @@ x64dbg_plugin(${PROJECT_NAME}
include/Views/ViewJournalPage.h
include/Views/ViewThreads.h
include/Views/ViewStdMap.h
include/Views/ViewEntityList.h
include/QtHelpers/StyledItemDelegateHTML.h
include/QtHelpers/StyledItemDelegateColorPicker.h
include/QtHelpers/TreeViewMemoryFields.h
Expand Down Expand Up @@ -131,6 +133,7 @@ x64dbg_plugin(${PROJECT_NAME}
src/Views/ViewStdMap.cpp
src/Views/ViewJournalPage.cpp
src/Views/ViewThreads.cpp
src/Views/ViewEntityList.cpp
src/QtHelpers/StyledItemDelegateHTML.cpp
src/QtHelpers/TreeViewMemoryFields.cpp
src/QtHelpers/WidgetMemoryView.cpp
Expand Down
9 changes: 5 additions & 4 deletions include/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ namespace S2Plugin
Double,
Array,
Matrix,
EntityList,
};

struct VirtualFunction
Expand Down Expand Up @@ -159,8 +160,8 @@ namespace S2Plugin
size_t get_size() const;
union
{
// length, size of array etc.
size_t numberOfElements{0};
// length, size of array etc.
size_t numberOfElements{0};
// row count for matrix
size_t rows;
};
Expand Down Expand Up @@ -249,7 +250,7 @@ namespace S2Plugin
const std::vector<std::pair<int64_t, std::string>>& refTitlesOfField(const std::string& fieldName) const;

size_t getTypeSize(const std::string& typeName, bool entitySubclass = false);
const EntityList& entityList() const
const EntityNamesList& entityList() const
{
return entityNames;
};
Expand Down Expand Up @@ -295,7 +296,7 @@ namespace S2Plugin
void processRoomCodesJSON(nlohmann::ordered_json& json);
MemoryField populateMemoryField(const nlohmann::ordered_json& field, const std::string& struct_name);

EntityList entityNames;
EntityNamesList entityNames;
ParticleEmittersList particleEmitters;

Configuration();
Expand Down
159 changes: 159 additions & 0 deletions include/Data/EntityList.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
#pragma once

#include "Entity.h"
#include "pluginmain.h"
#include "read_helpers.h"
#include <cstdint>
#include <utility>

namespace S2Plugin
{

class EntityList
{
public:
EntityList(uintptr_t _address) : address(_address){};
uintptr_t entities() const
{
return Script::Memory::ReadQword(address);
}

uintptr_t uids() const
{
return Script::Memory::ReadQword(address + sizeof(uintptr_t));
}
uint32_t capacity() const
{
return Script::Memory::ReadDword(address + sizeof(uintptr_t) * 2);
}
uint32_t size() const
{
return Script::Memory::ReadDword(address + sizeof(uintptr_t) * 2 + sizeof(uint32_t));
}
struct Iterator
{
// Iterator(){};
Iterator(const EntityList entityList, uint32_t index) noexcept : Iterator(entityList.begin())
{
advance(index);
}
void advance(int count) noexcept // should probably be int64 ?
{
addr.first += count * sizeof(uintptr_t);
addr.second += count * sizeof(uint32_t);
}
Iterator& operator++() noexcept
{
advance(1);
return *this;
}
Iterator operator++(int) noexcept
{
auto copy = *this;
advance(1);
return copy;
}
Iterator& operator--() noexcept
{
advance(-1);
}
Iterator operator--(int) noexcept
{
auto copy = *this;
advance(-1);
return copy;
}
std::pair<uintptr_t, uint32_t> operator*() const
{
return {addr.first, Script::Memory::ReadDword(addr.second)};
}
bool operator==(const Iterator& other) const noexcept
{
return addr.first == other.addr.first;
}
bool operator!=(const Iterator& other) const noexcept
{
return addr.first != other.addr.first;
}
uintptr_t entityRaw() const
{
return Script::Memory::ReadQword(addr.first);
}
Entity entity() const
{
return Script::Memory::ReadQword(addr.first);
}
uint32_t uid() const
{
return Script::Memory::ReadDword(addr.second);
}

private:
Iterator(uintptr_t entitiesAddress, uintptr_t uidsAddress) : addr(entitiesAddress, uidsAddress){};
std::pair<uintptr_t, uintptr_t> addr;
friend class EntityList;
};

Iterator begin() const
{
uintptr_t pointers[2] = {0, 0};
// slightly faster then reading both thru ReadQword
Script::Memory::Read(address, &pointers, sizeof(uintptr_t) * 2, nullptr);
return {pointers[0], pointers[1]};
}
Iterator end() const
{
auto full = getFullStruct();
uintptr_t entitiesEnd = full.entities + full.size * sizeof(uintptr_t);
uintptr_t uidsEnd = full.uids + full.size * sizeof(uint32_t);
return {entitiesEnd, uidsEnd};
}
const Iterator cbegin() const
{
return begin();
}
const Iterator cend() const
{
return end();
}
Iterator find(uint32_t uid) const
{
auto endIterator = end();
for (auto it = begin(); it != endIterator; ++it)
{
if (it.uid() == uid)
return it;
}
return endIterator;
}
Iterator findEntity(uintptr_t addr) const
{
auto endIterator = end();
for (auto it = begin(); it != endIterator; ++it)
{
if (it.entityRaw() == addr)
return it;
}
return endIterator;
}

private:
uintptr_t address;
struct TrueEntityList
{
uintptr_t entities{0};
uintptr_t uids{0};
uint32_t cap{0};
uint32_t size{0};

private:
TrueEntityList() = delete;
// TrueEntityList(const TrueEntityList&) = delete;
// TrueEntityList& operator=(const TrueEntityList&) = delete;
};
TrueEntityList getFullStruct() const
{
return Read<TrueEntityList>(address);
}
};
}; // namespace S2Plugin
8 changes: 4 additions & 4 deletions include/Data/IDNameList.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ namespace S2Plugin
ParticleEmittersList(const ParticleEmittersList&) = delete;
ParticleEmittersList& operator=(const ParticleEmittersList&) = delete;
};
class EntityList : public IDNameList
class EntityNamesList : public IDNameList
{
public:
explicit EntityList();
explicit EntityNamesList();

EntityList(const EntityList&) = delete;
EntityList& operator=(const EntityList&) = delete;
EntityNamesList(const EntityNamesList&) = delete;
EntityNamesList& operator=(const EntityNamesList&) = delete;
};
} // namespace S2Plugin
30 changes: 30 additions & 0 deletions include/Views/ViewEntityList.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#pragma once

#include <QSize>
#include <QWidget>
#include <cstdint>
#include <string>

namespace S2Plugin
{
class TreeViewMemoryFields;

class ViewEntityList : public QWidget
{
Q_OBJECT
public:
ViewEntityList(uintptr_t address, QWidget* parent = nullptr);

protected:
QSize sizeHint() const override;
QSize minimumSizeHint() const override;

private slots:
void refreshEntityListContents();

private:
uintptr_t mEntityListAddress;

TreeViewMemoryFields* mMainTreeView;
};
} // namespace S2Plugin
1 change: 1 addition & 0 deletions include/Views/ViewToolbar.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ namespace S2Plugin
void showLevelGen(uintptr_t address);
void showArray(uintptr_t address, std::string name, std::string arrayTypeName, size_t length);
void showMatrix(uintptr_t address, std::string name, std::string arrayTypeName, size_t rows, size_t columns);
void showEntityList(uintptr_t address);

public slots:
ViewEntityDB* showEntityDB();
Expand Down
1 change: 1 addition & 0 deletions src/Configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ namespace S2Plugin
{MemoryFieldType::IPv4Address, "IPv4Address", "uint32_t", "IPv4Address", 4, false},
{MemoryFieldType::Array, "Array", "", "Array", 0, false},
{MemoryFieldType::Matrix, "Matrix", "", "Matrix", 0, false},
{MemoryFieldType::EntityList, "EntityList", "EntityList*", "EntityList", 24, false},
// Other
//{MemoryFieldType::EntitySubclass, "", "", "", 0},
//{MemoryFieldType::DefaultStructType, "", "", "", 0},
Expand Down
2 changes: 1 addition & 1 deletion src/Data/IDNameList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ std::string S2Plugin::IDNameList::nameForID(uint32_t id) const

static const std::regex regexEntityLine("^([0-9]+): ENT_TYPE_(.*?)$", std::regex_constants::ECMAScript);

S2Plugin::EntityList::EntityList() : IDNameList("plugins/Spelunky2Entities.txt", regexEntityLine) {}
S2Plugin::EntityNamesList::EntityNamesList() : IDNameList("plugins/Spelunky2Entities.txt", regexEntityLine) {}

static const std::regex regexParticleLine("^([0-9]+): PARTICLEEMITTER_(.*?)$", std::regex_constants::ECMAScript);

Expand Down
Loading

0 comments on commit 0a284b8

Please sign in to comment.