Есть код чатлоггера от Наруто. Ничего в c++ не понимаю, но возможно кто-то знает как сделать вначале каждой строки в чатлоге дату по типу...
Вот сам код...
Код:
[22.12.2017][12:42:12] Connected. Joining the game...
[22.12.2017]"- Это добавить. "[12:42:12] Connected. Joining the game..."- Это серверное.
Вот сам код...
Код:
#include <windows.h>
#include <string>
#include <assert.h>
#include <process.h>
#include <ctime>
#include "SAMPFUNCS_API.h"
// Enhanced Chatlog plugin for SAMPFUNCS 5.2
// by NarutoUA for BlastHack.net
#define SAMPAddr SF->getSAMP()->getSAMPAddr()
SAMPFUNCS *SF = new SAMPFUNCS();
using namespace std;
struct stDate{
char mon_s[3], day_s[3], year_s[3], hour_s[3], min_s[3];
};
stDate myDate;
DWORD file; // we save file pointer here
char msg[256];
DWORD offsetA;
DWORD ret_fclose;
void hook_sprintf(){
_asm pushad
DWORD offset1, offset2;
offset1 = offset2 = SF->getSAMP()->getSAMPAddr();
offset1 += 0x219F88;
offset2 += 0x219E80;
char chatlog_path[260];
sprintf(chatlog_path, "%s\\ChatLogs", (char*)offset1);
// Check is directory exist
bool result = ((bool(__cdecl *)(int)) (SF->getSAMP()->getSAMPAddr() + 0xAF480))(((int)&chatlog_path));
if (!result)
CreateDirectoryA(chatlog_path, 0);
sprintf((char*)offset2, "%s\\ChatLogs\\ChatLogs - %s.20%s.txt", (char*)offset1, myDate.mon_s, myDate.year_s);
_asm popad
}
__declspec(naked) void hook_fclose(){
// Save file pointer
__asm mov file,eax
// Restore original
__asm push eax
__asm mov[esi + 0x0D], 0x00000001
__asm jmp[ret_fclose]
}
void CALLBACK mainloop(void)
{
static bool patched = false;
if (!patched){
if (!SAMPAddr) return;
//
// STUFF
//
// Get time + date
time_t t = time(0);
struct tm * now = localtime(&t);
int year;
// Date
now->tm_year += 1900;
now->tm_year %= 100;
// Дата
sprintf(myDate.year_s, "%02d", now->tm_year); // прочитай где нибудь в интернете, про параметры printf
sprintf(myDate.mon_s, "%02d", ++now->tm_mon); // префиксный инкремент, аналогично now->tm_mon += 1, возвращает увеличенное значение
sprintf(myDate.day_s, "%02d", now->tm_mday);
// Время
sprintf(myDate.hour_s, "%d", now->tm_hour);
sprintf(myDate.min_s, "%02d", now->tm_min);
// calculate offset for "a" atribute
offsetA = SAMPAddr + 0xD3E34;
char offA[6];
char tmp;
// логичное линейное решение, цикл тут излишний
offA[4] = (offsetA >> 0x18); // думаю тут уместнее смещение, чем деление
offA[3] = (offsetA >> 0x10); // модуль по 0x100, нахуй не нужен
offA[2] = (offsetA >> 0x08); // потому что BYTE больше 0x100 быть не может
std::swap(offA[1], offA[4]);
offA[4] = tmp;
tmp = offA[2];
std::swap(offA[1], offA[4]);
//
// PATCHES
//
DWORD protect;
// Patch "w" atribute to "a"
VirtualProtect((void*)(SAMPAddr + 0x6485B), 5, PAGE_EXECUTE_READWRITE, &protect);
memcpy((void *)(SAMPAddr + 0x6485B), (uint8_t *)offA, 5);
VirtualProtect((void*)(SAMPAddr + 0x6485B), 5, protect, &protect);
// NOP fclose function
VirtualProtect((void*)(SAMPAddr + 0x64876), 5, PAGE_EXECUTE_READWRITE, &protect);
memcpy((void *)(SAMPAddr + 0x64876), "\x90\x90\x90\x90\x90", 5);
VirtualProtect((void*)(SAMPAddr + 0x64876), 5, protect, &protect);
//
// HOOKS
//
// "Copy file pointer" hook
ret_fclose = 0x6486E + 8 + SAMPAddr;
SF->getGame()->createHook((void*)(SF->getSAMP()->getSAMPAddr() + 0x6486E), hook_fclose, DETOUR_TYPE_JMP, 8);
// "Folder" hook
SF->getGame()->createHook((void*)(SF->getSAMP()->getSAMPAddr() + 0x2FCC72), hook_sprintf, DETOUR_TYPE_CALL_FUNC, 5);
}
static bool bfile = false;
if (!bfile){
if (!file)return;
// Write to file current Date and Time
sprintf(msg, "\n\n\n\t// Дата: %s.%s.%s\n\t// Время: %s:%s\n\n\n\n", myDate.day_s, myDate.mon_s, myDate.year_s, myDate.hour_s, myDate.min_s);
((int(__cdecl *)(int, int)) (SF->getSAMP()->getSAMPAddr() + 0xB79BC))(file, (int)msg); // fprintf
((signed int(__cdecl *)(int)) (SF->getSAMP()->getSAMPAddr() + 0xB67E6))(file); // fclose
bfile = true;
}
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReasonForCall, LPVOID lpReserved)
{
switch (dwReasonForCall)
{
case DLL_PROCESS_ATTACH:
SF->initPlugin(mainloop, hModule);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}