(still untested) More splitting and cleanup
This commit is contained in:
@@ -222,7 +222,7 @@ void FindFiles(WIN32_FIND_DATAW* fd)
|
||||
{
|
||||
if (fd->cFileName[0] == '.' && fd->cFileName[1] == '_') continue; // exclude macOS metadata
|
||||
|
||||
if (!_wcsicmp(fd->cFileName, L"Patches.dva") || !_wcsicmp(fd->cFileName, L"Render.dva") || !_wcsicmp(fd->cFileName, L"DivaWig.dva"))
|
||||
if (!_wcsicmp(fd->cFileName, L"Patches.dva") || !_wcsicmp(fd->cFileName, L"Render.dva"))
|
||||
{
|
||||
DeleteFileW(fd->cFileName);
|
||||
continue;
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{84DBD504-6220-1BCE-A7E4-6799DAF7C5BF}</ProjectGuid>
|
||||
<RootNamespace>CustoMixer</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>CustoMixer</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<TargetExt>.dva</TargetExt>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<TargetExt>.dva</TargetExt>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>-d2FH4- /utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalLibraryDirectories>..\..\..\dependencies\detours\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>evr.lib;mfplat.lib;mfuuid.lib;strmiids.lib;syelog.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalOptions>-d2:-FH4- %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<AdditionalOptions>-d2FH4- /utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>evr.lib;mfplat.lib;mfuuid.lib;syelog.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\..\..\dependencies\detours\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>-d2:-FH4- %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="PluginConfigApi.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="PluginConfigApi.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,168 @@
|
||||
#pragma once
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
#include <windows.h>
|
||||
#include <vector>
|
||||
|
||||
// resolution class to store and sort the width and height easily
|
||||
class resolution
|
||||
{
|
||||
public:
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
|
||||
resolution()
|
||||
{
|
||||
width = 0;
|
||||
height = 0;
|
||||
}
|
||||
|
||||
resolution(unsigned int width, unsigned int height)
|
||||
{
|
||||
resolution::width = width;
|
||||
resolution::height = height;
|
||||
}
|
||||
|
||||
bool operator ==(const resolution &res2)
|
||||
{
|
||||
return width == res2.width && height == res2.height;
|
||||
}
|
||||
|
||||
// in comparisons width takes priority because it's usually displayed first
|
||||
bool operator <(const resolution &res2)
|
||||
{
|
||||
if (width == res2.width)
|
||||
return height < res2.height;
|
||||
else
|
||||
return width < res2.width;
|
||||
}
|
||||
bool operator >(const resolution &res2)
|
||||
{
|
||||
if (width == res2.width)
|
||||
return height > res2.height;
|
||||
else
|
||||
return width > res2.width;
|
||||
}
|
||||
};
|
||||
|
||||
namespace PluginConfig
|
||||
{
|
||||
#pragma pack(push, 1)
|
||||
enum ConfigType {
|
||||
CONFIG_BOOLEAN,
|
||||
CONFIG_NUMERIC,
|
||||
CONFIG_STRING,
|
||||
CONFIG_DROPDOWN_INDEX,
|
||||
CONFIG_DROPDOWN_TEXT,
|
||||
CONFIG_DROPDOWN_NUMBER,
|
||||
CONFIG_RESOLUTION,
|
||||
CONFIG_GROUP_START,
|
||||
CONFIG_GROUP_END,
|
||||
CONFIG_BUTTON,
|
||||
CONFIG_SPACER
|
||||
};
|
||||
|
||||
struct PluginConfigBooleanData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
bool defaultVal;
|
||||
bool saveAsString;
|
||||
};
|
||||
|
||||
struct PluginConfigNumericData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
int defaultVal;
|
||||
int minVal;
|
||||
int maxVal;
|
||||
};
|
||||
|
||||
struct PluginConfigStringData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
LPCWSTR defaultVal;
|
||||
bool useUtf8;
|
||||
};
|
||||
|
||||
struct PluginConfigDropdownIndexData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
int defaultVal;
|
||||
std::vector<LPCWSTR> valueStrings;
|
||||
};
|
||||
|
||||
struct PluginConfigDropdownTextData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
LPCWSTR defaultVal;
|
||||
std::vector<LPCWSTR> valueStrings;
|
||||
bool editable;
|
||||
bool useUtf8;
|
||||
};
|
||||
|
||||
struct PluginConfigDropdownNumberData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
int defaultVal;
|
||||
std::vector<int> valueInts;
|
||||
bool editable;
|
||||
};
|
||||
|
||||
struct PluginConfigResolutionData {
|
||||
LPCWSTR iniVarName;
|
||||
LPCWSTR iniVarName2;
|
||||
LPCWSTR iniSectionName;
|
||||
LPCWSTR iniFilePath;
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
resolution defaultVal;
|
||||
std::vector<resolution> valueResolutions;
|
||||
bool editable;
|
||||
};
|
||||
|
||||
struct PluginConfigGroupData
|
||||
{
|
||||
LPCWSTR name;
|
||||
int height;
|
||||
};
|
||||
|
||||
struct PluginConfigButtonData {
|
||||
LPCWSTR friendlyName;
|
||||
LPCWSTR description;
|
||||
void(*func)();
|
||||
};
|
||||
|
||||
struct PluginConfigSpacerData {
|
||||
int height;
|
||||
};
|
||||
|
||||
struct PluginConfigOption
|
||||
{
|
||||
ConfigType cfgType;
|
||||
void* data;
|
||||
};
|
||||
|
||||
struct PluginConfigArray
|
||||
{
|
||||
int len;
|
||||
PluginConfigOption* options;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
#include "PluginConfigApi.h"
|
||||
#include "framework.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int nNoHandScaling, nDefaultHandSize, nForceMouth, nForceExpressions, nForceLook;
|
||||
|
||||
void loadConfig()
|
||||
{
|
||||
nNoHandScaling = GetPrivateProfileIntW(L"patches", L"no_hand_scaling", FALSE, CONFIG_FILE) > 0 ? true : false;
|
||||
nDefaultHandSize = GetPrivateProfileIntW(L"patches", L"default_hand_size", -1, CONFIG_FILE);
|
||||
nForceMouth = GetPrivateProfileIntW(L"patches", L"force_mouth", 0, CONFIG_FILE);
|
||||
nForceExpressions = GetPrivateProfileIntW(L"patches", L"force_expressions", 0, CONFIG_FILE);
|
||||
nForceLook = GetPrivateProfileIntW(L"patches", L"force_look", 0, CONFIG_FILE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void pvPatches()
|
||||
{
|
||||
puts("[CustoMixer] Applying PV patches...");
|
||||
|
||||
// Force mouth animations
|
||||
{
|
||||
if (nForceMouth == 1) // PDA
|
||||
{
|
||||
printf("[CustoMixer] Forcing PDA mouth...\n");
|
||||
int* mouth_table = (int*)(0x1409A1DC0);
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(mouth_table, 44, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
for (int i = 0; i < 11; i++)
|
||||
{
|
||||
mouth_table[i]++;
|
||||
}
|
||||
VirtualProtect(mouth_table, 44, oldProtect, nullptr);
|
||||
printf("[CustoMixer] PDA mouth forced\n");
|
||||
}
|
||||
else if (nForceMouth == 2) // FT
|
||||
{
|
||||
printf("[CustoMixer] Forcing FT mouth...\n");
|
||||
int* mouth_table_oldid = (int*)(0x1409A1E1C);
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(mouth_table_oldid, 44, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
for (int i = 0; i < 11; i++)
|
||||
{
|
||||
mouth_table_oldid[i]--;
|
||||
}
|
||||
VirtualProtect(mouth_table_oldid, 44, oldProtect, nullptr);
|
||||
printf("[CustoMixer] FT mouth forced\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Force expressions
|
||||
{
|
||||
if (nForceExpressions == 1) // PDA
|
||||
{
|
||||
printf("[CustoMixer] Forcing PDA expressions...\n");
|
||||
int* exp_table = (int*)(0x140A21900);
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(exp_table, 104, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
for (int i = 0; i < 26; i++)
|
||||
{
|
||||
exp_table[i] += 2;
|
||||
}
|
||||
VirtualProtect(exp_table, 104, oldProtect, nullptr);
|
||||
printf("[CustoMixer] PDA expressions forced\n");
|
||||
}
|
||||
else if (nForceExpressions == 2) // FT
|
||||
{
|
||||
printf("[CustoMixer] Forcing FT expressions...\n");
|
||||
int* exp_table_oldid = (int*)(0x140A219D0);
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(exp_table_oldid, 104, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
for (int i = 0; i < 26; i++)
|
||||
{
|
||||
exp_table_oldid[i] -= 2;
|
||||
}
|
||||
VirtualProtect(exp_table_oldid, 104, oldProtect, nullptr);
|
||||
printf("[CustoMixer] FT expressions forced\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Force look animations
|
||||
{
|
||||
if (nForceLook == 1) // PDA
|
||||
{
|
||||
printf("[CustoMixer] Forcing PDA look...\n");
|
||||
int* look_table = (int*)(0x1409A1D70);
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(look_table, 36, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
look_table[i]++;
|
||||
}
|
||||
VirtualProtect(look_table, 36, oldProtect, nullptr);
|
||||
printf("[CustoMixer] PDA look forced\n");
|
||||
}
|
||||
else if (nForceLook == 2) // FT
|
||||
{
|
||||
printf("[CustoMixer] Forcing FT look...\n");
|
||||
int* look_table_oldid = (int*)(0x1409A1D9C);
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(look_table_oldid, 36, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
look_table_oldid[i]--;
|
||||
}
|
||||
VirtualProtect(look_table_oldid, 36, oldProtect, nullptr);
|
||||
printf("[CustoMixer] FT look forced\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Disable hand scaling
|
||||
if (nNoHandScaling)
|
||||
{
|
||||
InjectCode((void*)0x0000000140120709, { 0xE9, 0x82, 0x0A, 0x00 });
|
||||
}
|
||||
|
||||
// Default hand size
|
||||
if (nDefaultHandSize != -1 && nDefaultHandSize < 1)
|
||||
{
|
||||
MessageBoxW(nullptr, L"The default hand size is lower than 1 and higher than -1 (default). Hands may disappear.\n\nIf this is not intentional, set it back to -1.", L"DivaWig", MB_ICONWARNING);
|
||||
|
||||
printf("[CustoMixer] Changing default hand size...\n");
|
||||
const float num = (float)nDefaultHandSize / 10000.0;
|
||||
DWORD oldProtect;
|
||||
float* addr1 = (float*)(0x140506B59);
|
||||
float* addr2 = (float*)(0x140506B60);
|
||||
/*float* addr3 = (float*)(0x140506B67);
|
||||
float* addr4 = (float*)(0x140506B71);*/
|
||||
VirtualProtect(addr1, 4, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
VirtualProtect(addr2, 4, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
/*VirtualProtect(addr3, 4, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
VirtualProtect(addr4, 4, PAGE_EXECUTE_READWRITE, &oldProtect);*/
|
||||
*addr1 = *addr2 /*= *addr3 = *addr4*/ = num;
|
||||
VirtualProtect(addr1, 4, oldProtect, nullptr);
|
||||
VirtualProtect(addr2, 4, oldProtect, nullptr);
|
||||
/*VirtualProtect(addr3, 4, oldProtect, nullptr);
|
||||
VirtualProtect(addr4, 4, oldProtect, nullptr);*/
|
||||
printf("[CustoMixer] New default hand size: %f\n", num);
|
||||
}
|
||||
|
||||
puts("[CustoMixer] PV patches applied.");
|
||||
}
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
loadConfig();
|
||||
pvPatches();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const std::vector<LPCWSTR> typeList = { L"Default", L"PDA", L"PDAFT/PDFT/PDM39" };
|
||||
|
||||
PluginConfig::PluginConfigOption config[] = {
|
||||
{ PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"no_hand_scaling", L"patches", CONFIG_FILE, L"No Hand Scaling", L"Disable scripted hand scaling.", false } },
|
||||
{ PluginConfig::CONFIG_NUMERIC, new PluginConfig::PluginConfigNumericData{ L"default_hand_size", L"patches", CONFIG_FILE, L"Default Hand Size:", L"-1: default\n12200: PDA", -1, -1, INT_MAX } },
|
||||
{ PluginConfig::CONFIG_DROPDOWN_INDEX, new PluginConfig::PluginConfigDropdownIndexData{ L"force_mouth", L"patches", CONFIG_FILE, L"Mouth Animations:", L"Change the mouth animations.", 0, typeList}},
|
||||
{ PluginConfig::CONFIG_DROPDOWN_INDEX, new PluginConfig::PluginConfigDropdownIndexData{ L"force_expressions", L"patches", CONFIG_FILE, L"Expr. Animations:", L"Change the expressions.", 0, typeList}},
|
||||
{ PluginConfig::CONFIG_DROPDOWN_INDEX, new PluginConfig::PluginConfigDropdownIndexData{ L"force_look", L"patches", CONFIG_FILE, L"Look Animations:", L"Change the look animations.", 0, typeList}},
|
||||
};
|
||||
|
||||
extern "C" __declspec(dllexport) LPCWSTR GetPluginName(void)
|
||||
{
|
||||
return L"CustoMixer";
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) LPCWSTR GetPluginDescription(void)
|
||||
{
|
||||
return L"CustoMixer Plugin by nas\n\DivaWig lets you change some PV settings.";
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) PluginConfig::PluginConfigArray GetPluginOptions(void)
|
||||
{
|
||||
return PluginConfig::PluginConfigArray{ _countof(config), config };
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
|
||||
void InjectCode(void* address, const std::vector<uint8_t> data)
|
||||
{
|
||||
const size_t byteCount = data.size() * sizeof(uint8_t);
|
||||
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(address, byteCount, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
memcpy(address, data.data(), byteCount);
|
||||
VirtualProtect(address, byteCount, oldProtect, nullptr);
|
||||
}
|
||||
|
||||
std::wstring ExePath() {
|
||||
WCHAR buffer[MAX_PATH];
|
||||
GetModuleFileNameW(NULL, buffer, MAX_PATH);
|
||||
return std::wstring(buffer);
|
||||
}
|
||||
|
||||
std::wstring DirPath() {
|
||||
std::wstring exepath = ExePath();
|
||||
std::wstring::size_type pos = exepath.find_last_of(L"\\/");
|
||||
return exepath.substr(0, pos);
|
||||
}
|
||||
|
||||
std::wstring CONFIG_FILE_STRING = DirPath() + L"\\plugins\\CustoMixer.ini";
|
||||
LPCWSTR CONFIG_FILE = CONFIG_FILE_STRING.c_str();
|
||||
@@ -15,7 +15,7 @@
|
||||
<ProjectGuid>{2394C586-F73B-4EF2-BA3E-2A0FC3034B1A}</ProjectGuid>
|
||||
<RootNamespace>DivaWig</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>CustoMixer</ProjectName>
|
||||
<ProjectName>DivaWig</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
|
||||
@@ -7,33 +7,36 @@
|
||||
#include <tchar.h>
|
||||
#include <thread>
|
||||
|
||||
#define HEAD_ACCESSORY 0
|
||||
#define HAIR 1
|
||||
#define UNKNOWN_1 2
|
||||
#define UNKNOWN_2 3
|
||||
#define FACE_ACCESSORY 4
|
||||
#define UNKNOWN_3 5
|
||||
#define FACE_TEXTURES 6
|
||||
#define UNKNOWN_4 7
|
||||
#define CHEST_ACCESSORY 8
|
||||
#define UNKNOWN_5 9
|
||||
#define BODY 10
|
||||
#define UNKNOWN_6 11
|
||||
#define UNKNOWN_7 12
|
||||
#define UNKNOWN_8 13
|
||||
#define HANDS 14,
|
||||
#define UNKNOWN_9 15
|
||||
#define BACK_ACCESSORY 16
|
||||
#define UNKNOWN_10 17
|
||||
#define UNKNOWN_11 18
|
||||
#define UNKNOWN_12 19
|
||||
#define UNKNOWN_13 20
|
||||
#define UNKNOWN_14 21
|
||||
#define UNKNOWN_15 22
|
||||
#define UNKNOWN_16 23
|
||||
#define HEAD 24
|
||||
#define ALL -1
|
||||
#define NONE -2
|
||||
static const enum module_part
|
||||
{
|
||||
HEAD_ACCESSORY,
|
||||
HAIR,
|
||||
UNKNOWN_1,
|
||||
UNKNOWN_2,
|
||||
FACE_ACCESSORY,
|
||||
UNKNOWN_3,
|
||||
FACE_TEXTURES,
|
||||
UNKNOWN_4,
|
||||
CHEST_ACCESSORY,
|
||||
UNKNOWN_5,
|
||||
BODY,
|
||||
UNKNOWN_6,
|
||||
UNKNOWN_7,
|
||||
UNKNOWN_8,
|
||||
HANDS,
|
||||
UNKNOWN_9,
|
||||
BACK_ACCESSORY,
|
||||
UNKNOWN_10,
|
||||
UNKNOWN_11,
|
||||
UNKNOWN_12,
|
||||
UNKNOWN_13,
|
||||
UNKNOWN_14,
|
||||
UNKNOWN_15,
|
||||
UNKNOWN_16,
|
||||
HEAD,
|
||||
ALL = -1,
|
||||
NONE = -2
|
||||
};
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -47,12 +50,7 @@ void(__cdecl* loadFunc)(uint64_t* classp, unsigned int unk, __int64 performer) =
|
||||
const string Strings[25] = { "Head accessory", "Hair", "Unknown 1", "Unknown 2", "Face accessory", "Unknown 3", "Face textures", "Unknown 4", "Chest accessory", "Unknown 5", "Body", "Unknown 6", "Unknown 7", "Unknown 8", "Hands", "Unknown 9", "Back accessory", "Unknown 10", "Unknown 11", "Unknown 12", "Unknown 13", "Unknown 14", "Unknown 15", "Unknown 16", "Head" };
|
||||
char part_to_update = -1;
|
||||
|
||||
/*uint64_t *last_unload_a1 = 0, *last_reload_a1 = 0;
|
||||
unsigned int last_unload_a2 = 0, last_reload_a2 = 0;
|
||||
__int64 last_unload_a3 = 0, last_reload_a3 = 0;*/
|
||||
|
||||
bool dobeep = true, allowReloading = true, debug = false;
|
||||
int nNoHandScaling, nDefaultHandSize, nSingMissed, nForceMouth, nForceExpressions, nForceLook;
|
||||
|
||||
void loadConfig()
|
||||
{
|
||||
@@ -60,155 +58,13 @@ void loadConfig()
|
||||
allowReloading = GetPrivateProfileIntW(L"wig", L"reloading", 0, CONFIG_FILE) > 0 ? true : false;
|
||||
debug = GetPrivateProfileIntW(L"general", L"debug", 0, CONFIG_FILE) > 0 ? true : false;
|
||||
|
||||
nSingMissed = GetPrivateProfileIntW(L"patches", L"sing_missed", FALSE, CONFIG_FILE) > 0 ? true : false;
|
||||
nNoHandScaling = GetPrivateProfileIntW(L"patches", L"no_hand_scaling", FALSE, CONFIG_FILE) > 0 ? true : false;
|
||||
nDefaultHandSize = GetPrivateProfileIntW(L"patches", L"default_hand_size", -1, CONFIG_FILE);
|
||||
nForceMouth = GetPrivateProfileIntW(L"patches", L"force_mouth", 0, CONFIG_FILE);
|
||||
nForceExpressions = GetPrivateProfileIntW(L"patches", L"force_expressions", 0, CONFIG_FILE);
|
||||
nForceLook = GetPrivateProfileIntW(L"patches", L"force_look", 0, CONFIG_FILE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void pvPatches()
|
||||
{
|
||||
cout << "[CustoMixer] Applying PV patches..." << endl;
|
||||
|
||||
// Sing missed notes
|
||||
if (nSingMissed)
|
||||
{
|
||||
InjectCode((void*)0x140109044, { 0xEB });
|
||||
// Breaks border:
|
||||
// InjectCode((void*)0x140109096, { 0xEB });
|
||||
}
|
||||
|
||||
// Force mouth animations
|
||||
{
|
||||
if (nForceMouth == 1) // PDA
|
||||
{
|
||||
printf("[Patches] Forcing PDA mouth...\n");
|
||||
int* mouth_table = (int*)(0x1409A1DC0);
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(mouth_table, 44, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
for (int i = 0; i < 11; i++)
|
||||
{
|
||||
mouth_table[i]++;
|
||||
}
|
||||
VirtualProtect(mouth_table, 44, oldProtect, nullptr);
|
||||
printf("[Patches] PDA mouth forced\n");
|
||||
}
|
||||
else if (nForceMouth == 2) // FT
|
||||
{
|
||||
printf("[Patches] Forcing FT mouth...\n");
|
||||
int* mouth_table_oldid = (int*)(0x1409A1E1C);
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(mouth_table_oldid, 44, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
for (int i = 0; i < 11; i++)
|
||||
{
|
||||
mouth_table_oldid[i]--;
|
||||
}
|
||||
VirtualProtect(mouth_table_oldid, 44, oldProtect, nullptr);
|
||||
printf("[Patches] FT mouth forced\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Force expressions
|
||||
{
|
||||
if (nForceExpressions == 1) // PDA
|
||||
{
|
||||
printf("[Patches] Forcing PDA expressions...\n");
|
||||
int* exp_table = (int*)(0x140A21900);
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(exp_table, 104, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
for (int i = 0; i < 26; i++)
|
||||
{
|
||||
exp_table[i] += 2;
|
||||
}
|
||||
VirtualProtect(exp_table, 104, oldProtect, nullptr);
|
||||
printf("[Patches] PDA expressions forced\n");
|
||||
}
|
||||
else if (nForceExpressions == 2) // FT
|
||||
{
|
||||
printf("[Patches] Forcing FT expressions...\n");
|
||||
int* exp_table_oldid = (int*)(0x140A219D0);
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(exp_table_oldid, 104, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
for (int i = 0; i < 26; i++)
|
||||
{
|
||||
exp_table_oldid[i] -= 2;
|
||||
}
|
||||
VirtualProtect(exp_table_oldid, 104, oldProtect, nullptr);
|
||||
printf("[Patches] FT expressions forced\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Force look animations
|
||||
{
|
||||
if (nForceLook == 1) // PDA
|
||||
{
|
||||
printf("[Patches] Forcing PDA look...\n");
|
||||
int* look_table = (int*)(0x1409A1D70);
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(look_table, 36, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
look_table[i]++;
|
||||
}
|
||||
VirtualProtect(look_table, 36, oldProtect, nullptr);
|
||||
printf("[Patches] PDA look forced\n");
|
||||
}
|
||||
else if (nForceLook == 2) // FT
|
||||
{
|
||||
printf("[Patches] Forcing FT look...\n");
|
||||
int* look_table_oldid = (int*)(0x1409A1D9C);
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(look_table_oldid, 36, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
for (int i = 0; i < 9; i++)
|
||||
{
|
||||
look_table_oldid[i]--;
|
||||
}
|
||||
VirtualProtect(look_table_oldid, 36, oldProtect, nullptr);
|
||||
printf("[Patches] FT look forced\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Disable hand scaling
|
||||
if (nNoHandScaling)
|
||||
{
|
||||
InjectCode((void*)0x0000000140120709, { 0xE9, 0x82, 0x0A, 0x00 });
|
||||
}
|
||||
|
||||
// Default hand size
|
||||
if (nDefaultHandSize != -1 && nDefaultHandSize < 1)
|
||||
{
|
||||
MessageBoxW(nullptr, L"The default hand size is lower than 1 and higher than -1 (default). Hands may disappear.\n\nIf this is not intentional, set it back to -1.", L"CustoMixer", MB_ICONWARNING);
|
||||
|
||||
printf("[Patches] Changing default hand size...\n");
|
||||
const float num = (float)nDefaultHandSize / 10000.0;
|
||||
DWORD oldProtect;
|
||||
float* addr1 = (float*)(0x140506B59);
|
||||
float* addr2 = (float*)(0x140506B60);
|
||||
/*float* addr3 = (float*)(0x140506B67);
|
||||
float* addr4 = (float*)(0x140506B71);*/
|
||||
VirtualProtect(addr1, 4, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
VirtualProtect(addr2, 4, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
/*VirtualProtect(addr3, 4, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
VirtualProtect(addr4, 4, PAGE_EXECUTE_READWRITE, &oldProtect);*/
|
||||
*addr1 = *addr2 /*= *addr3 = *addr4*/ = num;
|
||||
VirtualProtect(addr1, 4, oldProtect, nullptr);
|
||||
VirtualProtect(addr2, 4, oldProtect, nullptr);
|
||||
/*VirtualProtect(addr3, 4, oldProtect, nullptr);
|
||||
VirtualProtect(addr4, 4, oldProtect, nullptr);*/
|
||||
printf("[Patches] New default hand size: %f\n", num);
|
||||
}
|
||||
|
||||
cout << "[CustoMixer] PV patches applied." << endl;
|
||||
}
|
||||
|
||||
void setPartToUpdate(char part, string message, unsigned short beepfreq)
|
||||
{
|
||||
part_to_update = part;
|
||||
cout << "[CustoMixer] " << message << endl;
|
||||
cout << "[DivaWig] " << message << endl;
|
||||
if (dobeep) Beep(beepfreq, 300);
|
||||
|
||||
this_thread::sleep_for(chrono::seconds(1));
|
||||
@@ -219,7 +75,7 @@ void unloadAll()
|
||||
unloadFunc((uint64_t*)0x1411B7060, 0, 5387286240);
|
||||
unloadFunc((uint64_t*)0x1411B7060, 0, 5387319280);
|
||||
unloadFunc((uint64_t*)0x1411B7060, 0, 5387352320);
|
||||
cout << "[CustoMixer] All unloaded!" << endl;
|
||||
cout << "[DivaWig] All unloaded!" << endl;
|
||||
if (dobeep) Beep(500, 100);
|
||||
this_thread::sleep_for(chrono::seconds(1));;
|
||||
}
|
||||
@@ -227,7 +83,7 @@ void unloadAll()
|
||||
void unload(__int64 performer_address)
|
||||
{
|
||||
unloadFunc((uint64_t*)0x1411B7060, 0, performer_address);
|
||||
cout << "[CustoMixer] Performer " << performer_address/33040 + 1 << " unloaded!" << endl;
|
||||
cout << "[DivaWig] Performer " << performer_address/33040 + 1 << " unloaded!" << endl;
|
||||
if (dobeep) Beep(500, 100);
|
||||
this_thread::sleep_for(chrono::seconds(1));;
|
||||
}
|
||||
@@ -237,7 +93,7 @@ void loadAll()
|
||||
loadFunc((uint64_t*)0x1411B7060, 0, 5387286240);
|
||||
loadFunc((uint64_t*)0x1411B7060, 0, 5387319280);
|
||||
loadFunc((uint64_t*)0x1411B7060, 0, 5387352320);
|
||||
cout << "[CustoMixer] All loaded!" << endl;
|
||||
cout << "[DivaWig] All loaded!" << endl;
|
||||
if (dobeep) Beep(600, 100);
|
||||
this_thread::sleep_for(chrono::seconds(1));;
|
||||
}
|
||||
@@ -245,29 +101,11 @@ void loadAll()
|
||||
void load(__int64 performer_address)
|
||||
{
|
||||
loadFunc((uint64_t*)0x1411B7060, 0, performer_address);
|
||||
cout << "[CustoMixer] Performer " << performer_address / 33040 + 1 << " loaded!" << endl;
|
||||
cout << "[DivaWig] Performer " << performer_address / 33040 + 1 << " loaded!" << endl;
|
||||
if (dobeep) Beep(600, 100);
|
||||
this_thread::sleep_for(chrono::seconds(1));
|
||||
}
|
||||
|
||||
/*void hookedUnload(uint64_t* a1, unsigned int a2, __int64 a3)
|
||||
{
|
||||
cout << "[CustoMixer] hookedUnload a1: " << a1 << "; a2: " << a2 << "; a3: " << a3 << endl;
|
||||
last_unload_a1 = a1;
|
||||
last_unload_a2 = a2;
|
||||
last_unload_a3 = a3;
|
||||
unloadFunc(a1, a2, a3);
|
||||
}
|
||||
|
||||
void hookedLoad(uint64_t* a1, unsigned int a2, __int64 a3)
|
||||
{
|
||||
cout << "[CustoMixer] hookedReload a1: " << a1 << "; a2: " << a2 << "; a3: " << a3 << endl;
|
||||
last_reload_a1 = a1;
|
||||
last_reload_a2 = a2;
|
||||
last_reload_a3 = a3;
|
||||
loadFunc(a1, a2, a3);
|
||||
}*/
|
||||
|
||||
void inputLoop(__int64 a1)
|
||||
{
|
||||
//if (GetKeyState(VK_CONTROL) < 0)
|
||||
@@ -306,7 +144,7 @@ void inputLoop(__int64 a1)
|
||||
|
||||
__int64 hookedWig(__int64 classp, int module_part, int part_id)
|
||||
{
|
||||
if (debug) cout << "[CustoMixer] Performer: " << (classp-5387286232)/33040+1 << "; Module part: " << module_part << " (" << Strings[module_part] << ")" << "; Default part: " << part_id << "." << endl;
|
||||
if (debug) cout << "[DivaWig] Performer: " << (classp-5387286232)/33040+1 << "; Module part: " << module_part << " (" << Strings[module_part] << ")" << "; Default part: " << part_id << "." << endl;
|
||||
|
||||
if (part_to_update == ALL || part_to_update == module_part)
|
||||
*(int*)(classp + 4i64 * module_part + 8) = part_id;
|
||||
@@ -331,16 +169,15 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
||||
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
loadConfig();
|
||||
pvPatches();
|
||||
DisableThreadLibraryCalls(hModule);
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
cout << "[CustoMixer] Hooking functions..." << endl;
|
||||
cout << "[DivaWig] Hooking functions..." << endl;
|
||||
DetourAttach(&(PVOID&)originalWig, (PVOID)hookedWig);
|
||||
DetourAttach(&(PVOID&)originalSec, (PVOID)hookedSec);
|
||||
DetourAttach(&(PVOID&)originalThi, (PVOID)hookedThi);
|
||||
DetourAttach(&(PVOID&)pvTimerUpdate, (PVOID)inputLoop);
|
||||
cout << "[CustoMixer] Functions hooked." << endl;
|
||||
cout << "[DivaWig] Functions hooked." << endl;
|
||||
DetourTransactionCommit();
|
||||
|
||||
/*if (allowReloading)
|
||||
@@ -364,28 +201,20 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const std::vector<LPCWSTR> typeList = { L"Default", L"PDA", L"PDAFT/PDFT/PDM39" };
|
||||
|
||||
PluginConfig::PluginConfigOption config[] = {
|
||||
{ PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"beep", L"wig", CONFIG_FILE, L"Beep", L"Beep when selecting the part that should be updated.", true } },
|
||||
{ PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"reloading", L"wig", CONFIG_FILE, L"Unloading and loading (experimental)", L"Allow unloading (CTRL+U or U+number) and loading (CTRL+L or L+number).", false } },
|
||||
{ PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"sing_missed", L"patches", CONFIG_FILE, L"Sing Missed Notes", L"Sing Missed Notes.", false } },
|
||||
{ PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"no_hand_scaling", L"patches", CONFIG_FILE, L"No Hand Scaling", L"Disable scripted hand scaling.", false } },
|
||||
{ PluginConfig::CONFIG_NUMERIC, new PluginConfig::PluginConfigNumericData{ L"default_hand_size", L"patches", CONFIG_FILE, L"Default Hand Size:", L"-1: default\n12200: PDA", -1, -1, INT_MAX } },
|
||||
{ PluginConfig::CONFIG_DROPDOWN_INDEX, new PluginConfig::PluginConfigDropdownIndexData{ L"force_mouth", L"patches", CONFIG_FILE, L"Mouth Animations:", L"Change the mouth animations.", 0, typeList}},
|
||||
{ PluginConfig::CONFIG_DROPDOWN_INDEX, new PluginConfig::PluginConfigDropdownIndexData{ L"force_expressions", L"patches", CONFIG_FILE, L"Expr. Animations:", L"Change the expressions.", 0, typeList}},
|
||||
{ PluginConfig::CONFIG_DROPDOWN_INDEX, new PluginConfig::PluginConfigDropdownIndexData{ L"force_look", L"patches", CONFIG_FILE, L"Look Animations:", L"Change the look animations.", 0, typeList}},
|
||||
{ PluginConfig::CONFIG_BOOLEAN, new PluginConfig::PluginConfigBooleanData{ L"debug", L"general", CONFIG_FILE, L"Debug", L"Print extra information.", false } },
|
||||
};
|
||||
|
||||
extern "C" __declspec(dllexport) LPCWSTR GetPluginName(void)
|
||||
{
|
||||
return L"CustoMixer";
|
||||
return L"DivaWig";
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) LPCWSTR GetPluginDescription(void)
|
||||
{
|
||||
return L"CustoMixer Plugin by nas\n\nCustoMixer lets you change some PV settings, and mix module parts by pressing CTRL+0~9.";
|
||||
return L"DivaWig Plugin by nas\n\DivaWig lets you mix module parts by pressing CTRL+0~9.";
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) PluginConfig::PluginConfigArray GetPluginOptions(void)
|
||||
|
||||
@@ -1,16 +1,6 @@
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
|
||||
void InjectCode(void* address, const std::vector<uint8_t> data)
|
||||
{
|
||||
const size_t byteCount = data.size() * sizeof(uint8_t);
|
||||
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(address, byteCount, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
memcpy(address, data.data(), byteCount);
|
||||
VirtualProtect(address, byteCount, oldProtect, nullptr);
|
||||
}
|
||||
|
||||
std::wstring ExePath() {
|
||||
WCHAR buffer[MAX_PATH];
|
||||
GetModuleFileNameW(NULL, buffer, MAX_PATH);
|
||||
@@ -23,5 +13,5 @@ std::wstring DirPath() {
|
||||
return exepath.substr(0, pos);
|
||||
}
|
||||
|
||||
std::wstring CONFIG_FILE_STRING = DirPath() + L"\\plugins\\CustoMixer.ini";
|
||||
std::wstring CONFIG_FILE_STRING = DirPath() + L"\\plugins\\DivaWig.ini";
|
||||
LPCWSTR CONFIG_FILE = CONFIG_FILE_STRING.c_str();
|
||||
|
||||
Reference in New Issue
Block a user