Finish updater

This commit is contained in:
Grinch_ 2021-03-15 02:54:55 +06:00
parent 8a1f984d5c
commit c0bb8d3e71
10 changed files with 8784 additions and 17 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@ build/
.vscode/.BROWSE.VC.DB
.gitignore
.vscode/BROWSE.VC.DB
CheatMenu/json/versioninfo.json

View File

@ -17,8 +17,6 @@ Cheat menu for Grand Theft Auto SanAndreas which allows a large set of modificat
Get stable binaries from [here](https://github.com/user-grinch/Cheat-Menu/releases). Beta binaries are available at the discord server.
A portuguese translation of the menu is [here](https://github.com/Dowglass/Cheat-Menu)
## Installation
1. Install [DirectX9](https://www.microsoft.com/en-us/download/details.aspx?id=35) & [Visual C++ Redistributable 2019 x86](hhttps://aka.ms/vs/16/release/vc_redist.x86.exe) if not already installed.
@ -34,6 +32,7 @@ You'll need to install Visual Studio 2019 (v142), [DirectX9 SDK](https://www.mic
2. [Kiero](https://github.com/Rebzzel/kiero)
3. [MinHook](https://github.com/TsudaKageyu/minhook)
4. [Plugin SDK](https://github.com/DK22Pac/plugin-sdk)
5. [Zip](https://github.com/kuba--/zip)
## Images
<details>

3
deps/CMakeLists.txt vendored
View File

@ -39,6 +39,9 @@ set(depend_files
"kiero/minhook/trampoline.c"
"kiero/minhook/hde/hde32.c"
"kiero/minhook/trampoline.c"
"zip/miniz.h"
"zip/zip.h"
"zip/zip.c"
)
add_library(${PROJECT_NAME} STATIC ${depend_files})

6874
deps/zip/miniz.h vendored Normal file

File diff suppressed because it is too large Load Diff

1482
deps/zip/zip.c vendored Normal file

File diff suppressed because it is too large Load Diff

351
deps/zip/zip.h vendored Normal file
View File

@ -0,0 +1,351 @@
/*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#ifndef ZIP_H
#define ZIP_H
#include <string.h>
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(_POSIX_C_SOURCE) && defined(_MSC_VER)
// 64-bit Windows is the only mainstream platform
// where sizeof(long) != sizeof(void*)
#ifdef _WIN64
typedef long long ssize_t; /* byte count or error */
#else
typedef long ssize_t; /* byte count or error */
#endif
#endif
#ifndef MAX_PATH
#define MAX_PATH 32767 /* # chars in a path name including NULL */
#endif
/**
* @mainpage
*
* Documenation for @ref zip.
*/
/**
* @addtogroup zip
* @{
*/
/**
* Default zip compression level.
*/
#define ZIP_DEFAULT_COMPRESSION_LEVEL 6
/**
* @struct zip_t
*
* This data structure is used throughout the library to represent zip archive -
* forward declaration.
*/
struct zip_t;
/**
* Opens zip archive with compression level using the given mode.
*
* @param zipname zip archive file name.
* @param level compression level (0-9 are the standard zlib-style levels).
* @param mode file access mode.
* - 'r': opens a file for reading/extracting (the file must exists).
* - 'w': creates an empty file for writing.
* - 'a': appends to an existing archive.
*
* @return the zip archive handler or NULL on error
*/
extern struct zip_t *zip_open(const char *zipname, int level, char mode);
/**
* Closes the zip archive, releases resources - always finalize.
*
* @param zip zip archive handler.
*/
extern void zip_close(struct zip_t *zip);
/**
* Determines if the archive has a zip64 end of central directory headers.
*
* @param zip zip archive handler.
*
* @return the return code - 1 (true), 0 (false), negative number (< 0) on
* error.
*/
extern int zip_is64(struct zip_t *zip);
/**
* Opens an entry by name in the zip archive.
*
* For zip archive opened in 'w' or 'a' mode the function will append
* a new entry. In readonly mode the function tries to locate the entry
* in global dictionary.
*
* @param zip zip archive handler.
* @param entryname an entry name in local dictionary.
*
* @return the return code - 0 on success, negative number (< 0) on error.
*/
extern int zip_entry_open(struct zip_t *zip, const char *entryname);
/**
* Opens a new entry by index in the zip archive.
*
* This function is only valid if zip archive was opened in 'r' (readonly) mode.
*
* @param zip zip archive handler.
* @param index index in local dictionary.
*
* @return the return code - 0 on success, negative number (< 0) on error.
*/
extern int zip_entry_openbyindex(struct zip_t *zip, int index);
/**
* Closes a zip entry, flushes buffer and releases resources.
*
* @param zip zip archive handler.
*
* @return the return code - 0 on success, negative number (< 0) on error.
*/
extern int zip_entry_close(struct zip_t *zip);
/**
* Returns a local name of the current zip entry.
*
* The main difference between user's entry name and local entry name
* is optional relative path.
* Following .ZIP File Format Specification - the path stored MUST not contain
* a drive or device letter, or a leading slash.
* All slashes MUST be forward slashes '/' as opposed to backwards slashes '\'
* for compatibility with Amiga and UNIX file systems etc.
*
* @param zip: zip archive handler.
*
* @return the pointer to the current zip entry name, or NULL on error.
*/
extern const char *zip_entry_name(struct zip_t *zip);
/**
* Returns an index of the current zip entry.
*
* @param zip zip archive handler.
*
* @return the index on success, negative number (< 0) on error.
*/
extern int zip_entry_index(struct zip_t *zip);
/**
* Determines if the current zip entry is a directory entry.
*
* @param zip zip archive handler.
*
* @return the return code - 1 (true), 0 (false), negative number (< 0) on
* error.
*/
extern int zip_entry_isdir(struct zip_t *zip);
/**
* Returns an uncompressed size of the current zip entry.
*
* @param zip zip archive handler.
*
* @return the uncompressed size in bytes.
*/
extern unsigned long long zip_entry_size(struct zip_t *zip);
/**
* Returns CRC-32 checksum of the current zip entry.
*
* @param zip zip archive handler.
*
* @return the CRC-32 checksum.
*/
extern unsigned int zip_entry_crc32(struct zip_t *zip);
/**
* Compresses an input buffer for the current zip entry.
*
* @param zip zip archive handler.
* @param buf input buffer.
* @param bufsize input buffer size (in bytes).
*
* @return the return code - 0 on success, negative number (< 0) on error.
*/
extern int zip_entry_write(struct zip_t *zip, const void *buf, size_t bufsize);
/**
* Compresses a file for the current zip entry.
*
* @param zip zip archive handler.
* @param filename input file.
*
* @return the return code - 0 on success, negative number (< 0) on error.
*/
extern int zip_entry_fwrite(struct zip_t *zip, const char *filename);
/**
* Extracts the current zip entry into output buffer.
*
* The function allocates sufficient memory for a output buffer.
*
* @param zip zip archive handler.
* @param buf output buffer.
* @param bufsize output buffer size (in bytes).
*
* @note remember to release memory allocated for a output buffer.
* for large entries, please take a look at zip_entry_extract function.
*
* @return the return code - the number of bytes actually read on success.
* Otherwise a -1 on error.
*/
extern ssize_t zip_entry_read(struct zip_t *zip, void **buf, size_t *bufsize);
/**
* Extracts the current zip entry into a memory buffer using no memory
* allocation.
*
* @param zip zip archive handler.
* @param buf preallocated output buffer.
* @param bufsize output buffer size (in bytes).
*
* @note ensure supplied output buffer is large enough.
* zip_entry_size function (returns uncompressed size for the current
* entry) can be handy to estimate how big buffer is needed. for large
* entries, please take a look at zip_entry_extract function.
*
* @return the return code - the number of bytes actually read on success.
* Otherwise a -1 on error (e.g. bufsize is not large enough).
*/
extern ssize_t zip_entry_noallocread(struct zip_t *zip, void *buf,
size_t bufsize);
/**
* Extracts the current zip entry into output file.
*
* @param zip zip archive handler.
* @param filename output file.
*
* @return the return code - 0 on success, negative number (< 0) on error.
*/
extern int zip_entry_fread(struct zip_t *zip, const char *filename);
/**
* Extracts the current zip entry using a callback function (on_extract).
*
* @param zip zip archive handler.
* @param on_extract callback function.
* @param arg opaque pointer (optional argument, which you can pass to the
* on_extract callback)
*
* @return the return code - 0 on success, negative number (< 0) on error.
*/
extern int
zip_entry_extract(struct zip_t *zip,
size_t (*on_extract)(void *arg, unsigned long long offset,
const void *data, size_t size),
void *arg);
/**
* Returns the number of all entries (files and directories) in the zip archive.
*
* @param zip zip archive handler.
*
* @return the return code - the number of entries on success, negative number
* (< 0) on error.
*/
extern int zip_total_entries(struct zip_t *zip);
/**
* Creates a new archive and puts files into a single zip archive.
*
* @param zipname zip archive file.
* @param filenames input files.
* @param len: number of input files.
*
* @return the return code - 0 on success, negative number (< 0) on error.
*/
extern int zip_create(const char *zipname, const char *filenames[], size_t len);
/**
* Extracts a zip archive file into directory.
*
* If on_extract_entry is not NULL, the callback will be called after
* successfully extracted each zip entry.
* Returning a negative value from the callback will cause abort and return an
* error. The last argument (void *arg) is optional, which you can use to pass
* data to the on_extract_entry callback.
*
* @param zipname zip archive file.
* @param dir output directory.
* @param on_extract_entry on extract callback.
* @param arg opaque pointer.
*
* @return the return code - 0 on success, negative number (< 0) on error.
*/
extern int zip_extract(const char *zipname, const char *dir,
int (*on_extract_entry)(const char *filename, void *arg),
void *arg);
/**
* Extracts a zip archive stream into directory.
*
* If on_extract is not NULL, the callback will be called after
* successfully extracted each zip entry.
* Returning a negative value from the callback will cause abort and return an
* error. The last argument (void *arg) is optional, which you can use to pass
* data to the on_extract callback.
*
* @param stream zip archive stream.
* @param size stream size.
* @param dir output directory.
* @param on_extract on extract callback.
* @param arg opaque pointer.
*
* @return the return code - 0 on success, negative number (< 0) on error.
*/
extern int zip_extract_stream(const char *stream, size_t size, const char *dir,
int (*on_extract)(const char *filename,
void *arg),
void *arg);
/**
* Opens zip archive stream into memory.
*
* @param stream zip archive stream.
* @param size stream size.
*
* @return the zip archive handler or NULL on error
*/
extern struct zip_t *zip_open_stream(const char *stream, size_t size);
/**
* Deletes zip archive entries.
*
* @param zip zip archive handler.
* @param entries array of zip archive entries to be deleted.
* @param len the number of entries to be deleted.
* @return the number of deleted entries, or negative number (< 0) on error.
*/
extern int zip_entries_delete(struct zip_t *zip, char *const entries[],
size_t len);
/** @} */
#ifdef __cplusplus
}
#endif
#endif

View File

@ -45,7 +45,7 @@ void CheatMenu::DrawWindow()
if (Updater::state == UPDATER_DOWNLOADED)
{
if (ImGui::Button("Update downloaded. Click to install.",Ui::GetSize()))
Updater::state = UPDATER_IDLE;
Updater::state = UPDATER_INSTALLING;
}
Ui::DrawHeaders(header);
@ -224,23 +224,36 @@ void MenuThread(void* param)
break;
if (Updater::state == UPDATER_CHECKING)
Updater::CheckForUpdates();
Updater::CheckForUpdate();
if (Updater::state == UPDATER_DOWNLOADING)
Updater::DownloadUpdate();
if (Updater::state == UPDATER_INSTALLING)
{
Updater::InstallUpdate();
break;
}
}
delete menu;
Sleep(100);
CHud::SetHelpMessage("CheatMenu unloaded",false,false,false);
flog << "Unloaded" << std::endl;
// reset mouse patches
patch::SetUChar(0x6194A0, 0xE9);
patch::SetUChar(0x746ED0, 0xA1);
patch::SetRaw(0x53F41F, (void*)"\x85\xC0\x0F\x8C", 4);
FreeLibraryAndExitThread(GetModuleHandle("CheatMenu.asi"),0);
if (Updater::state == UPDATER_INSTALLING)
{
CHud::SetHelpMessage("Install complete, restarting menu!",false,false,false);
Updater::FinishUpdate();
}
else
{
CHud::SetHelpMessage("CheatMenu unloaded",false,false,false);
FreeLibraryAndExitThread(GetModuleHandle("CheatMenu.asi"),0);
FreeLibraryAndExitThread(GetModuleHandle("CheatMenuNew.asi"),0);
}
}
BOOL WINAPI DllMain(HINSTANCE hDllHandle, DWORD nReason, LPVOID Reserved)

View File

@ -1,11 +1,12 @@
#include "Updater.h"
#include "pch.h"
#include "MenuInfo.h"
#include "..\deps\zip\zip.h"
void Updater::CheckForUpdates()
void Updater::CheckForUpdate()
{
LPCSTR link = "https://api.github.com/repos/user-grinch/Cheat-Menu/tags";
LPCSTR path = PLUGIN_PATH((char*)"CheatMenu/json/versioninfo.json");
const char* link = "https://api.github.com/repos/user-grinch/Cheat-Menu/tags";
char* path = PLUGIN_PATH((char*)"CheatMenu/json/versioninfo.json");
HRESULT res = URLDownloadToFile(NULL, link, path, 0, NULL);
if (res == E_OUTOFMEMORY || res == INET_E_DOWNLOAD_FAILURE)
@ -32,8 +33,8 @@ void Updater::CheckForUpdates()
void Updater::DownloadUpdate()
{
std::string link = "https://github.com/user-grinch/Cheat-Menu/releases/download/" + latest_version + "/CheatMenu.7z";
LPCSTR path = PLUGIN_PATH((char*)"update.7z");
std::string link = "https://github.com/user-grinch/Cheat-Menu/releases/download/" + latest_version + "/CheatMenu.zip";
char* path = PLUGIN_PATH((char*)"update.zip");
HRESULT res = URLDownloadToFile(NULL, link.c_str(), path, 0, NULL);
if (res == E_OUTOFMEMORY || res == INET_E_DOWNLOAD_FAILURE)
@ -44,4 +45,45 @@ void Updater::DownloadUpdate()
}
CHud::SetHelpMessage("Update downloaded successfully.",false,false,false);
state = UPDATER_DOWNLOADED;
}
void Updater::InstallUpdate()
{
CHud::SetHelpMessage("Updating in progress. Do not pause/close the game.",false,false,false);
Sleep(100);
// delete the old menu
std::remove(PLUGIN_PATH((char*)"CheatMenu.asi.old"));
std::string new_name = PLUGIN_PATH((char*)"CheatMenu.asi.old");
std::string old_name = PLUGIN_PATH((char*)"CheatMenu.asi");
std::rename(old_name.c_str(),new_name.c_str());
fs::remove_all(PLUGIN_PATH((char*)"CheatMenu"));
std::string dir = PLUGIN_PATH((char*)"");
std::string file = PLUGIN_PATH((char*)"update.zip");
zip_extract(file.c_str(),dir.c_str(),NULL,NULL);
}
static bool menu_loaded = false;
static void LoadUpdatedMenu()
{
std::string new_name = PLUGIN_PATH((char*)"CheatMenuNew.asi");
LoadLibrary(new_name.c_str());
menu_loaded = true;
}
void Updater::FinishUpdate()
{
// kinda hacky
std::string new_name = PLUGIN_PATH((char*)"CheatMenuNew.asi");
std::string old_name = PLUGIN_PATH((char*)"CheatMenu.asi");
std::rename(old_name.c_str(),new_name.c_str());
Events::processScriptsEvent += LoadUpdatedMenu;
while (!menu_loaded)
Sleep(1000);
Events::processScriptsEvent -= LoadUpdatedMenu;
std::rename(new_name.c_str(),old_name.c_str());
}

View File

@ -15,7 +15,9 @@ class Updater
public:
inline static UPDATER_STATE state = UPDATER_IDLE;
inline static std::string latest_version = "";
static void CheckForUpdates();
// TODO: fix memory leak
static void CheckForUpdate();
static void DownloadUpdate();
static void InstallUpdate();
static void FinishUpdate();
};

View File

@ -42,7 +42,7 @@ int main()
procId = GetProcId(procName);
Sleep(30);
}
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, procId);
if (hProc && hProc != INVALID_HANDLE_VALUE)