Compare commits
18 Commits
renovate/c
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
857f5a2198 | ||
|
c33a2ab19b | ||
|
f752c8d013 | ||
|
79684d3120 | ||
|
0ff5072ecc | ||
|
e915089ebf | ||
|
ffa97e06f3 | ||
|
0e3442ba48 | ||
|
06ad6bee1b | ||
|
9ddc68c6e3 | ||
|
b03dd634c0 | ||
198010c907 | |||
|
96ee3d7669 | ||
|
bad57abbd7 | ||
|
de9e878855 | ||
|
f6bf64184b | ||
|
61783bd28e | ||
|
36c771dd27 |
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -1,2 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
* text=auto
|
11
.github/dependabot.yml
vendored
Normal file
11
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "npm" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "weekly"
|
143
LICENSE
143
LICENSE
@ -1,5 +1,5 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
@ -7,17 +7,15 @@
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
@ -26,44 +24,34 @@ them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
@ -72,7 +60,7 @@ modification follow.
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
@ -549,35 +537,45 @@ to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
@ -635,40 +633,29 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
|
99
README.md
99
README.md
@ -1,7 +1,7 @@
|
||||
[![Discord](https://img.shields.io/discord/945420505157083208?color=%237289DA&label=members&logo=discord&logoColor=%23FFFFFF)](https://discord.gg/donetsk)
|
||||
|
||||
<p align="center">
|
||||
<img src="/github/assets/donetskbanner.png?raw=true" />
|
||||
<img src="github/assets/donetskbanner.png?raw=true" />
|
||||
</p>
|
||||
|
||||
## Note: Donetsk is in beta, the experience may not be exactly what you expected. Bugs and issues are to be expected
|
||||
@ -11,22 +11,105 @@ Project Donetsk is an attempt to create a more open Modern Warfare 2019 with a s
|
||||
---
|
||||
|
||||
# What are some of the goals of project Donetsk
|
||||
1. Allow Call of Duty Warzone to be played after Activision officially discontinued it on Septerber 21st, 2023
|
||||
1. Allow Call of Duty Warzone to be played after Activision officially discontinued it on September 21st, 2023
|
||||
2. Allow Modern Warfare to be played outside of Battle.net and Steam
|
||||
3. Allow custom content such as maps, weapons, and cosmetics to be used in Modern Warfare
|
||||
4. Add a server browser
|
||||
---
|
||||
|
||||
# Installation
|
||||
1. Find a compatible version of Modern Warfare
|
||||
#### This does not work on the latest version of Modern Warfare (1.67). If you try it on that version you risk a ban
|
||||
2. Download the latest dll for Donetsk or compile from source
|
||||
3. Put the dll into the game folder and launch game_dx12_ship_replay.exe
|
||||
1. Visit our website for a download of the required game files
|
||||
#### This does not work on the latest version of Modern Warfare (1.67). If you try it on that version, you risk a ban!
|
||||
2. Download the latest .dll for Donetsk or compile from source
|
||||
3. Put the .dll into the game folder and launch `game_dx12_ship_replay.exe`
|
||||
---
|
||||
# Common Errors
|
||||
- ```Failed to initialize TACT client: E_STORAGE_INIT (25), Invalid build info ```
|
||||
- Right click on game folder and uncheck read only
|
||||
- ```Fatal Error (Of any variety)```
|
||||
- ```Fatal Error (Of any variety) ```
|
||||
- Right click on game folder and uncheck read only
|
||||
- ```DirectX call failed with error: DX ERROR UNKNOWN[OX8000FFFF]. ```
|
||||
- This is a directx error, the best solution is to reinstall windows from usb, but you may have some sucess in repairing your windows installation
|
||||
- This is a DirectX error, the best solution is to reinstall windows from USB, but you may have some success in repairing your windows installation
|
||||
|
||||
# FAQ
|
||||
|
||||
**<u>How do I join a game?</u>**
|
||||
|
||||
By using utilizing a LAN match and Radmin VPN it’s possible to host tournaments and BR matches
|
||||
|
||||
**<u>How much space is Donetsk launcher?</u>**
|
||||
|
||||
Season 3/1.20 is 88.8GB
|
||||
|
||||
**<u>How can I host my own server?</u>**
|
||||
|
||||
Yes, by connecting to the same LAN network through a VPN, However, only 700m around the moving host is playable.
|
||||
|
||||
**<u>Can I use a controller on this?</u>**
|
||||
|
||||
Yes, you can use controllers! PS4, and Xbox controllers (old and newgen) work like normal. Although new gen PS5 controllers don't work, you'll need to use a third party software like DS4 to emulate a PS4 controller. https://ds4-windows.com/
|
||||
|
||||
**<u>Can I play this on a Console/Mac/Mobile?</u>**
|
||||
|
||||
There is no support for Console/Mac/Mobile.
|
||||
|
||||
**<u>Can I get banned on actual Free-To-Play Warzone 1?</u>**
|
||||
|
||||
No, this whole project has nothing to do with Activision Publishing, Inc. or their servers themselves.
|
||||
|
||||
**<u>If I need help, where can I find it?</u>**
|
||||
|
||||
Join our new supportive community at https://discord.gg/donetsk
|
||||
|
||||
Hopefully this list clears up any confusion / problems you may have, Have Fun!
|
||||
|
||||
**<u>Is campaign here?</u>**
|
||||
|
||||
NO
|
||||
|
||||
**<u>Do I need a good connection to play this game?</u>**
|
||||
|
||||
- If you are planning to play by yourself, no. You can perfectly play with bots and mess around with the games engine however you feel.
|
||||
- However, if you do plan to play with your friends or the public, yes. You will need a good internet connection: usually ranging at 30mbs download for client, and for the host at least 50mbs< upload for multiplayer. 65mbs< upload for hosting a game of Warzone Verdansk. And 40mbs download for the client connecting to Warzone Verdansk.
|
||||
```
|
||||
Reason being for a higher requirements is because you’re connecting to a dedicated server that maybe located within either a single band data center, someone’s house, or some trailer park in Ohio. You’re not connecting to a cluster of servers like how Activision had it setup, its only connecting to one direct location.
|
||||
```
|
||||
|
||||
**<u>Splitscreen's here?</u>**
|
||||
|
||||
No.
|
||||
|
||||
**<u>How to change your in-game name?</u>**
|
||||
|
||||
Go on the console and write `player_name [your name]`
|
||||
|
||||
**<u>DirectX call failed with error: DX ERROR UNKNOWN [OX8000FFFF]</u>**
|
||||
|
||||
First open Command Prompt (CMD) as admin and type in "SFC /scannow" and check if it has been fixed, if not hard reset windows through BIOS
|
||||
|
||||
**If someone has this error on MW19:
|
||||
Failed to initialize TACT client : E_REPAIR (28), invalid build info?**
|
||||
|
||||
Delete the CASCRepair.mrk file in Call of Duty Modern Warfare (2019)\Data\data\CASCRepair.mrk thx to SKU-111 for providing this fix 🙂
|
||||
|
||||
# Common Errors And Fixes
|
||||
|
||||
**<u>Disconnected from Server Or Status: Goldflake</u>**
|
||||
|
||||
Create a second Windows profile (don't forget to give Admin privileges) and play the game from that profile
|
||||
Delete Call of Duty Modern Warfare folder under Documents
|
||||
Then start game once, close it and put .cfg files back under C:\Users<USER>\Documents\Call of Duty Modern Warfare\players
|
||||
|
||||
**<u>Failed to initialize TACT client: E_STORAGE_INIT (25), Invalid build info</u>**
|
||||
|
||||
Right click on game folder and uncheck read only
|
||||
|
||||
**<u>Corrupted And Missing File Errors</u>**
|
||||
|
||||
Make sure you have enough space on your drive and/or
|
||||
Re-download or re-unzip the game
|
||||
Example: Fatal Error
|
||||
|
||||
**<u>DirectX call failed with error: DX ERROR UNKNOWN[OX8000FFFF].</u>**
|
||||
|
||||
The only fix I'm aware of is to make a fresh Windows install
|
5
build.bat
Normal file
5
build.bat
Normal file
@ -0,0 +1,5 @@
|
||||
@echo off
|
||||
|
||||
"C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\msbuild.exe" hook_lib.sln /p:Configuration=Release /p:Platform=x64
|
||||
|
||||
pause
|
@ -1,3 +0,0 @@
|
||||
This folder is used for items for the github repo
|
||||
This is used for things like the readme on the main page
|
||||
This will not be used in the donetsk project it
|
@ -2,6 +2,7 @@
|
||||
#include "game_inc.h"
|
||||
#include "debug_output.h"
|
||||
|
||||
#include "discord.h"
|
||||
#include "addr_utils.hpp"
|
||||
|
||||
void entry_point()
|
||||
@ -30,11 +31,11 @@ void entry_point()
|
||||
extern "C" __declspec(dllexport) int DiscordCreate()
|
||||
{
|
||||
CreateThread(0, 0xA0, (LPTHREAD_START_ROUTINE)entry_point, 0, 0, 0);
|
||||
|
||||
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)DiscordThread, 0, 0, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char buffer[0x5000];
|
||||
|
||||
BOOL WINAPI DllMain(HMODULE hModule, DWORD Reason, LPVOID lpVoid)
|
||||
{
|
||||
initAddrUtils();
|
||||
@ -62,7 +63,7 @@ BOOL WINAPI DllMain(HMODULE hModule, DWORD Reason, LPVOID lpVoid)
|
||||
addCustomCmds();
|
||||
patchGame();
|
||||
|
||||
printf("Discord: discord.gg/donetsk\n");
|
||||
printf("Website: donetsk.live\n");
|
||||
|
||||
cmd_args = (CmdArgs*)(0x14D20CBD0_g);
|
||||
|
||||
|
102
hook_lib/discord.cpp
Normal file
102
hook_lib/discord.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
#include "discord.h"
|
||||
#include "discord_rpc.h"
|
||||
|
||||
#include "Main.hpp"
|
||||
|
||||
#include "addr_utils.hpp"
|
||||
|
||||
struct DiscordInfo {
|
||||
const char* mapName;
|
||||
const char* gameType;
|
||||
int partySize;
|
||||
int partyMax;
|
||||
const char* largeImageKey;
|
||||
const char* smallImageKey;
|
||||
};
|
||||
|
||||
bool discordInitalized;
|
||||
|
||||
void DiscordInitialize() {
|
||||
DiscordEventHandlers handlers;
|
||||
memset(&handlers, 0, sizeof(handlers));
|
||||
Discord_Initialize("1183441008168534016", &handlers, 1, NULL);
|
||||
discordInitalized = true;
|
||||
}
|
||||
|
||||
__int64 startTime;
|
||||
void Discord_UpdateStatus_Internal(DiscordInfo info) {
|
||||
DiscordRichPresence discordPresence;
|
||||
memset(&discordPresence, 0, sizeof(discordPresence));
|
||||
discordPresence.details = info.mapName;
|
||||
discordPresence.state = info.gameType;
|
||||
discordPresence.partySize = info.partySize;
|
||||
discordPresence.partyMax = info.partyMax;
|
||||
discordPresence.startTimestamp = startTime;
|
||||
//discordPresence.endTimestamp = 1507665886;
|
||||
discordPresence.largeImageKey = info.largeImageKey;
|
||||
discordPresence.largeImageText = info.mapName;
|
||||
discordPresence.smallImageKey = info.smallImageKey;
|
||||
discordPresence.smallImageText = info.gameType;
|
||||
/*discordPresence.partyId = "";
|
||||
discordPresence.joinSecret = "";*/
|
||||
Discord_UpdatePresence(&discordPresence);
|
||||
}
|
||||
|
||||
void DiscordUpdate() {
|
||||
if (discordInitalized) {
|
||||
DiscordInfo info;
|
||||
bool inFrontend = *(bool*)(0x1459D1750_g);
|
||||
const char* dvarMap = Dvar_GetStringSafe("ui_mapname");
|
||||
const char* dvarMode = Dvar_GetStringSafe("ui_gametype");
|
||||
const char* mapName = GetMapName(dvarMap);
|
||||
if (inFrontend) {
|
||||
startTime = std::time(0);
|
||||
int partySize = *(int*)(0x14C7B0958_g);
|
||||
info.mapName = "In Menus";
|
||||
info.gameType = "Waiting";
|
||||
info.partySize = partySize;
|
||||
info.partyMax = Dvar_GetIntSafe("party_maxplayers");
|
||||
info.largeImageKey = "mw";
|
||||
info.smallImageKey = "";
|
||||
}
|
||||
else {
|
||||
startTime = std::time(0);
|
||||
int partySize = *(int*)(0x14C7B0958_g);
|
||||
info.mapName = mapName;
|
||||
info.gameType = GetGametypeName(dvarMode);
|
||||
info.partySize = partySize;
|
||||
info.partyMax = Dvar_GetIntSafe("party_maxplayers");
|
||||
info.largeImageKey = dvarMap;
|
||||
info.smallImageKey = dvarMode;
|
||||
}
|
||||
Discord_UpdateStatus_Internal(info);
|
||||
printf("Discord Status Updated\n");
|
||||
}
|
||||
}
|
||||
|
||||
void DiscordThread()
|
||||
{
|
||||
puts("Initializing Discord Presence.");
|
||||
DiscordInitialize();
|
||||
|
||||
if (discordInitalized == false)
|
||||
{
|
||||
puts("Initializing Discord Presence failed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
DiscordUpdate();
|
||||
}
|
||||
|
||||
while (discordInitalized)
|
||||
{
|
||||
bool inFrontend = *(bool*)(0x1459D1750_g);
|
||||
|
||||
Sleep(5000);
|
||||
|
||||
if (inFrontend != *(bool*)(0x1459D1750_g))
|
||||
{
|
||||
DiscordUpdate();
|
||||
}
|
||||
}
|
||||
}
|
5
hook_lib/discord.h
Normal file
5
hook_lib/discord.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#pragma comment(lib, "discord-rpc.lib")
|
||||
|
||||
void DiscordThread();
|
87
hook_lib/discord_rpc.h
Normal file
87
hook_lib/discord_rpc.h
Normal file
@ -0,0 +1,87 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
// clang-format off
|
||||
|
||||
#if defined(DISCORD_DYNAMIC_LIB)
|
||||
# if defined(_WIN32)
|
||||
# if defined(DISCORD_BUILDING_SDK)
|
||||
# define DISCORD_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define DISCORD_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
# else
|
||||
# define DISCORD_EXPORT __attribute__((visibility("default")))
|
||||
# endif
|
||||
#else
|
||||
# define DISCORD_EXPORT
|
||||
#endif
|
||||
|
||||
// clang-format on
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct DiscordRichPresence {
|
||||
const char* state; /* max 128 bytes */
|
||||
const char* details; /* max 128 bytes */
|
||||
int64_t startTimestamp;
|
||||
int64_t endTimestamp;
|
||||
const char* largeImageKey; /* max 32 bytes */
|
||||
const char* largeImageText; /* max 128 bytes */
|
||||
const char* smallImageKey; /* max 32 bytes */
|
||||
const char* smallImageText; /* max 128 bytes */
|
||||
const char* partyId; /* max 128 bytes */
|
||||
int partySize;
|
||||
int partyMax;
|
||||
const char* matchSecret; /* max 128 bytes */
|
||||
const char* joinSecret; /* max 128 bytes */
|
||||
const char* spectateSecret; /* max 128 bytes */
|
||||
int8_t instance;
|
||||
} DiscordRichPresence;
|
||||
|
||||
typedef struct DiscordUser {
|
||||
const char* userId;
|
||||
const char* username;
|
||||
const char* discriminator;
|
||||
const char* avatar;
|
||||
} DiscordUser;
|
||||
|
||||
typedef struct DiscordEventHandlers {
|
||||
void (*ready)(const DiscordUser* request);
|
||||
void (*disconnected)(int errorCode, const char* message);
|
||||
void (*errored)(int errorCode, const char* message);
|
||||
void (*joinGame)(const char* joinSecret);
|
||||
void (*spectateGame)(const char* spectateSecret);
|
||||
void (*joinRequest)(const DiscordUser* request);
|
||||
} DiscordEventHandlers;
|
||||
|
||||
#define DISCORD_REPLY_NO 0
|
||||
#define DISCORD_REPLY_YES 1
|
||||
#define DISCORD_REPLY_IGNORE 2
|
||||
|
||||
DISCORD_EXPORT void Discord_Initialize(const char* applicationId,
|
||||
DiscordEventHandlers* handlers,
|
||||
int autoRegister,
|
||||
const char* optionalSteamId);
|
||||
DISCORD_EXPORT void Discord_Shutdown(void);
|
||||
|
||||
/* checks for incoming messages, dispatches callbacks */
|
||||
DISCORD_EXPORT void Discord_RunCallbacks(void);
|
||||
|
||||
/* If you disable the lib starting its own io thread, you'll need to call this from your own */
|
||||
#ifdef DISCORD_DISABLE_IO_THREAD
|
||||
DISCORD_EXPORT void Discord_UpdateConnection(void);
|
||||
#endif
|
||||
|
||||
DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* presence);
|
||||
DISCORD_EXPORT void Discord_ClearPresence(void);
|
||||
|
||||
DISCORD_EXPORT void Discord_Respond(const char* userid, /* DISCORD_REPLY_ */ int reply);
|
||||
|
||||
DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* handlers);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
@ -164,6 +164,11 @@ dvar_t* Dvar_RegisterBool(const char* dvarName, bool value, unsigned int flags,
|
||||
return func(dvarName, value, flags, description);
|
||||
}
|
||||
|
||||
dvar_t* Dvar_RegisterInt(const char* dvarName, bool value, int min, int max, unsigned int flags, const char* description) {
|
||||
auto func = reinterpret_cast<dvar_t * (*)(const char* dvarName, bool value, int min, int max, unsigned int flags, const char* description)>(0x1413E7A00_g);
|
||||
return func(dvarName, value, min, max, flags, description);
|
||||
}
|
||||
|
||||
void LUI_CoD_LuaCall_ExecNow(uintptr_t luaVM, const char* str) {
|
||||
lua_getfield(luaVM, -10002, "Engine");
|
||||
lua_getfield(luaVM, -1, "DAGFFDGFII");
|
||||
@ -499,7 +504,7 @@ uintptr_t G_GetEntityPlayerState(gentity_s* ent)
|
||||
|
||||
int G_Main_GetTime()
|
||||
{
|
||||
return *(int*)0x14BC21730;
|
||||
return *(int*)0x14BC21730_g;
|
||||
}
|
||||
|
||||
const char* _va(const char* format, ...)
|
||||
@ -513,6 +518,34 @@ const char* _va(const char* format, ...)
|
||||
return _buf;
|
||||
}
|
||||
|
||||
const char* SEH_StringEd_GetString(const char* string) {
|
||||
auto func = reinterpret_cast <const char* (*)(const char*)>(0x1413CC2A0_g);
|
||||
return func(string);
|
||||
}
|
||||
|
||||
mapInfo* Com_GameInfo_GetMapInfoForLoadName(const char* mapName) {
|
||||
auto func = reinterpret_cast<mapInfo * (*)(const char*)>(0x1410C77F0_g);
|
||||
return func(mapName);
|
||||
}
|
||||
|
||||
const char* GetMapName(const char* mapName) {
|
||||
mapInfo* mapinfo = Com_GameInfo_GetMapInfoForLoadName(mapName);
|
||||
if (!mapinfo) return "Unknown Map";
|
||||
if (mapinfo->mapName[0] == 31) return "error";
|
||||
return SEH_StringEd_GetString(mapinfo->mapName);
|
||||
}
|
||||
|
||||
gameTypeInfo* Com_GameInfo_GetGameTypeForInternalName(const char* mapName) {
|
||||
auto func = reinterpret_cast<gameTypeInfo * (*)(const char*)>(0x1410C7580_g);
|
||||
return func(mapName);
|
||||
}
|
||||
const char* GetGametypeName(const char* gameType) {
|
||||
gameTypeInfo* gametypeinfo = Com_GameInfo_GetGameTypeForInternalName(gameType);
|
||||
if (!gametypeinfo) return "Unknown Mode";
|
||||
if (gametypeinfo->gameTypeName[0] == 31) return "error";
|
||||
return SEH_StringEd_GetString(gametypeinfo->gameTypeName);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
dvar_t* player_name;
|
||||
@ -521,6 +554,9 @@ dvar_t* spawn_br_gas;
|
||||
dvar_t* show_watermark;
|
||||
dvar_t* player_sustainammo;
|
||||
dvar_t* print_debug;
|
||||
dvar_t* weap_impactType;
|
||||
dvar_t* weap_dismembermentAlwaysEnabled;
|
||||
dvar_t* g_dumpScripts;
|
||||
|
||||
cmd_function_s set_byte_f_VAR;
|
||||
cmd_function_s set_short_f_VAR;
|
||||
|
@ -102,6 +102,8 @@ struct DBFile
|
||||
|
||||
struct Weapon;
|
||||
struct scrContext_t;
|
||||
struct mapInfo;
|
||||
struct gameTypeInfo;
|
||||
|
||||
extern dvar_t* player_name;
|
||||
extern dvar_t* sv_cheats;
|
||||
@ -109,6 +111,9 @@ extern dvar_t* spawn_br_gas;
|
||||
extern dvar_t* show_watermark;
|
||||
extern dvar_t* player_sustainammo;
|
||||
extern dvar_t* print_debug;
|
||||
extern dvar_t* weap_impactType;
|
||||
extern dvar_t* weap_dismembermentAlwaysEnabled;
|
||||
extern dvar_t* g_dumpScripts;
|
||||
|
||||
extern cmd_function_s set_byte_f_VAR;
|
||||
extern cmd_function_s set_short_f_VAR;
|
||||
@ -170,6 +175,7 @@ dvar_t* Dvar_FindVarByName(const char* dvarName);
|
||||
void CL_DrawText(const uintptr_t scrPlace, const char* text, int maxChars, uintptr_t font, float x, float y, int horzAlign, int vertAlign, float xScale, float yScale, const float* color, int style);
|
||||
dvar_t* Dvar_RegisterString(const char* dvarName, const char* value, unsigned int flags, const char* description);
|
||||
dvar_t* Dvar_RegisterBool(const char* dvarName, bool value, unsigned int flags, const char* description);
|
||||
dvar_t* Dvar_RegisterInt(const char* dvarName, bool value, int min, int max, unsigned int flags, const char* description);
|
||||
|
||||
void LUI_CoD_LuaCall_ExecNow(uintptr_t luaVM, const char* str);
|
||||
bool LUI_LuaCall_Game_IsEntityAlive(uintptr_t luaVM, int entityNum);
|
||||
@ -253,4 +259,14 @@ int G_Main_GetTime();
|
||||
|
||||
const char* _va(const char* format, ...);
|
||||
|
||||
const char* SEH_StringEd_GetString(const char* string);
|
||||
|
||||
mapInfo* Com_GameInfo_GetMapInfoForLoadName(const char* mapName);
|
||||
|
||||
const char* GetMapName(const char* mapName);
|
||||
|
||||
gameTypeInfo* Com_GameInfo_GetGameTypeForInternalName(const char* mapName);
|
||||
|
||||
const char* GetGametypeName(const char* gameType);
|
||||
|
||||
#pragma endregion
|
||||
|
@ -48,7 +48,7 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
@ -167,6 +167,7 @@
|
||||
<ClCompile Include="ddl.cpp" />
|
||||
<ClCompile Include="debug_output.cpp" />
|
||||
<ClCompile Include="devgui.cpp" />
|
||||
<ClCompile Include="discord.cpp" />
|
||||
<ClCompile Include="dvar.cpp" />
|
||||
<ClCompile Include="fastfile.cpp" />
|
||||
<ClCompile Include="functions.cpp" />
|
||||
@ -212,6 +213,8 @@
|
||||
<ClInclude Include="ddl.h" />
|
||||
<ClInclude Include="debug_output.h" />
|
||||
<ClInclude Include="devgui.h" />
|
||||
<ClInclude Include="discord.h" />
|
||||
<ClInclude Include="discord_rpc.h" />
|
||||
<ClInclude Include="dvar.h" />
|
||||
<ClInclude Include="fastfile.h" />
|
||||
<ClInclude Include="functions.hpp" />
|
||||
|
@ -20,6 +20,9 @@
|
||||
<Filter Include="hook_lib\game">
|
||||
<UniqueIdentifier>{0999b80b-b47c-4d8e-8776-f5c778bcac9f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="hook_lib\discord">
|
||||
<UniqueIdentifier>{8d71ea0c-2bb4-42e8-9e46-36f0aa487cbf}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="common\utils\binary_resource.cpp">
|
||||
@ -142,6 +145,9 @@
|
||||
<ClCompile Include="debug_output.cpp">
|
||||
<Filter>hook_lib\game</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="discord.cpp">
|
||||
<Filter>hook_lib\discord</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="common\utils\binary_resource.hpp">
|
||||
@ -282,5 +288,11 @@
|
||||
<ClInclude Include="debug_output.h">
|
||||
<Filter>hook_lib\game</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="discord_rpc.h">
|
||||
<Filter>hook_lib\discord</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="discord.h">
|
||||
<Filter>hook_lib\discord</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -13,6 +13,11 @@ void LUI_CoD_RegisterDvars_Detour()
|
||||
|
||||
print_debug = Dvar_RegisterBool("print_debug", false, 0, "Print debug output to the external console");
|
||||
|
||||
weap_impactType = Dvar_RegisterInt("weap_impactType", -1, -1, 1000, 0, "Forces an weapon impact type on every weapon. -1 = default");
|
||||
weap_dismembermentAlwaysEnabled = Dvar_RegisterBool("weap_dismembermentAlwaysEnabled", false, 0, "Enables dismemberment effect for all weapons");
|
||||
|
||||
g_dumpScripts = Dvar_RegisterBool("g_dumpScripts", false, 0, "Dump GSC scripts");
|
||||
|
||||
lui_cod_registerdvars.stub<void>();
|
||||
}
|
||||
|
||||
|
@ -10,5 +10,13 @@ void PartyHost_StartPrivateParty_Detour(int localClientNum, int localControllerI
|
||||
{
|
||||
Cbuf_AddText("exec autoexec.cfg");
|
||||
LoadInventory();
|
||||
|
||||
// skips Tutorial stuff
|
||||
Cbuf_AddText("setRankedPlayerData mpTutorialLevel -2147463171");
|
||||
Cbuf_AddText("setRankedPlayerData mpTutorialLevel2 28671");
|
||||
Cbuf_AddText("setRankedPlayerData mpTutorialLevel - 2147454979");
|
||||
Cbuf_AddText("setRankedPlayerData mpTutorialLevel2 61439");
|
||||
|
||||
autoexec = true;
|
||||
}
|
||||
}
|
@ -103,6 +103,7 @@ bool ProfanityFilter_IsBadWord_Detour()
|
||||
void hooks()
|
||||
{
|
||||
process_script_file.create(0x141322350_g, ProcessScriptFile);
|
||||
utils::hook::jump(0x140DFE370_g, Load_ScriptFile_Detour);
|
||||
|
||||
//utils::hook::jump(0x141BD3360_g, sub_141BD3360_Detour);
|
||||
|
||||
@ -153,11 +154,15 @@ void hooks()
|
||||
|
||||
utils::hook::jump(0x141609140_g, ProfanityFilter_IsBadWord_Detour);
|
||||
|
||||
cg_overrideimpacteffecttype.create(0x141733CD0_g, CG_OverrideImpactEffectType_Detour);
|
||||
bg_getweapondismembermentenabled.create(0x141170C00_g, BG_GetWeaponDismembermentEnabled_Detour);
|
||||
|
||||
// replacing Com_GameMode_GetActiveGameMode call with CheatsEnabled for jump_height dvar
|
||||
utils::hook::call(0x14110195A_g, CheatsEnabled);
|
||||
|
||||
// remove FF Header version check
|
||||
// db_checkxfileversion.create(0x1411A7840_g, DB_CheckXFileVersion_Detour);
|
||||
// utils::hook::jump(0x1411A7840_g, DB_CheckXFileVersion_Detour);
|
||||
}
|
||||
|
||||
void patchGame()
|
||||
@ -203,6 +208,9 @@ void patchGame()
|
||||
// enable functionality for jump_height dvar
|
||||
utils::hook::set<byte>(0x141101946_g, 0xEB);
|
||||
|
||||
// enable friction dvar
|
||||
utils::hook::set(0x14112141E_g, (int8_t)2);
|
||||
|
||||
// remove FF Header version check
|
||||
// utils::hook::set<byte>(0x1411A776B_g, 0xEB);
|
||||
}
|
@ -21,4 +21,7 @@ void CL_ScreenMP_DrawOverlay_Detour()
|
||||
if (show_watermark->current.enabled) {
|
||||
CG_DrawWaterMark();
|
||||
}
|
||||
|
||||
float white[4] = { 1.0f, 1.0f, 1.0f, 0.075f };
|
||||
CL_DrawText(0x14EF2DEA0_g, "Project Warzon", 0x7FFFFFFF, *reinterpret_cast<uintptr_t*>(0x14EEB0C68_g), 0, 480, 1, 1, 0.45000001, 0.45000001, white, 7);
|
||||
}
|
@ -2,55 +2,203 @@
|
||||
#include "script.h"
|
||||
#include "game_inc.h"
|
||||
|
||||
void ProcessScriptFile(void* scrContext, ScriptFile* scriptfile)
|
||||
void Load_ScriptFile_Detour(int streamStart)
|
||||
{
|
||||
auto DB_PatchMem_PushAsset = reinterpret_cast<void(*)(size_t len, ScriptFile * script)>(0x140D8D860_g);
|
||||
auto Load_Stream = reinterpret_cast<void(*)(int streamStart, void* ptr, size_t size)>(0x1411B2A20_g);
|
||||
auto DB_PushStreamPos = reinterpret_cast<void(*)(int param_1)>(0x1411B2570_g);
|
||||
auto Load_XString = reinterpret_cast<void(*)(int param_1)>(0x140DD3400_g);
|
||||
auto DB_PopStreamPos = reinterpret_cast<void(*)(void)>(0x1411B24C0_g);
|
||||
auto DB_PatchMem_PopAsset = reinterpret_cast<void(*)(void)>(0x140D8D850_g);
|
||||
auto DB_ReadXFile = reinterpret_cast<void(*)(void* ptr, size_t size)>(0x1411A85D0_g);
|
||||
|
||||
if (scriptfile)
|
||||
ScriptFile** varScriptFile = reinterpret_cast<ScriptFile**>(0x145D43670_g);
|
||||
char** varXString = reinterpret_cast<char**>(0x145D417C0_g);
|
||||
char** varConstChar = reinterpret_cast<char**>(0x145D417B0_g);
|
||||
char** varbyte = reinterpret_cast<char**>(0x145D415D8_g);
|
||||
char** g_streamPosGlob_pos = reinterpret_cast<char**>(0x14D120C00_g);
|
||||
|
||||
char* backup;
|
||||
ScriptFile* scriptfile;
|
||||
|
||||
DB_PatchMem_PushAsset(ASSET_TYPE_SCRIPTFILE, *varScriptFile);
|
||||
Load_Stream(streamStart, *varScriptFile, sizeof(ScriptFile));
|
||||
DB_PushStreamPos(5);
|
||||
|
||||
char* xStringBackup = *varXString;
|
||||
*varXString = reinterpret_cast<char*>(*varScriptFile);
|
||||
Load_XString(1);
|
||||
*varXString = xStringBackup;
|
||||
DB_PushStreamPos(6);
|
||||
|
||||
scriptfile = *varScriptFile;
|
||||
|
||||
backup = *varConstChar;
|
||||
|
||||
printf("Loading scriptfile '%s' into database\n", scriptfile->name);
|
||||
std::string filepath = "script.gscbin";
|
||||
bool scriptgscbin = false;
|
||||
|
||||
if (!strcmp(scriptfile->name, "1892") && file_exists("script.gscbin"))
|
||||
{
|
||||
printf("loading gsc: %s\n", scriptfile->name);
|
||||
if (!strcmp(scriptfile->name, "1892"))
|
||||
scriptgscbin = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string scriptname = scriptfile->name;
|
||||
if (isSubStr(scriptname, ".gsc"))
|
||||
{
|
||||
printf("WAR GSC ASSET - %llX\nGSC - BYTECODE %llx\n", scriptfile, scriptfile->bytecode);
|
||||
std::ifstream script;
|
||||
script.open("script.gscbin", std::ios::binary | std::ios::ate);
|
||||
|
||||
int size = (int)script.tellg();
|
||||
script.seekg(0, std::ios::beg);
|
||||
|
||||
if (script.fail())
|
||||
{
|
||||
printf("Couldn't find file to inject");
|
||||
process_script_file.stub<void>(scrContext, scriptfile);
|
||||
return;
|
||||
}
|
||||
|
||||
auto Load_scriptFileAsset = reinterpret_cast<void* (*)(size_t size, size_t alignment, int pool, int stack, const char* hint)>(0x140F134D0_g);
|
||||
|
||||
char* allocMemAddress = (char*)Load_scriptFileAsset(size, 4, 0, 0, nullptr);
|
||||
|
||||
script.read(allocMemAddress, size);
|
||||
script.seekg(0, std::ios::beg);
|
||||
|
||||
while (script.get() != '\0') //read past the name
|
||||
{
|
||||
}
|
||||
|
||||
int vars[3] = { 0 };
|
||||
script.read((char*)vars, sizeof(int) * 3); //read header info
|
||||
|
||||
printf("vars[0] %X\n", vars[0]);
|
||||
printf("vars[1] %X\n", vars[1]);
|
||||
printf("vars[2] %X\n", vars[2]);
|
||||
printf("buffer 0x%llX\n", allocMemAddress + (int)script.tellg());
|
||||
printf("bytecode 0x%llX\n", allocMemAddress + vars[0] + script.tellg());
|
||||
|
||||
scriptfile->compressedLen = vars[0];
|
||||
scriptfile->len = vars[1];
|
||||
scriptfile->bytecodeLen = vars[2];
|
||||
scriptfile->buffer = allocMemAddress + (int)script.tellg();
|
||||
//scriptfile->bytecode = (unsigned char*)(allocMemAddress + vars[0] + (int)script.tellg());
|
||||
memcpy(scriptfile->bytecode, allocMemAddress + vars[0] + (int)script.tellg(), vars[2]);
|
||||
filepath = "donetsk/scripts/" + scriptname + "bin";
|
||||
}
|
||||
else // numbered scriptfiles like "1892"
|
||||
{
|
||||
filepath = "donetsk/scripts/" + scriptname + ".gscbin";
|
||||
}
|
||||
}
|
||||
|
||||
if (file_exists(filepath.c_str()) || scriptgscbin)
|
||||
{
|
||||
std::ifstream script;
|
||||
script.open(filepath, std::ios::binary | std::ios::ate);
|
||||
int size = (int)script.tellg();
|
||||
script.seekg(0, std::ios::beg);
|
||||
|
||||
char* customScript = new char[size];
|
||||
script.read(customScript, size);
|
||||
script.seekg(0, std::ios::beg);
|
||||
|
||||
while (script.get() != '\0'); // read past the name
|
||||
int vars[3] = { 0 };
|
||||
script.read((char*)vars, sizeof(int) * 3); //read header info
|
||||
|
||||
if (scriptfile->buffer != NULL)
|
||||
{
|
||||
*varConstChar = *g_streamPosGlob_pos;
|
||||
scriptfile->buffer = *varConstChar;
|
||||
|
||||
char* dummyMem = new char[scriptfile->compressedLen];
|
||||
DB_ReadXFile(dummyMem, scriptfile->compressedLen);
|
||||
delete[scriptfile->compressedLen] dummyMem;
|
||||
|
||||
memmove(*g_streamPosGlob_pos, customScript + (int)script.tellg(), vars[0]);
|
||||
|
||||
*g_streamPosGlob_pos = *g_streamPosGlob_pos + vars[0];
|
||||
scriptfile->compressedLen = vars[0];
|
||||
}
|
||||
*varConstChar = backup;
|
||||
scriptfile->len = vars[1];
|
||||
|
||||
DB_PopStreamPos();
|
||||
DB_PushStreamPos(6);
|
||||
|
||||
scriptfile = *varScriptFile;
|
||||
backup = *varbyte;
|
||||
|
||||
if (scriptfile->bytecode != NULL)
|
||||
{
|
||||
*varbyte = *g_streamPosGlob_pos;
|
||||
scriptfile->bytecode = (unsigned char*)*varbyte;
|
||||
|
||||
char* dummyMem = new char[scriptfile->bytecodeLen];
|
||||
DB_ReadXFile(dummyMem, scriptfile->bytecodeLen);
|
||||
delete[scriptfile->bytecodeLen] dummyMem;
|
||||
|
||||
memmove(*g_streamPosGlob_pos, customScript + vars[0] + (int)script.tellg(), vars[2]);
|
||||
|
||||
*g_streamPosGlob_pos = *g_streamPosGlob_pos + vars[2];
|
||||
scriptfile->bytecodeLen = vars[2];
|
||||
}
|
||||
*varbyte = backup;
|
||||
|
||||
delete[size] customScript;
|
||||
script.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (scriptfile->buffer != NULL)
|
||||
{
|
||||
*varConstChar = *g_streamPosGlob_pos;
|
||||
scriptfile->buffer = *varConstChar;
|
||||
Load_Stream(0, *varConstChar, scriptfile->compressedLen);
|
||||
}
|
||||
*varConstChar = backup;
|
||||
|
||||
DB_PopStreamPos();
|
||||
DB_PushStreamPos(6);
|
||||
|
||||
scriptfile = *varScriptFile;
|
||||
backup = *varbyte;
|
||||
if (scriptfile->bytecode != NULL)
|
||||
{
|
||||
*varbyte = *g_streamPosGlob_pos;
|
||||
scriptfile->bytecode = (unsigned char*)*varbyte;
|
||||
Load_Stream(0, *varbyte, scriptfile->bytecodeLen);
|
||||
}
|
||||
*varbyte = backup;
|
||||
}
|
||||
|
||||
DB_PopStreamPos();
|
||||
DB_PopStreamPos();
|
||||
DB_PatchMem_PopAsset();
|
||||
}
|
||||
|
||||
void dump_gsc_script(std::ofstream& stream, ScriptFile* scriptfile)
|
||||
{
|
||||
std::string buffer;
|
||||
buffer.append(scriptfile->name, strlen(scriptfile->name) + 1);
|
||||
|
||||
buffer.append(reinterpret_cast<char*>(&scriptfile->compressedLen), 4);
|
||||
buffer.append(reinterpret_cast<char*>(&scriptfile->len), 4);
|
||||
buffer.append(reinterpret_cast<char*>(&scriptfile->bytecodeLen), 4);
|
||||
buffer.append(scriptfile->buffer, scriptfile->compressedLen);
|
||||
buffer.append((char*)scriptfile->bytecode, scriptfile->bytecodeLen);
|
||||
|
||||
stream << buffer;
|
||||
}
|
||||
|
||||
|
||||
void ProcessScriptFile(void* scrContext, ScriptFile* scriptfile)
|
||||
{
|
||||
/*if (scriptfile)
|
||||
{
|
||||
if (strcmp(scriptfile->name, "1892") == 0)
|
||||
{
|
||||
std::ofstream gscbin_file("1892.gscbin", std::ios::out | std::ios::binary);
|
||||
if (gscbin_file.is_open())
|
||||
{
|
||||
dump_gsc_script(gscbin_file, scriptfile);
|
||||
gscbin_file.close();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if (g_dumpScripts->current.enabled)
|
||||
{
|
||||
std::string scriptFileStr = "";
|
||||
if (isSubStr(scriptfile->name, ".gsc"))
|
||||
{
|
||||
scriptFileStr = "gsc_dump/" + std::string(scriptfile->name) + "bin";
|
||||
}
|
||||
else
|
||||
{
|
||||
scriptFileStr = "gsc_dump/" + std::string(scriptfile->name) + ".gscbin";
|
||||
}
|
||||
|
||||
size_t lastSlash = scriptFileStr.find_last_of("/");
|
||||
if (lastSlash != std::string::npos && isSubStr(scriptfile->name, "/"))
|
||||
{
|
||||
std::string directory = scriptFileStr.substr(0, lastSlash);
|
||||
|
||||
std::filesystem::create_directories(directory);
|
||||
}
|
||||
|
||||
std::ofstream gscbin_file(scriptFileStr, std::ios::out | std::ios::binary);
|
||||
if (gscbin_file.is_open())
|
||||
{
|
||||
dump_gsc_script(gscbin_file, scriptfile);
|
||||
gscbin_file.close();
|
||||
}
|
||||
}
|
||||
|
||||
process_script_file.stub<void>(scrContext, scriptfile);
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
#include "Main.hpp"
|
||||
|
||||
void Load_ScriptFile_Detour(int streamStart);
|
||||
|
||||
inline utils::hook::detour process_script_file;
|
||||
void ProcessScriptFile(void* scrContext, ScriptFile* scriptfile);
|
@ -2086,6 +2086,27 @@ struct __declspec(align(8)) OmnvarDef
|
||||
byte userType[1];
|
||||
};
|
||||
|
||||
struct gameTypeInfo
|
||||
{
|
||||
char gameTypeInternalName[12];
|
||||
char gameTypeName[32];
|
||||
char customizedGameTypeName[64];
|
||||
char customizedGameTypeDesc[64];
|
||||
};
|
||||
|
||||
struct mapInfo
|
||||
{
|
||||
char mapName[32];
|
||||
char mapLoadName[16];
|
||||
char mapDescription[32];
|
||||
char mapLoadImage[32];
|
||||
char mapVoteImage[32];
|
||||
char mapCamoTypes[2][16];
|
||||
char mapDefaultGameType[32];
|
||||
char mapGameTypes[1024];
|
||||
int isAliensMap;
|
||||
int mapPack;
|
||||
};
|
||||
|
||||
struct scrContext_t :class_helper {
|
||||
|
||||
|
@ -12,11 +12,25 @@ void PM_WeaponUseAmmo_Detour(__int64 playerstate, Weapon* weapon, char a3, int a
|
||||
}
|
||||
}
|
||||
|
||||
void CG_OverrideImpactEffectType(uintptr_t localClientNum, unsigned int sourceEntityNum, int* fxImpactType) // 0x141733CD0_g
|
||||
void CG_OverrideImpactEffectType_Detour(uintptr_t localClientNum, unsigned int sourceEntityNum, int* fxImpactType) // 0x141733CD0_g
|
||||
{
|
||||
//33 = red, 34 = blue, 35 = pink, 36 = green
|
||||
fxImpactType[2] = 34;
|
||||
cg_overrideimpacteffecttype.stub<__int64>(localClientNum, sourceEntityNum, fxImpactType);
|
||||
if (weap_impactType->current.integer != -1)
|
||||
{
|
||||
int impactType = weap_impactType->current.integer;
|
||||
fxImpactType[2] = impactType;
|
||||
//33 = red, 34 = blue, 35 = pink, 36 = green
|
||||
}
|
||||
// cg_overrideimpacteffecttype.stub<__int64>(localClientNum, sourceEntityNum, fxImpactType);
|
||||
cg_overrideimpacteffecttype.stub<void>(localClientNum, sourceEntityNum, fxImpactType);
|
||||
}
|
||||
|
||||
bool BG_GetWeaponDismembermentEnabled_Detour(Weapon* weapon, bool alt)
|
||||
{
|
||||
if (weap_dismembermentAlwaysEnabled->current.enabled == true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return bg_getweapondismembermentenabled.stub<bool>(weapon, alt);
|
||||
}
|
||||
|
||||
TracerDef* GetTracerDef(const char* asset) {
|
||||
@ -54,6 +68,14 @@ void Dump_WeaponDef() {
|
||||
weaponDefJson[weap->szInternalName]["damageInfo"]["damageData"][i]["damage"] = weap->weapDef->damageInfo.damageData[i].damage;
|
||||
}
|
||||
|
||||
// spread
|
||||
weaponDefJson[weap->szInternalName]["playerSpread"] = weap->weapDef->playerSpread;
|
||||
weaponDefJson[weap->szInternalName]["hipSpreadStandMax"] = weap->weapDef->hipSpreadStandMax;
|
||||
|
||||
weaponDefJson[weap->szInternalName]["adsMoveSpeedScale"] = weap->weapDef->adsMoveSpeedScale;
|
||||
weaponDefJson[weap->szInternalName]["fAdsIdleAmount"] = weap->weapDef->fAdsIdleAmount;
|
||||
weaponDefJson[weap->szInternalName]["adsSpeedMs_0"] = weap->weapDef->adsSpeedMs[0];
|
||||
|
||||
// WeaponDef
|
||||
weaponDefJson[weap->szInternalName]["ladderWeapon"] = weap->weapDef->ladderWeapon;
|
||||
weaponDefJson[weap->szInternalName]["canHoldBreath"] = weap->weapDef->canHoldBreath;
|
||||
@ -107,6 +129,14 @@ void Load_WeaponDef() {
|
||||
weap->weapDef->damageInfo.damageData[i].damage = weaponDefJson[weap->szInternalName]["damageInfo"]["damageData"][i]["damage"];
|
||||
}
|
||||
|
||||
// spread
|
||||
weap->weapDef->playerSpread = weaponDefJson[weap->szInternalName]["playerSpread"];
|
||||
weap->weapDef->hipSpreadStandMax = weaponDefJson[weap->szInternalName]["hipSpreadStandMax"];
|
||||
|
||||
weap->weapDef->adsMoveSpeedScale = weaponDefJson[weap->szInternalName]["adsMoveSpeedScale"];
|
||||
weap->weapDef->fAdsIdleAmount = weaponDefJson[weap->szInternalName]["fAdsIdleAmount"];
|
||||
weap->weapDef->adsSpeedMs[0] = weaponDefJson[weap->szInternalName]["adsSpeedMs_0"];
|
||||
|
||||
weap->weapDef->ladderWeapon = weaponDefJson[weap->szInternalName]["ladderWeapon"];
|
||||
weap->weapDef->canHoldBreath = weaponDefJson[weap->szInternalName]["canHoldBreath"];
|
||||
weap->weapDef->iFireTime = weaponDefJson[weap->szInternalName]["iFireTime"];
|
||||
|
@ -5,7 +5,10 @@ inline utils::hook::detour PM_WeaponUseAmmo;
|
||||
void PM_WeaponUseAmmo_Detour(__int64 playerstate, Weapon* weapon, char a3, int a4, int hand);
|
||||
|
||||
inline utils::hook::detour cg_overrideimpacteffecttype;
|
||||
void CG_OverrideImpactEffectType(uintptr_t localClientNum, unsigned int sourceEntityNum, int* fxImpactType);
|
||||
void CG_OverrideImpactEffectType_Detour(uintptr_t localClientNum, unsigned int sourceEntityNum, int* fxImpactType);
|
||||
|
||||
inline utils::hook::detour bg_getweapondismembermentenabled;
|
||||
bool BG_GetWeaponDismembermentEnabled_Detour(Weapon* weapon, bool alt);
|
||||
|
||||
TracerDef* GetTracerDef(const char* asset);
|
||||
|
||||
|
BIN
lib/discord-rpc.lib
Normal file
BIN
lib/discord-rpc.lib
Normal file
Binary file not shown.
BIN
lib/minhook.lib
BIN
lib/minhook.lib
Binary file not shown.
@ -1,6 +0,0 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:recommended"
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user