commit
04ff32ce34
@ -23,7 +23,6 @@ ItemSchemaPtr_t GetItemSchema(void) {
|
|||||||
if (!ItemSystem) {
|
if (!ItemSystem) {
|
||||||
ItemSystem = (ItemSystem_t)gSignatures.GetClientSignature((char*)sig_GetItemSchema);
|
ItemSystem = (ItemSystem_t)gSignatures.GetClientSignature((char*)sig_GetItemSchema);
|
||||||
}
|
}
|
||||||
logging::Info("ItemSystem: 0x%08x 0x%08x", ItemSystem, ItemSystem());
|
|
||||||
return (void*)((uint32_t)(ItemSystem()) + 4);
|
return (void*)((uint32_t)(ItemSystem()) + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,6 +31,17 @@ CAttribute::CAttribute(uint16_t iAttributeDefinitionIndex, float flValue) {
|
|||||||
value = flValue;
|
value = flValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float CAttributeList::GetAttribute(int defindex) {
|
||||||
|
for (int i = 0; i < m_Attributes.Count(); i++) {
|
||||||
|
const auto& a = m_Attributes[i];
|
||||||
|
if (a.defidx == defindex) {
|
||||||
|
return a.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
void CAttributeList::RemoveAttribute(int index) {
|
void CAttributeList::RemoveAttribute(int index) {
|
||||||
for (int i = 0; i < m_Attributes.Count(); i++) {
|
for (int i = 0; i < m_Attributes.Count(); i++) {
|
||||||
const auto& a = m_Attributes[i];
|
const auto& a = m_Attributes[i];
|
||||||
@ -45,11 +55,10 @@ void CAttributeList::RemoveAttribute(int index) {
|
|||||||
CAttributeList::CAttributeList() {}
|
CAttributeList::CAttributeList() {}
|
||||||
|
|
||||||
void CAttributeList::SetAttribute(int index, float value) {
|
void CAttributeList::SetAttribute(int index, float value) {
|
||||||
ItemSchemaPtr_t schema = GetItemSchema();
|
static ItemSchemaPtr_t schema = GetItemSchema();
|
||||||
logging::Info("Schema: 0x%08x", schema);
|
|
||||||
AttributeDefinitionPtr_t attrib = GetAttributeDefinitionFn(schema, index);
|
AttributeDefinitionPtr_t attrib = GetAttributeDefinitionFn(schema, index);
|
||||||
logging::Info("Attrib: 0x%08x", attrib);
|
|
||||||
SetRuntimeAttributeValueFn(this, attrib, value);
|
SetRuntimeAttributeValueFn(this, attrib, value);
|
||||||
|
// The code below actually is unused now - but I'll keep it just in case!
|
||||||
// Let's check if attribute exists already. We don't want dupes.
|
// Let's check if attribute exists already. We don't want dupes.
|
||||||
/*for (int i = 0; i < m_Attributes.Count(); i++) {
|
/*for (int i = 0; i < m_Attributes.Count(); i++) {
|
||||||
auto& a = m_Attributes[i];
|
auto& a = m_Attributes[i];
|
||||||
@ -62,33 +71,64 @@ void CAttributeList::SetAttribute(int index, float value) {
|
|||||||
if (m_Attributes.Count() > 14)
|
if (m_Attributes.Count() > 14)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//m_Attributes.m_Memory.m_nGrowSize = -1;
|
m_Attributes.AddToTail({ index, value });
|
||||||
//logging::Info("0x%08x 0x%08x 0x%08x", m_Attributes.m_Memory.m_nAllocationCount, m_Attributes.m_Memory.m_nGrowSize, m_Attributes.m_Memory.m_pMemory);
|
*/
|
||||||
//m_Attributes.m_Memory.SetExternalBuffer(m_Attributes.m_Memory.Base(), 15);
|
|
||||||
CAttribute attr( index, value );
|
|
||||||
m_Attributes.AddToTail(attr);*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static CatVar enabled(CV_SWITCH, "skinchanger", "0", "Skin Changer");
|
static CatVar enabled(CV_SWITCH, "skinchanger", "0", "Skin Changer");
|
||||||
static CatCommand set_attr("skinchanger_set", "Set Attribute", [](const CCommand& args) {
|
static CatCommand set_attr("skinchanger_set", "Set Attribute", [](const CCommand& args) {
|
||||||
unsigned attrid = strtoul(args.Arg(1), nullptr, 10);
|
unsigned attrid = strtoul(args.Arg(1), nullptr, 10);
|
||||||
unsigned attrv = strtoul(args.Arg(2), nullptr, 10);
|
float attrv = strtof(args.Arg(2), nullptr);
|
||||||
GetModifier(CE_INT(LOCAL_W, netvar.iItemDefinitionIndex)).Set(attrid, attrv);
|
GetModifier(CE_INT(LOCAL_W, netvar.iItemDefinitionIndex)).Set(attrid, attrv);
|
||||||
InvalidateCookies();
|
InvalidateCookie();
|
||||||
|
});
|
||||||
|
static CatCommand remove_attr("skinchanger_remove", "Remove attribute", [](const CCommand& args) {
|
||||||
|
unsigned attrid = strtoul(args.Arg(1), nullptr, 10);
|
||||||
|
GetModifier(CE_INT(LOCAL_W, netvar.iItemDefinitionIndex)).Remove(attrid);
|
||||||
|
InvalidateCookie();
|
||||||
});
|
});
|
||||||
static CatCommand set_redirect("skinchanger_redirect", "Set Redirect", [](const CCommand& args) {
|
static CatCommand set_redirect("skinchanger_redirect", "Set Redirect", [](const CCommand& args) {
|
||||||
unsigned redirect = strtoul(args.Arg(1), nullptr, 10);
|
unsigned redirect = strtoul(args.Arg(1), nullptr, 10);
|
||||||
GetModifier(CE_INT(LOCAL_W, netvar.iItemDefinitionIndex)).defidx_redirect = redirect;
|
GetModifier(CE_INT(LOCAL_W, netvar.iItemDefinitionIndex)).defidx_redirect = redirect;
|
||||||
InvalidateCookies();
|
InvalidateCookie();
|
||||||
});
|
});
|
||||||
static CatCommand dump_attrs("skinchanger_debug_attrs", "Dump attributes", []() {
|
static CatCommand dump_attrs("skinchanger_debug_attrs", "Dump attributes", []() {
|
||||||
CAttributeList* list = CE_VAR(LOCAL_W, netvar.AttributeList, CAttributeList*);
|
CAttributeList* list = (CAttributeList*)((uintptr_t)(RAW_ENT(LOCAL_W)) + netvar.AttributeList);
|
||||||
logging::Info("ATTRIBUTE LIST: %i", list->m_Attributes.Size());
|
logging::Info("ATTRIBUTE LIST: %i", list->m_Attributes.Size());
|
||||||
for (int i = 0; i < 15; i++) {
|
for (int i = 0; i < list->m_Attributes.Size(); i++) {
|
||||||
logging::Info("%i %.2f", list->m_Attributes[i].defidx, list->m_Attributes[i].value);
|
logging::Info("%i %.2f", list->m_Attributes[i].defidx, list->m_Attributes[i].value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
static CatCommand invalidate_cookies("skinchanger_invalidate_cookies", "Invalidate Cookies", InvalidateCookies);
|
|
||||||
|
static CatCommand list_redirects("skinchanger_redirect_list", "Dump redirects", []() {
|
||||||
|
for (const auto& mod : modifier_map) {
|
||||||
|
if (mod.second.defidx_redirect) {
|
||||||
|
logging::Info("%d -> %d", mod.first, mod.second.defidx_redirect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
static CatCommand save("skinchanger_save", "Save", [](const CCommand& args) {
|
||||||
|
std::string filename = "skinchanger";
|
||||||
|
if (args.ArgC() > 1) {
|
||||||
|
filename = args.Arg(1);
|
||||||
|
}
|
||||||
|
Save(filename);
|
||||||
|
});
|
||||||
|
static CatCommand load("skinchanger_load", "Load", [](const CCommand& args) {
|
||||||
|
std::string filename = "skinchanger";
|
||||||
|
if (args.ArgC() > 1) {
|
||||||
|
filename = args.Arg(1);
|
||||||
|
}
|
||||||
|
Load(filename);
|
||||||
|
});
|
||||||
|
static CatCommand remove_redirect("skinchanger_remove_redirect", "Remove redirect", [](const CCommand& args) {
|
||||||
|
unsigned redirectid = strtoul(args.Arg(1), nullptr, 10);
|
||||||
|
GetModifier(redirectid).defidx_redirect = 0;
|
||||||
|
logging::Info("Redirect removed");
|
||||||
|
InvalidateCookie();
|
||||||
|
});
|
||||||
|
|
||||||
|
static CatCommand invalidate_cookies("skinchanger_bite_cookie", "Bite Cookie", InvalidateCookie);
|
||||||
|
|
||||||
void FrameStageNotify(int stage) {
|
void FrameStageNotify(int stage) {
|
||||||
if (!enabled) return;
|
if (!enabled) return;
|
||||||
@ -102,24 +142,126 @@ void FrameStageNotify(int stage) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (stage != FRAME_NET_UPDATE_POSTDATAUPDATE_START) return;
|
if (stage != FRAME_NET_UPDATE_POSTDATAUPDATE_START) return;
|
||||||
int handle = CE_INT(g_pLocalPlayer->entity, netvar.hActiveWeapon);
|
int* weapon_list = (int*)((unsigned)(RAW_ENT(LOCAL_E)) + netvar.hMyWeapons);
|
||||||
int eid = handle & 0xFFF;
|
int my_weapon = CE_INT(g_pLocalPlayer->entity, netvar.hActiveWeapon);
|
||||||
IClientEntity* entity = g_IEntityList->GetClientEntity(eid);
|
IClientEntity* my_weapon_ptr = g_IEntityList->GetClientEntity(my_weapon & 0xFFF);
|
||||||
GetModifier(NET_INT(entity, netvar.iItemDefinitionIndex)).Apply(eid);
|
static IClientEntity* last_weapon_out = nullptr;
|
||||||
/*if (!GetCookie(weapon->m_IDX).Check()) {
|
for (int i = 0; i < 5; i++) {
|
||||||
logging::Info("Cookie bad for %i", weapon->m_IDX); // FIXME DEBUG LOGS!
|
int handle = weapon_list[i];
|
||||||
GetModifier(CE_INT(weapon, netvar.iItemDefinitionIndex)).Apply(weapon->m_IDX);
|
int eid = handle & 0xFFF;
|
||||||
GetCookie(weapon->m_IDX).Update(weapon->m_IDX);
|
if (eid < 32 || eid > HIGHEST_ENTITY) continue;
|
||||||
}*/
|
//logging::Info("eid, %i", eid);
|
||||||
|
IClientEntity* entity = g_IEntityList->GetClientEntity(eid);
|
||||||
|
if (!entity) continue;
|
||||||
|
if ((my_weapon_ptr != last_weapon_out) || !cookie.Check()) {
|
||||||
|
GetModifier(NET_INT(entity, netvar.iItemDefinitionIndex)).Apply(eid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((my_weapon_ptr != last_weapon_out) || !cookie.Check())
|
||||||
|
cookie.Update(my_weapon & 0xFFF);
|
||||||
|
last_weapon_out = my_weapon_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CatVar show_debug_info(CV_SWITCH, "skinchanger_debug", "1", "Debug Skinchanger");
|
||||||
|
|
||||||
void PaintTraverse() {
|
void PaintTraverse() {
|
||||||
if (!enabled) return;
|
if (!enabled) return;
|
||||||
if (CE_GOOD(LOCAL_W))
|
if (!show_debug_info) return;
|
||||||
|
if (CE_GOOD(LOCAL_W)) {
|
||||||
AddSideString(format("dIDX: ", CE_INT(LOCAL_W, netvar.iItemDefinitionIndex)));
|
AddSideString(format("dIDX: ", CE_INT(LOCAL_W, netvar.iItemDefinitionIndex)));
|
||||||
|
CAttributeList* list = (CAttributeList*)((uintptr_t)(RAW_ENT(LOCAL_W)) + netvar.AttributeList);
|
||||||
|
for (int i = 0; i < list->m_Attributes.Size(); i++) {
|
||||||
|
AddSideString(format('[', i, "] ", list->m_Attributes[i].defidx, ": ", list->m_Attributes[i].value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
// Debug info?
|
// Debug info?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define BINARY_FILE_WRITE(handle, data) handle.write(reinterpret_cast<const char*>(&data), sizeof(data))
|
||||||
|
#define BINARY_FILE_READ(handle, data) handle.read(reinterpret_cast<char*>(&data), sizeof(data))
|
||||||
|
|
||||||
|
void Save(std::string filename) {
|
||||||
|
uid_t uid = geteuid();
|
||||||
|
passwd* pw = getpwuid(uid);
|
||||||
|
if (!pw) {
|
||||||
|
logging::Info("Couldn't get username!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::string name(pw->pw_name);
|
||||||
|
DIR* cathook_directory = opendir(strfmt("/home/%s/.cathook", pw->pw_name));
|
||||||
|
if (!cathook_directory) {
|
||||||
|
logging::Info(".cathook directory doesn't exist, creating one!");
|
||||||
|
mkdir(strfmt("/home/%s/.cathook", pw->pw_name), S_IRWXU | S_IRWXG);
|
||||||
|
} else closedir(cathook_directory);
|
||||||
|
try {
|
||||||
|
std::ofstream file("/home/" + name + "/.cathook/" + filename, std::ios::out | std::ios::binary);
|
||||||
|
BINARY_FILE_WRITE(file, SERIALIZE_VERSION);
|
||||||
|
size_t size = modifier_map.size();
|
||||||
|
BINARY_FILE_WRITE(file, size);
|
||||||
|
for (const auto& item : modifier_map) {
|
||||||
|
BINARY_FILE_WRITE(file, item.first);
|
||||||
|
// modifier data isn't a POD (it contains a vector), we can't BINARY_WRITE it completely.
|
||||||
|
BINARY_FILE_WRITE(file, item.second.defidx_redirect);
|
||||||
|
const auto& modifiers = item.second.modifiers;
|
||||||
|
size_t modifier_count = modifiers.size();
|
||||||
|
BINARY_FILE_WRITE(file, modifier_count);
|
||||||
|
// this code is a bit tricky - I'm treating vector as an array
|
||||||
|
if (modifier_count) {
|
||||||
|
file.write(reinterpret_cast<const char*>(modifiers.data()), modifier_count * sizeof(attribute_s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
logging::Info("Writing successful");
|
||||||
|
} catch (std::exception& e) {
|
||||||
|
logging::Info("Writing unsuccessful: %s", e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Load(std::string filename) {
|
||||||
|
uid_t uid = geteuid();
|
||||||
|
passwd* pw = getpwuid(uid);
|
||||||
|
if (!pw) {
|
||||||
|
logging::Info("Couldn't get username!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::string name(pw->pw_name);
|
||||||
|
DIR* cathook_directory = opendir(strfmt("/home/%s/.cathook", pw->pw_name));
|
||||||
|
if (!cathook_directory) {
|
||||||
|
logging::Info(".cathook directory doesn't exist, creating one!");
|
||||||
|
mkdir(strfmt("/home/%s/.cathook", pw->pw_name), S_IRWXU | S_IRWXG);
|
||||||
|
} else closedir(cathook_directory);
|
||||||
|
try {
|
||||||
|
std::ifstream file("/home/" + name + "/.cathook/" + filename, std::ios::in | std::ios::binary);
|
||||||
|
unsigned file_serialize = 0;
|
||||||
|
BINARY_FILE_READ(file, file_serialize);
|
||||||
|
if (file_serialize != SERIALIZE_VERSION) {
|
||||||
|
logging::Info("Outdated/corrupted SkinChanger file! Cannot load this.");
|
||||||
|
file.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t size = 0;
|
||||||
|
BINARY_FILE_READ(file, size);
|
||||||
|
logging::Info("Reading %i entries...", size);
|
||||||
|
modifier_map.clear();
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
int defindex;
|
||||||
|
BINARY_FILE_READ(file, defindex);
|
||||||
|
size_t count;
|
||||||
|
def_attribute_modifier modifier;
|
||||||
|
BINARY_FILE_READ(file, modifier.defidx_redirect);
|
||||||
|
BINARY_FILE_READ(file, count);
|
||||||
|
modifier.modifiers.resize(count);
|
||||||
|
file.read(reinterpret_cast<char*>(modifier.modifiers.data()), sizeof(attribute_s) * count);
|
||||||
|
modifier_map.insert(std::make_pair(defindex, std::move(modifier)));
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
logging::Info("Reading successful! Result: %i entries.", modifier_map.size());
|
||||||
|
} catch (std::exception& e) {
|
||||||
|
logging::Info("Reading unsuccessful: %s", e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void def_attribute_modifier::Set(int id, float value) {
|
void def_attribute_modifier::Set(int id, float value) {
|
||||||
for (auto& i : modifiers) {
|
for (auto& i : modifiers) {
|
||||||
if (i.defidx == id) {
|
if (i.defidx == id) {
|
||||||
@ -127,29 +269,25 @@ void def_attribute_modifier::Set(int id, float value) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
attribute_s& attr = modifiers.at(first_free_mod);
|
if (modifiers.size() > 13) {
|
||||||
first_free_mod++;
|
logging::Info("Woah there, that's too many! Remove some.");
|
||||||
attr.defidx = id;
|
return;
|
||||||
attr.value = value;
|
|
||||||
logging::Info("new attr: %i %.2f %i", attr.defidx, attr.value, first_free_mod);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InvalidateCookies() {
|
|
||||||
logging::Info("All cookies invalidated!"); // FIXME DEBUG LOGS!
|
|
||||||
for (auto& cookie : cookie_map) {
|
|
||||||
cookie.second.valid = false;
|
|
||||||
}
|
}
|
||||||
|
modifiers.push_back(attribute_s { id, value });
|
||||||
|
logging::Info("Added new attribute: %i %.2f (%i)", id, value, modifiers.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
patched_weapon_cookie::patched_weapon_cookie(int entity) {
|
void InvalidateCookie() {
|
||||||
Update(entity);
|
cookie.valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
patched_weapon_cookie::patched_weapon_cookie(int entity) {}
|
||||||
|
|
||||||
void patched_weapon_cookie::Update(int entity) {
|
void patched_weapon_cookie::Update(int entity) {
|
||||||
IClientEntity* ent = g_IEntityList->GetClientEntity(entity);
|
IClientEntity* ent = g_IEntityList->GetClientEntity(entity);
|
||||||
if (!ent || ent->IsDormant()) return;
|
if (!ent || ent->IsDormant()) return;
|
||||||
logging::Info("Updating cookie for %i", entity); // FIXME DEBUG LOGS!
|
logging::Info("Updating cookie for %i", entity); // FIXME DEBUG LOGS!
|
||||||
CAttributeList* list = NET_VAR(ent, 0x9c0, CAttributeList*);
|
CAttributeList* list = (CAttributeList*)((uintptr_t)ent + netvar.AttributeList);
|
||||||
attrs = list->m_Attributes.Size();
|
attrs = list->m_Attributes.Size();
|
||||||
eidx = entity;
|
eidx = entity;
|
||||||
defidx = NET_INT(ent, netvar.iItemDefinitionIndex);
|
defidx = NET_INT(ent, netvar.iItemDefinitionIndex);
|
||||||
@ -161,32 +299,40 @@ bool patched_weapon_cookie::Check() {
|
|||||||
if (!valid) return false;
|
if (!valid) return false;
|
||||||
IClientEntity* ent = g_IEntityList->GetClientEntity(eidx);
|
IClientEntity* ent = g_IEntityList->GetClientEntity(eidx);
|
||||||
if (!ent || ent->IsDormant()) return false;
|
if (!ent || ent->IsDormant()) return false;
|
||||||
CAttributeList* list = NET_VAR(ent, 0x9c0, CAttributeList*);
|
CAttributeList* list = (CAttributeList*)((uintptr_t)ent + netvar.AttributeList);
|
||||||
if (attrs != list->m_Attributes.Size()) return false;
|
if (attrs != list->m_Attributes.Size()) return false;
|
||||||
if (eclass != ent->GetClientClass()->m_ClassID) return false;
|
if (eclass != ent->GetClientClass()->m_ClassID) return false;
|
||||||
if (defidx != NET_INT(ent, netvar.iItemDefinitionIndex)) return false;
|
if (defidx != NET_INT(ent, netvar.iItemDefinitionIndex)) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void def_attribute_modifier::Remove(int id) {
|
||||||
|
auto it = modifiers.begin();
|
||||||
|
while (it != modifiers.end()) {
|
||||||
|
if ((*it).defidx == id) {
|
||||||
|
it = modifiers.erase(it);
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void def_attribute_modifier::Apply(int entity) {
|
void def_attribute_modifier::Apply(int entity) {
|
||||||
IClientEntity* ent = g_IEntityList->GetClientEntity(entity);
|
IClientEntity* ent = g_IEntityList->GetClientEntity(entity);
|
||||||
if (!ent) return;
|
if (!ent) return;
|
||||||
//logging::Info("Applying modifiers for %i %i %i", entity, NET_INT(ent, netvar.iItemDefinitionIndex), defidx_redirect);
|
|
||||||
if (defidx_redirect && NET_INT(ent, netvar.iItemDefinitionIndex) != defidx_redirect) {
|
if (defidx_redirect && NET_INT(ent, netvar.iItemDefinitionIndex) != defidx_redirect) {
|
||||||
NET_INT(ent, netvar.iItemDefinitionIndex) = defidx_redirect;
|
NET_INT(ent, netvar.iItemDefinitionIndex) = defidx_redirect;
|
||||||
logging::Info("Updated DefIDX to %i", NET_INT(ent, netvar.iItemDefinitionIndex));
|
logging::Info("Redirect -> %i", NET_INT(ent, netvar.iItemDefinitionIndex));
|
||||||
GetCookie(entity).valid = false;
|
GetModifier(defidx_redirect).Apply(entity);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CAttributeList* list = NET_VAR(ent, netvar.AttributeList, CAttributeList*);
|
CAttributeList* list = (CAttributeList*)((uintptr_t)ent + netvar.AttributeList);
|
||||||
//::Info("Attribute list: 0x%08x 0x%08x 0x%08x 0x%08x", 0x9c0, ent, list, (uint32_t)list - (uint32_t)ent);
|
|
||||||
list->m_Attributes.m_Size = list->m_Attributes.Size();
|
|
||||||
//logging::Info("Length: %i", list->m_Attributes.m_Size);
|
|
||||||
//logging::Info("Base: 0x%08x", list->m_Attributes.Base());
|
|
||||||
for (const auto& mod : modifiers) {
|
for (const auto& mod : modifiers) {
|
||||||
if (mod.defidx) {
|
if (mod.defidx) {
|
||||||
//logging::Info("Setting %i to %.2f", mod.defidx, mod.value); // FIXME DEBUG LOGS!
|
//if (mod.value)
|
||||||
list->SetAttribute(mod.defidx, mod.value);
|
list->SetAttribute(mod.defidx, mod.value);
|
||||||
|
//else
|
||||||
|
// list->RemoveAttribute(mod.defidx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -200,16 +346,19 @@ def_attribute_modifier& GetModifier(int idx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
patched_weapon_cookie& GetCookie(int idx) {
|
/*patched_weapon_cookie& GetCookie(int idx) {
|
||||||
try {
|
try {
|
||||||
return cookie_map.at(idx);
|
return cookie_map.at(idx);
|
||||||
} catch (std::out_of_range& oor) {
|
} catch (std::out_of_range& oor) {
|
||||||
cookie_map.emplace(idx, patched_weapon_cookie{idx});
|
cookie_map.emplace(idx, patched_weapon_cookie{idx});
|
||||||
return cookie_map.at(idx);
|
return cookie_map.at(idx);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
// A map that maps an Item Definition Index to a modifier
|
||||||
std::unordered_map<int, def_attribute_modifier> modifier_map {};
|
std::unordered_map<int, def_attribute_modifier> modifier_map {};
|
||||||
std::unordered_map<int, patched_weapon_cookie> cookie_map {};
|
// A map that maps an Entity Index to a cookie
|
||||||
|
//std::unordered_map<int, patched_weapon_cookie> cookie_map {};
|
||||||
|
patched_weapon_cookie cookie { 0 };
|
||||||
|
|
||||||
}}}
|
}}}
|
||||||
|
@ -54,6 +54,7 @@ public:
|
|||||||
class CAttributeList {
|
class CAttributeList {
|
||||||
public:
|
public:
|
||||||
CAttributeList();
|
CAttributeList();
|
||||||
|
float GetAttribute(int defindex);
|
||||||
void SetAttribute(int index, float value);
|
void SetAttribute(int index, float value);
|
||||||
void RemoveAttribute(int index);
|
void RemoveAttribute(int index);
|
||||||
public:
|
public:
|
||||||
@ -66,7 +67,8 @@ enum class Attributes {
|
|||||||
is_australium_item = 2027,
|
is_australium_item = 2027,
|
||||||
item_style_override = 542,
|
item_style_override = 542,
|
||||||
sheen = 2014,
|
sheen = 2014,
|
||||||
killstreak_tier = 2025
|
killstreak_tier = 2025,
|
||||||
|
set_item_texture_wear = 725
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class UnusualEffects {
|
enum class UnusualEffects {
|
||||||
@ -76,6 +78,16 @@ enum class UnusualEffects {
|
|||||||
ENERGY_ORB
|
ENERGY_ORB
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class Sheens {
|
||||||
|
TEAM_SHINE = 1,
|
||||||
|
DEADLY_DAFFODIL,
|
||||||
|
MANNDARIN,
|
||||||
|
MEAN_GREEN,
|
||||||
|
AGONIZING_EMERALD,
|
||||||
|
VILLAINOUS_VIOLET,
|
||||||
|
HOT_ROD
|
||||||
|
};
|
||||||
|
|
||||||
struct patched_weapon_cookie {
|
struct patched_weapon_cookie {
|
||||||
patched_weapon_cookie(int entity);
|
patched_weapon_cookie(int entity);
|
||||||
void Update(int entity);
|
void Update(int entity);
|
||||||
@ -91,19 +103,24 @@ public:
|
|||||||
struct def_attribute_modifier {
|
struct def_attribute_modifier {
|
||||||
void Apply(int entity);
|
void Apply(int entity);
|
||||||
void Set(int id, float value);
|
void Set(int id, float value);
|
||||||
|
void Remove(int id);
|
||||||
int defidx { 0 };
|
int defidx { 0 };
|
||||||
int defidx_redirect { 0 };
|
int defidx_redirect { 0 };
|
||||||
std::array<attribute_s, 15> modifiers { attribute_s{ 0, 0 } };
|
std::vector<attribute_s> modifiers { };
|
||||||
int first_free_mod { 0 };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::unordered_map<int, def_attribute_modifier> modifier_map;
|
extern std::unordered_map<int, def_attribute_modifier> modifier_map;
|
||||||
extern std::unordered_map<int, patched_weapon_cookie> cookie_map;
|
extern patched_weapon_cookie cookie;
|
||||||
|
//extern std::unordered_map<int, patched_weapon_cookie> cookie_map;
|
||||||
|
|
||||||
def_attribute_modifier& GetModifier(int idx);
|
def_attribute_modifier& GetModifier(int idx);
|
||||||
patched_weapon_cookie& GetCookie(int idx);
|
//patched_weapon_cookie& GetCookie(int idx);
|
||||||
|
|
||||||
void InvalidateCookies();
|
constexpr unsigned SERIALIZE_VERSION = 1;
|
||||||
|
void Save(std::string filename);
|
||||||
|
void Load(std::string filename);
|
||||||
|
|
||||||
|
void InvalidateCookie();
|
||||||
void FrameStageNotify(int stage);
|
void FrameStageNotify(int stage);
|
||||||
void PaintTraverse();
|
void PaintTraverse();
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ void NetVars::Init() {
|
|||||||
this->iTeamNum = gNetvars.get_offset("DT_BaseEntity", "m_iTeamNum");
|
this->iTeamNum = gNetvars.get_offset("DT_BaseEntity", "m_iTeamNum");
|
||||||
this->vViewOffset = gNetvars.get_offset("DT_BasePlayer", "localdata", "m_vecViewOffset[0]");
|
this->vViewOffset = gNetvars.get_offset("DT_BasePlayer", "localdata", "m_vecViewOffset[0]");
|
||||||
this->hActiveWeapon = gNetvars.get_offset("DT_BaseCombatCharacter", "m_hActiveWeapon");
|
this->hActiveWeapon = gNetvars.get_offset("DT_BaseCombatCharacter", "m_hActiveWeapon");
|
||||||
|
this->hMyWeapons = gNetvars.get_offset("DT_BaseCombatCharacter", "m_hMyWeapons");
|
||||||
this->iHitboxSet = gNetvars.get_offset("DT_BaseAnimating", "m_nHitboxSet");
|
this->iHitboxSet = gNetvars.get_offset("DT_BaseAnimating", "m_nHitboxSet");
|
||||||
this->vVelocity = gNetvars.get_offset("DT_BasePlayer", "localdata", "m_vecVelocity[0]");
|
this->vVelocity = gNetvars.get_offset("DT_BasePlayer", "localdata", "m_vecVelocity[0]");
|
||||||
this->movetype = gNetvars.get_offset("DT_BaseEntity", "movetype");
|
this->movetype = gNetvars.get_offset("DT_BaseEntity", "movetype");
|
||||||
@ -30,7 +31,7 @@ void NetVars::Init() {
|
|||||||
//this->flReloadPriorNextFire = gNetvars.get_offset("DT_TFWeaponBase", "LocalActiveTFWeaponData", "m_flReloadPriorNextFire");
|
//this->flReloadPriorNextFire = gNetvars.get_offset("DT_TFWeaponBase", "LocalActiveTFWeaponData", "m_flReloadPriorNextFire");
|
||||||
//this->flObservedCritChance = gNetvars.get_offset("DT_TFWeaponBase", "LocalActiveTFWeaponData", "m_flObservedCritChance");
|
//this->flObservedCritChance = gNetvars.get_offset("DT_TFWeaponBase", "LocalActiveTFWeaponData", "m_flObservedCritChance");
|
||||||
this->iItemDefinitionIndex = gNetvars.get_offset("DT_EconEntity", "m_AttributeManager", "m_Item", "m_iItemDefinitionIndex");
|
this->iItemDefinitionIndex = gNetvars.get_offset("DT_EconEntity", "m_AttributeManager", "m_Item", "m_iItemDefinitionIndex");
|
||||||
this->AttributeList = gNetvars.get_offset("DT_EconEntity", "m_AttributeManager", "m_Item", "m_AttributeList") + 8; // hmmm
|
this->AttributeList = gNetvars.get_offset("DT_EconEntity", "m_AttributeManager", "m_Item", "m_AttributeList"); // hmmm
|
||||||
this->flChargeBeginTime = gNetvars.get_offset("DT_WeaponPipebombLauncher", "PipebombLauncherLocalData", "m_flChargeBeginTime");
|
this->flChargeBeginTime = gNetvars.get_offset("DT_WeaponPipebombLauncher", "PipebombLauncherLocalData", "m_flChargeBeginTime");
|
||||||
this->flLastFireTime = gNetvars.get_offset("DT_TFWeaponBase", "LocalActiveTFWeaponData", "m_flLastFireTime");
|
this->flLastFireTime = gNetvars.get_offset("DT_TFWeaponBase", "LocalActiveTFWeaponData", "m_flLastFireTime");
|
||||||
this->bDistributed = gNetvars.get_offset("DT_CurrencyPack", "m_bDistributed");
|
this->bDistributed = gNetvars.get_offset("DT_CurrencyPack", "m_bDistributed");
|
||||||
@ -77,7 +78,6 @@ void NetVars::Init() {
|
|||||||
this->vecPunchAngle = gNetvars.get_offset("DT_BasePlayer", "localdata", "m_Local", "m_vecPunchAngle");
|
this->vecPunchAngle = gNetvars.get_offset("DT_BasePlayer", "localdata", "m_Local", "m_vecPunchAngle");
|
||||||
this->vecPunchAngleVel = gNetvars.get_offset("DT_BasePlayer", "localdata", "m_Local", "m_vecPunchAngleVel");
|
this->vecPunchAngleVel = gNetvars.get_offset("DT_BasePlayer", "localdata", "m_Local", "m_vecPunchAngleVel");
|
||||||
this->hThrower = gNetvars.get_offset("DT_BaseGrenade", "m_hThrower");
|
this->hThrower = gNetvars.get_offset("DT_BaseGrenade", "m_hThrower");
|
||||||
this->hMyWeapons = gNetvars.get_offset("DT_BaseCombatCharacter", "m_hMyWeapons");
|
|
||||||
this->iObserverMode = gNetvars.get_offset("DT_BasePlayer", "m_iObserverMode");
|
this->iObserverMode = gNetvars.get_offset("DT_BasePlayer", "m_iObserverMode");
|
||||||
this->hObserverTarget = gNetvars.get_offset("DT_BasePlayer", "m_hObserverTarget");
|
this->hObserverTarget = gNetvars.get_offset("DT_BasePlayer", "m_hObserverTarget");
|
||||||
this->deadflag = gNetvars.get_offset("DT_BasePlayer", "pl", "deadflag");
|
this->deadflag = gNetvars.get_offset("DT_BasePlayer", "pl", "deadflag");
|
||||||
|
Reference in New Issue
Block a user