Skip to content

Commit 25c6931

Browse files
authored
Release v1.1.0 (#1)
1 parent eccb764 commit 25c6931

7 files changed

Lines changed: 135 additions & 151 deletions

File tree

LICENSE

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,21 @@
1-
PersistentXPKickers - A QoL mod for Company of Heroes 1
2-
Copyright (C) 2025 Tosox
3-
All rights reserved.
1+
MIT License
42

5-
Redistribution and use in source and binary forms, with or without
6-
modification, are permitted provided that the following conditions
7-
are met:
3+
Copyright (c) 2025 - 2026 Tosox
84

9-
1. Redistributions of source code must retain the above copyright
10-
notice, this list of conditions and the following disclaimer.
11-
2. Redistributions in binary form must reproduce the above copyright
12-
notice, this list of conditions and the following disclaimer in the
13-
documentation and/or other materials provided with the distribution.
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
1411

15-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16-
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17-
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18-
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
19-
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20-
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21-
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22-
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23-
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24-
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25-
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
2614

27-
-------------------------------------------------------------------------------
28-
This mod includes code from the CoHModSDK project by Tosox, licensed under the BSD 2-Clause License.
29-
See licenses/CoHModSDK.txt for details.
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

PersistentXPKickers.vcxproj

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,6 @@
109109
<None Include="LICENSE" />
110110
<None Include="README.md" />
111111
</ItemGroup>
112-
<ItemGroup>
113-
<Text Include="licenses\CoHModSDK.txt" />
114-
</ItemGroup>
115112
<ItemGroup>
116113
<ResourceCompile Include="res\resource.rc" />
117114
</ItemGroup>
Lines changed: 109 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,140 @@
1+
/**
2+
* CoHModSDK - The lightweight modding SDK for Company of Heroes
3+
* Copyright (c) 2026 Tosox
4+
*
5+
* This project is licensed under the Creative Commons
6+
* Attribution-NonCommercial-NoDerivatives 4.0 International License
7+
* (CC BY-NC-ND 4.0) with additional permissions.
8+
*
9+
* Independent mods using this project only through its public interfaces
10+
* are not required to use CC BY-NC-ND 4.0.
11+
*
12+
* See the repository root LICENSE file for the full license text and
13+
* additional permissions.
14+
*/
15+
116
#pragma once
217

318
#include <Windows.h>
419
#include <cstddef>
520
#include <cstdint>
621

722
extern "C" {
8-
// Called once when ModSDK loads the mod
23+
/**
24+
* @brief Called once when the SDK loads the mod DLL.
25+
*
26+
* Perform any early setup required for the mod here (e.g., install hooks, patch memory).
27+
*/
928
__declspec(dllexport) void OnSDKLoad();
1029

11-
// Called when the game is starting (after mod load)
30+
/**
31+
* @brief Called when the game is starting (after all mods have been loaded).
32+
*
33+
* Use this to initialize features that require the game to be fully running.
34+
*/
1235
__declspec(dllexport) void OnGameStart();
1336

14-
// Called when the game is shutting down
37+
/**
38+
* @brief Called when the game is shutting down.
39+
*
40+
* Use this to clean up any hooks, memory patches, or resources before unloading.
41+
*/
1542
__declspec(dllexport) void OnGameShutdown();
1643

17-
// Mod metadata
44+
/**
45+
* @brief Returns the display name of the mod.
46+
*
47+
* @return const char* - Name of the mod.
48+
*/
1849
__declspec(dllexport) const char* GetModName();
50+
51+
/**
52+
* @brief Returns the version string of the mod.
53+
*
54+
* @return const char* - Version of the mod.
55+
*/
1956
__declspec(dllexport) const char* GetModVersion();
57+
58+
/**
59+
* @brief Returns the author name(s) of the mod.
60+
*
61+
* @return const char* - Author or team name.
62+
*/
2063
__declspec(dllexport) const char* GetModAuthor();
2164
}
2265

2366
namespace ModSDK {
2467
namespace Memory {
25-
std::uintptr_t FindPattern(const char* moduleName, const char* signature, bool reportError = true);
68+
/**
69+
* @brief Returns a handle to the module that contains the original game code.
70+
*
71+
* @return HMODULE - Handle to `WW2Mod.original.dll` with fallback to `WW2Mod.dll`.
72+
*/
73+
HMODULE GetGameModuleHandle();
74+
75+
/**
76+
* @brief Scans a module for a byte pattern signature.
77+
*
78+
* Use `GetGameModuleHandle()` when you want to scan the original game module.
79+
*
80+
* @param moduleHandle Handle to the module to scan.
81+
* @param signature Pattern string (e.g., "48 8B ?? ?? ?? ?? ?? 48 8B").
82+
* @param reportError Whether to show an error if the pattern is not found.
83+
* @return std::uintptr_t Address where the pattern was found or 0 if not found.
84+
*/
85+
std::uintptr_t FindPattern(HMODULE moduleHandle, const char* signature, bool reportError = true);
86+
87+
/**
88+
* @brief Patches memory by copying bytes to a destination address.
89+
*
90+
* Automatically changes memory protection to allow writing.
91+
*
92+
* @param destination Target address to patch.
93+
* @param source Bytes to write.
94+
* @param size Number of bytes to copy.
95+
*/
2696
void PatchMemory(void* destination, const void* source, std::size_t size);
2797
}
2898

2999
namespace Hooks {
100+
/**
101+
* @brief Creates a hook from a target function to a detour function.
102+
*
103+
* @param targetFunction Pointer to the function to hook.
104+
* @param detourFunction Pointer to the custom function (your detour).
105+
* @param originalFunction Out parameter; will store the pointer to call original later.
106+
* @return true if the hook was created successfully, false otherwise.
107+
*/
30108
bool CreateHook(void* targetFunction, void* detourFunction, void** originalFunction);
109+
110+
/**
111+
* @brief Enables an individual installed hook.
112+
*
113+
* @param targetFunction Pointer to the function where a hook was created.
114+
* @return true if successfully enabled, false otherwise.
115+
*/
31116
bool EnableHook(void* targetFunction);
117+
118+
/**
119+
* @brief Enables all hooks created by the SDK.
120+
*
121+
* @return true if successful, false otherwise.
122+
*/
32123
bool EnableAllHooks();
124+
125+
/**
126+
* @brief Disables an individual hook.
127+
*
128+
* @param targetFunction Pointer to the hooked function.
129+
* @return true if successfully disabled, false otherwise.
130+
*/
33131
bool DisableHook(void* targetFunction);
132+
133+
/**
134+
* @brief Disables all active hooks created by the SDK.
135+
*
136+
* @return true if successful, false otherwise.
137+
*/
34138
bool DisableAllHooks();
35139
}
36140
}
-31.3 KB
Binary file not shown.

licenses/CoHModSDK.txt

Lines changed: 0 additions & 110 deletions
This file was deleted.

res/resource.rc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
6161
//
6262

6363
VS_VERSION_INFO VERSIONINFO
64-
FILEVERSION 0,1,0,0
65-
PRODUCTVERSION 0,1,0,0
64+
FILEVERSION 0,1,1,0
65+
PRODUCTVERSION 0,1,1,0
6666
FILEFLAGSMASK 0x3fL
6767
#ifdef _DEBUG
6868
FILEFLAGS 0x1L
@@ -79,12 +79,12 @@ BEGIN
7979
BEGIN
8080
VALUE "CompanyName", "Tosox"
8181
VALUE "FileDescription", "A QoL mod for Company of Heroes 1"
82-
VALUE "FileVersion", "0.1.0.0"
82+
VALUE "FileVersion", "0.1.1.0"
8383
VALUE "InternalName", "PersistentXPKickers"
84-
VALUE "LegalCopyright", "Copyright � 2025"
84+
VALUE "LegalCopyright", "Copyright � 2026"
8585
VALUE "OriginalFilename", "PersistentXPKickers.dll"
8686
VALUE "ProductName", "PersistentXPKickers"
87-
VALUE "ProductVersion", "0.1.0.0"
87+
VALUE "ProductVersion", "0.1.1.0"
8888
END
8989
END
9090
BLOCK "VarFileInfo"

src/dllmain.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,14 @@ bool __cdecl HookedSub2641C0(void* _this) {
3737
}
3838

3939
bool SetupHooks() {
40-
std::uintptr_t sub2641C0Addr = ModSDK::Memory::FindPattern("WW2Mod.dll", "56 E8 ?? ?? ?? ?? 85 C0 75 03 32 C0");
40+
HMODULE hGameModule = ModSDK::Memory::GetGameModuleHandle();
41+
std::uintptr_t sub2641C0Addr = ModSDK::Memory::FindPattern(hGameModule, "56 E8 ?? ?? ?? ?? 85 C0 75 03 32 C0");
4142
if (!sub2641C0Addr) {
4243
MessageBoxA(nullptr, "Pattern not found", "Error", MB_ICONERROR);
4344
return false;
4445
}
4546

46-
std::uintptr_t xpKickerCheckAddr = ModSDK::Memory::FindPattern("WW2Mod.dll", "E8 ?? ?? ?? ?? 84 C0 75 18 8B 54 24 10");
47+
std::uintptr_t xpKickerCheckAddr = ModSDK::Memory::FindPattern(hGameModule, "E8 ?? ?? ?? ?? 84 C0 75 18 8B 54 24 10");
4748
if (!xpKickerCheckAddr) {
4849
MessageBoxA(nullptr, "Caller pattern not found!", "Error", MB_ICONERROR);
4950
return false;
@@ -82,7 +83,7 @@ extern "C" {
8283
}
8384

8485
__declspec(dllexport) const char* GetModVersion() {
85-
return "1.0.0";
86+
return "1.1.0";
8687
}
8788

8889
__declspec(dllexport) const char* GetModAuthor() {

0 commit comments

Comments
 (0)