mirror of
https://github.com/0TheSpy/Seaside.git
synced 2025-01-11 03:32:10 +08:00
397 lines
10 KiB
C++
397 lines
10 KiB
C++
#pragma once
|
|
#include "ProtoParse.h"
|
|
#include "ProtobuffMessages.h"
|
|
#include <ctime>
|
|
|
|
#include "Options.hpp"
|
|
|
|
struct wskin
|
|
{
|
|
int wId;
|
|
int paintkit;
|
|
};
|
|
|
|
#define START_MUSICKIT_INDEX 1500000
|
|
#define START_ITEM_INDEX 2000000
|
|
|
|
static void clear_equip_state(CMsgClientWelcome::SubscribedType& object);
|
|
static void apply_medals(CMsgClientWelcome::SubscribedType& object);
|
|
static void apply_music_kits(CMsgClientWelcome::SubscribedType& object);
|
|
|
|
static void add_item(CMsgClientWelcome::SubscribedType& object, int index, ItemDefinitionIndex itemIndex, int quality, int rarity, int paintKit, int seed, float wear, std::string name, std::string desc, sticker stickers[5], int stattrak, int flag);
|
|
|
|
static int GetAvailableClassID(int definition_index);
|
|
static int GetSlotID(int definition_index);
|
|
static std::vector<uint32_t> music_kits = { 3, 4, 5, 6, 7, 8 };
|
|
|
|
|
|
template<typename T>
|
|
inline std::string get_4bytes(T value)
|
|
{
|
|
return std::string{ reinterpret_cast<const char*>(reinterpret_cast<void*>(&value)), 4 };
|
|
}
|
|
|
|
template<typename T>
|
|
inline CSOEconItemAttribute make_econ_item_attribute(int def_index, T value)
|
|
{
|
|
CSOEconItemAttribute attribute;
|
|
attribute.def_index().set(def_index);
|
|
attribute.value_bytes().set(get_4bytes(value));
|
|
return attribute;
|
|
}
|
|
|
|
inline CSOEconItemEquipped make_equipped_state(int team, int slot)
|
|
{
|
|
CSOEconItemEquipped equipped_state;
|
|
equipped_state.new_class().set(team);
|
|
equipped_state.new_slot().set(slot);
|
|
return equipped_state;
|
|
}
|
|
|
|
static std::string inventory_changer(void* pubDest, uint32_t* pcubMsgSize) {
|
|
CMsgClientWelcome msg((void*)((DWORD)pubDest + 8), *pcubMsgSize - 8);
|
|
if (!msg.outofdate_subscribed_caches().has())
|
|
return msg.serialize();
|
|
|
|
auto cache = msg.outofdate_subscribed_caches().get();
|
|
|
|
static auto fix_null_inventory = [&cache]()
|
|
{
|
|
auto objects = cache.objects().get_all();
|
|
auto it = std::find_if(objects.begin(), objects.end(), [](decltype(objects.front()) o)
|
|
{
|
|
return o.type_id().has() && o.type_id().get() == 1;
|
|
});
|
|
|
|
if (it == objects.end())
|
|
{
|
|
CMsgClientWelcome::SubscribedType null_object;
|
|
null_object.type_id().set(1);
|
|
cache.objects().add(null_object);
|
|
}
|
|
};
|
|
|
|
fix_null_inventory();
|
|
|
|
auto objects = cache.objects().get_all();
|
|
for (size_t i = 0; i < objects.size(); i++) {
|
|
auto object = objects[i];
|
|
|
|
if (!object.type_id().has())
|
|
continue;
|
|
|
|
switch (object.type_id().get())
|
|
{
|
|
case 1:
|
|
{
|
|
if (true)
|
|
object.object_data().clear();
|
|
|
|
int indexcount = 0;
|
|
|
|
for (int i = 0; i < g_Options.weapons.value->weaponzcount; i++)
|
|
if (g_Options.weapons.value->arr[i].active) {
|
|
indexcount++;
|
|
add_item(object, indexcount,
|
|
(ItemDefinitionIndex)g_Options.weapons.value->arr[i].modeldefindex,
|
|
g_Options.weapons.value->arr[i].quality,
|
|
g_Options.weapons.value->arr[i].rarity,
|
|
g_Options.weapons.value->arr[i].skinid,
|
|
g_Options.weapons.value->arr[i].seed,
|
|
g_Options.weapons.value->arr[i].wear,
|
|
g_Options.weapons.value->arr[i].nametag,
|
|
g_Options.weapons.value->arr[i].desctag,
|
|
g_Options.weapons.value->arr[i].stickers,
|
|
g_Options.weapons.value->arr[i].stattrak,
|
|
i);
|
|
}
|
|
|
|
cache.objects().set(object, i);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
msg.outofdate_subscribed_caches().set(cache);
|
|
|
|
return msg.serialize();
|
|
}
|
|
|
|
static bool inventory_changer_presend(void* pubData, uint32_t& cubData)
|
|
{
|
|
CMsgAdjustItemEquippedState msg((void*)((DWORD)pubData + 8), cubData - 8);
|
|
if (msg.item_id().has() && (msg.new_class().get() == 0 || msg.new_slot().get() == 54))
|
|
{
|
|
auto ItemIndex = msg.item_id().get() - START_MUSICKIT_INDEX;
|
|
|
|
if (ItemIndex > 38 || ItemIndex < 3)
|
|
return true;
|
|
|
|
msg.new_slot().get() == 0xFFFF ? 0 : ItemIndex - 2;
|
|
|
|
return false;
|
|
}
|
|
if (!msg.item_id().has() || !msg.new_class().get() || !msg.new_slot().get())
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
static void clear_equip_state(CMsgClientWelcome::SubscribedType& object)
|
|
{
|
|
auto object_data = object.object_data().get_all();
|
|
for (size_t j = 0; j < object_data.size(); j++)
|
|
{
|
|
auto item = object_data[j];
|
|
|
|
if (!item.equipped_state().has())
|
|
continue;
|
|
|
|
auto null_equipped_state = make_equipped_state(0, 0);
|
|
|
|
auto equipped_state = item.equipped_state().get_all();
|
|
for (size_t k = 0; k < equipped_state.size(); k++)
|
|
item.equipped_state().set(null_equipped_state, k);
|
|
|
|
object.object_data().set(item, j);
|
|
}
|
|
}
|
|
|
|
|
|
static void add_item(CMsgClientWelcome::SubscribedType& object, int index, ItemDefinitionIndex itemIndex, int quality, int rarity, int paintKit, int seed, float wear, std::string name, std::string desc, sticker stickers[5], int stattrak, int flag)
|
|
{
|
|
uint32_t steamid = iff.g_SteamUser->GetSteamID().GetAccountID();
|
|
|
|
CSOEconItem item;
|
|
item.id().set(START_ITEM_INDEX + itemIndex);
|
|
item.account_id().set(steamid);
|
|
if (flag == 5)
|
|
item.def_index().set(1314);
|
|
else item.def_index().set(itemIndex);
|
|
item.inventory().set(START_ITEM_INDEX + index);
|
|
item.origin().set(24);
|
|
item.quantity().set(1);
|
|
item.level().set(1);
|
|
item.style().set(0);
|
|
item.flags().set(0);
|
|
item.in_use().set(true);
|
|
item.original_id().set(0);
|
|
item.rarity().set(rarity);
|
|
item.quality().set(quality);
|
|
|
|
if (name.size() > 0)
|
|
item.custom_name().set(name);
|
|
|
|
if (desc.size() > 0)
|
|
item.custom_desc().set(desc);
|
|
|
|
if (flag > 5) {
|
|
int avalTeam = GetAvailableClassID(itemIndex);
|
|
if (avalTeam == TEAM_SPECTATOR || avalTeam == TEAM_TERRORIST) {
|
|
item.equipped_state().add(make_equipped_state(TEAM_TERRORIST, GetSlotID(itemIndex)));
|
|
}
|
|
if (avalTeam == TEAM_SPECTATOR || avalTeam == TEAM_CT) {
|
|
item.equipped_state().add(make_equipped_state(TEAM_CT, GetSlotID(itemIndex)));
|
|
}
|
|
}
|
|
|
|
item.attribute().add(make_econ_item_attribute(6, float(paintKit)));
|
|
item.attribute().add(make_econ_item_attribute(7, float(seed)));
|
|
item.attribute().add(make_econ_item_attribute(8, float(wear)));
|
|
|
|
|
|
for (int j = 0; j < 5; j++)
|
|
{
|
|
item.attribute().add(make_econ_item_attribute(113 + 4 * j, stickers[j].stickerid ));
|
|
item.attribute().add(make_econ_item_attribute(114 + 4 * j, stickers[j].wear));
|
|
item.attribute().add(make_econ_item_attribute(115 + 4 * j, stickers[j].scale));
|
|
item.attribute().add(make_econ_item_attribute(116 + 4 * j, stickers[j].rotation));
|
|
}
|
|
|
|
if (stattrak != -1)
|
|
{
|
|
item.attribute().add(make_econ_item_attribute(80, stattrak));
|
|
item.attribute().add(make_econ_item_attribute(81, 0));
|
|
}
|
|
|
|
if (flag == 0)
|
|
{
|
|
item.equipped_state().add(make_equipped_state(TEAM_TERRORIST, 0));
|
|
item.equipped_state().add(make_equipped_state(TEAM_CT, 0));
|
|
}
|
|
|
|
if (flag == 1)
|
|
{
|
|
item.equipped_state().add(make_equipped_state(TEAM_TERRORIST, 41));
|
|
item.equipped_state().add(make_equipped_state(TEAM_CT, 41));
|
|
}
|
|
|
|
if (flag == 2)
|
|
item.equipped_state().set(make_equipped_state(2, 38));
|
|
|
|
if (flag == 3)
|
|
item.equipped_state().set(make_equipped_state(3, 38));
|
|
|
|
|
|
if (flag == 4)
|
|
item.equipped_state().set(make_equipped_state(0, 55));
|
|
|
|
|
|
if (flag == 5)
|
|
{
|
|
item.attribute().add(make_econ_item_attribute(166, itemIndex));
|
|
item.inventory().set(START_MUSICKIT_INDEX + itemIndex);
|
|
item.id().set(START_MUSICKIT_INDEX + itemIndex);
|
|
item.equipped_state().set(make_equipped_state(0, 54));
|
|
}
|
|
|
|
object.object_data().add(item);
|
|
}
|
|
|
|
static int GetAvailableClassID(int definition_index)
|
|
{
|
|
switch (definition_index)
|
|
{
|
|
case WEAPON_KNIFE_BAYONET:
|
|
case WEAPON_KNIFE_FLIP:
|
|
case WEAPON_KNIFE_GUT:
|
|
case WEAPON_KNIFE_KARAMBIT:
|
|
case WEAPON_KNIFE_M9_BAYONET:
|
|
case WEAPON_KNIFE_TACTICAL:
|
|
case WEAPON_KNIFE_FALCHION:
|
|
case WEAPON_KNIFE_SURVIVAL_BOWIE:
|
|
case WEAPON_KNIFE_BUTTERFLY:
|
|
case WEAPON_KNIFE_PUSH:
|
|
case WEAPON_ELITE:
|
|
case WEAPON_P250:
|
|
case WEAPON_CZ75A:
|
|
case WEAPON_DEAGLE:
|
|
case WEAPON_REVOLVER:
|
|
case WEAPON_MP7:
|
|
case WEAPON_UMP45:
|
|
case WEAPON_P90:
|
|
case WEAPON_BIZON:
|
|
case WEAPON_SSG08:
|
|
case WEAPON_AWP:
|
|
case WEAPON_NOVA:
|
|
case WEAPON_XM1014:
|
|
case WEAPON_M249:
|
|
case WEAPON_NEGEV:
|
|
case GLOVE_STUDDED_BLOODHOUND:
|
|
case GLOVE_SPORTY:
|
|
case GLOVE_SLICK:
|
|
case GLOVE_LEATHER_WRAP:
|
|
case GLOVE_MOTORCYCLE:
|
|
case GLOVE_SPECIALIST:
|
|
return TEAM_SPECTATOR;
|
|
|
|
case WEAPON_GLOCK:
|
|
case WEAPON_AK47:
|
|
case WEAPON_MAC10:
|
|
case WEAPON_G3SG1:
|
|
case WEAPON_TEC9:
|
|
case WEAPON_GALILAR:
|
|
case WEAPON_SG553:
|
|
case WEAPON_SAWEDOFF:
|
|
case WEAPON_C4:
|
|
return TEAM_TERRORIST;
|
|
|
|
case WEAPON_AUG:
|
|
case WEAPON_FAMAS:
|
|
case WEAPON_MAG7:
|
|
case WEAPON_FIVESEVEN:
|
|
case WEAPON_USP_SILENCER:
|
|
case WEAPON_HKP2000:
|
|
case WEAPON_MP9:
|
|
case WEAPON_M4A1_SILENCER:
|
|
case WEAPON_M4A1:
|
|
case WEAPON_SCAR20:
|
|
return TEAM_CT;
|
|
|
|
default:
|
|
return TEAM_UNASSIGNED;
|
|
}
|
|
}
|
|
|
|
static int GetSlotID(int definition_index)
|
|
{
|
|
switch (definition_index)
|
|
{
|
|
case WEAPON_KNIFE_BAYONET:
|
|
case WEAPON_KNIFE_FLIP:
|
|
case WEAPON_KNIFE_GUT:
|
|
case WEAPON_KNIFE_KARAMBIT:
|
|
case WEAPON_KNIFE_M9_BAYONET:
|
|
case WEAPON_KNIFE_TACTICAL:
|
|
case WEAPON_KNIFE_FALCHION:
|
|
case WEAPON_KNIFE_SURVIVAL_BOWIE:
|
|
case WEAPON_KNIFE_BUTTERFLY:
|
|
case WEAPON_KNIFE_PUSH:
|
|
return 0;
|
|
case WEAPON_C4:
|
|
return 1;
|
|
case WEAPON_USP_SILENCER:
|
|
case WEAPON_HKP2000:
|
|
case WEAPON_GLOCK:
|
|
return 2;
|
|
case WEAPON_ELITE:
|
|
return 3;
|
|
case WEAPON_P250:
|
|
return 4;
|
|
case WEAPON_TEC9:
|
|
case WEAPON_CZ75A:
|
|
case WEAPON_FIVESEVEN:
|
|
return 5;
|
|
case WEAPON_DEAGLE:
|
|
case WEAPON_REVOLVER:
|
|
return 6;
|
|
case WEAPON_MP9:
|
|
case WEAPON_MAC10:
|
|
return 8;
|
|
case WEAPON_MP7:
|
|
return 9;
|
|
case WEAPON_UMP45:
|
|
return 10;
|
|
case WEAPON_P90:
|
|
return 11;
|
|
case WEAPON_BIZON:
|
|
return 12;
|
|
case WEAPON_FAMAS:
|
|
case WEAPON_GALILAR:
|
|
return 14;
|
|
case WEAPON_M4A1_SILENCER:
|
|
case WEAPON_M4A1:
|
|
case WEAPON_AK47:
|
|
return 15;
|
|
case WEAPON_SSG08:
|
|
return 16;
|
|
case WEAPON_SG553:
|
|
case WEAPON_AUG:
|
|
return 17;
|
|
case WEAPON_AWP:
|
|
return 18;
|
|
case WEAPON_G3SG1:
|
|
case WEAPON_SCAR20:
|
|
return 19;
|
|
case WEAPON_NOVA:
|
|
return 20;
|
|
case WEAPON_XM1014:
|
|
return 21;
|
|
case WEAPON_SAWEDOFF:
|
|
case WEAPON_MAG7:
|
|
return 22;
|
|
case WEAPON_M249:
|
|
return 23;
|
|
case WEAPON_NEGEV:
|
|
return 24;
|
|
case GLOVE_STUDDED_BLOODHOUND:
|
|
case GLOVE_SPORTY:
|
|
case GLOVE_SLICK:
|
|
case GLOVE_LEATHER_WRAP:
|
|
case GLOVE_MOTORCYCLE:
|
|
case GLOVE_SPECIALIST:
|
|
return 41;
|
|
default:
|
|
return -1;
|
|
}
|
|
} |