Другое С/С++ Вопрос - Ответ

ishi

Известный
444
106
C++:
ofstream fout("yiffme", ios::app);
Объявить это дело глобально при помощи extern не удаётся, в связи с чем вопрос: каким образом объявить fout внутри функции глобальной переменной?
 

ishi

Известный
444
106
Создавай указатель.
C++:
extern int *ptr = &fout;
выдаёт
Код:
1>main.cpp(53): error C2205: ptr: невозможно инициализировать внешние переменные с областью видимости блока
Последние три слова мне вообще ничего не говорят ._.
гугл тоже не смог мне помочь. Всё плохо.
 
Последнее редактирование:

Dark_Knight

Режим чтения
3,330
1,355
Не так надо.
Пример
C:
в main.h
extern int *ptr;

в main.cpp
int *ptr = nullptr;

void main(){
if(!ptr)
    ptr = new int;
}
 
  • Нравится
Реакции: ishi

ishi

Известный
444
106
в main.cpp:
C++:
int *ptr = nullptr;
в main.h:
C++:
extern int *ptr;
В void callback mainloop:
C++:
*ptr = &fout;
Ошибка:
Код:
error C2440: =: невозможно преобразовать "std::ofstream *" в "int"
 

ishi

Известный
444
106
Так ты объявляй ofstream, а не int
main.h
Код:
extern ofstream *ptr;
main.cpp
C++:
ofstream *ptr = nullptr;
void callback mainloop
C++:
*ptr = &fout;
ошибки:
Код:
1>main.cpp(17): error C2371: ptr: переопределение; различные базовые типы
1>  c:\users\snezh\documents\visual studio 2013\projects\aa\sfplugin\qwe\main.h(1): см. объявление "ptr"
1>main.cpp(53): error C2440: =: невозможно преобразовать "std::ofstream *" в "int"
1>  Не существует контекста, в котором такое преобразование возможно
1>
 

MISTER_GONWIK

Друг
Друг
1,095
1,193
C++:
ofstream fout("yiffme", ios::app);
Объявить это дело глобально при помощи extern не удаётся, в связи с чем вопрос: каким образом объявить fout внутри функции глобальной переменной?
C++:
// main.cpp
ofstream fout("yiffme", ios::app);

// main.h
extern ofstream fout;
 

Dark_Knight

Режим чтения
3,330
1,355
Какая у тебя задача вообще ? А то щас настроеш код из говна и палок и потом хер разберешься почему у тебя крашит.
 

ishi

Известный
444
106
Какая у тебя задача вообще ? А то щас настроеш код из говна и палок и потом хер разберешься почему у тебя крашит.
Отлично сказано.
Да вот я хотел поставить условие на проверку существования файла для логов, и открывать файл создавая указатель для записи, в зависимости от его наличия - есть файл, пишем с конца . Нет файла - создаём заново. Вот. И поскольку заполнение лога идёт через хук, мне требуется создать указатель на файл, (fout) в mainloop, чтобы он был доступен коллбеку irpc, вот код если не понятно:
C++:
#include <windows.h>
#include <string>
#include <assert.h>
#include <process.h>
#include "SAMPFUNCS_API.h"
#include "game_api\game_api.h"
#include "SFAPI\SFRakNet.h"
#include <tchar.h>
#include <fstream>
#include <stdlib.h>
#include <iostream>
#include <Shlwapi.h>
#include "qwe\main.h"
#pragma comment(lib, "shlwapi.lib")
using namespace std;
SAMPFUNCS *SF = new SAMPFUNCS();
int *a = nullptr;
bool CALLBACK irpc(stRakNetHookParams *params)
{
   if (params->packetId == ScriptRPCEnumeration::RPC_ScrClientMessage) // id: 93 thanks for MISTER_GONWIK
   {
     D3DCOLOR color = -1;
     int length = 0;
     char message[144]{ 0 };
     params->bitStream->Read(color);
     params->bitStream->Read(length);
     params->bitStream->Read(message, length);
     //sss[len] = '\0';
     if (strcmp(string(message).c_str(), " ") == 0)
       return false;
     else
     {
       //SF->getSAMP()->getChat()->AddChatMessage(555555, "%s", string(message).c_str());
       //fout << "\n" << string(message).c_str();
     }
   }
   return true;
}

void CALLBACK mainloop()
{
   static bool init = false;
   if (!init)
   {
     if (GAME == nullptr)
       return;
     if (GAME->GetSystemState() != eSystemState::GS_PLAYING_GAME)
       return;
     if (!SF->getSAMP()->IsInitialized())
     return;
     init = true;
     char meow[MAX_PATH];
     GetCurrentDirectory(sizeof(meow), meow);
     if (PathFileExists(strcat(meow, "/yiffme")))
     {
       ofstream fout("yiffme", ios::app);
       *a = reinterpret_cast<int>(&fout);
       SF->getSAMP()->getChat()->AddChatMessage(555555, "file exist");
     }
     else
       SF->getSAMP()->getChat()->AddChatMessage(555555, "file doesnt exist");
     fout << "\nsession started";
     SF->getRakNet()->registerRakNetCallback(RakNetScriptHookType::RAKHOOK_TYPE_INCOMING_RPC, irpc);
   }
}
 

MISTER_GONWIK

Друг
Друг
1,095
1,193
Отлично сказано.
Да вот я хотел поставить условие на проверку существования файла для логов, и открывать файл создавая указатель для записи, в зависимости от его наличия - есть файл, пишем с конца . Нет файла - создаём заново. Вот. И поскольку заполнение лога идёт через хук, мне требуется создать указатель на файл, (fout) в mainloop, чтобы он был доступен коллбеку irpc, вот код если не понятно:
C++:
#include <windows.h>
#include <string>
#include <assert.h>
#include <process.h>
#include "SAMPFUNCS_API.h"
#include "game_api\game_api.h"
#include "SFAPI\SFRakNet.h"
#include <tchar.h>
#include <fstream>
#include <stdlib.h>
#include <iostream>
#include <Shlwapi.h>
#include "qwe\main.h"
#pragma comment(lib, "shlwapi.lib")
using namespace std;
SAMPFUNCS *SF = new SAMPFUNCS();
int *a = nullptr;
bool CALLBACK irpc(stRakNetHookParams *params)
{
   if (params->packetId == ScriptRPCEnumeration::RPC_ScrClientMessage) // id: 93 thanks for MISTER_GONWIK
   {
     D3DCOLOR color = -1;
     int length = 0;
     char message[144]{ 0 };
     params->bitStream->Read(color);
     params->bitStream->Read(length);
     params->bitStream->Read(message, length);
     //sss[len] = '\0';
     if (strcmp(string(message).c_str(), " ") == 0)
       return false;
     else
     {
       //SF->getSAMP()->getChat()->AddChatMessage(555555, "%s", string(message).c_str());
       //fout << "\n" << string(message).c_str();
     }
   }
   return true;
}

void CALLBACK mainloop()
{
   static bool init = false;
   if (!init)
   {
     if (GAME == nullptr)
       return;
     if (GAME->GetSystemState() != eSystemState::GS_PLAYING_GAME)
       return;
     if (!SF->getSAMP()->IsInitialized())
     return;
     init = true;
     char meow[MAX_PATH];
     GetCurrentDirectory(sizeof(meow), meow);
     if (PathFileExists(strcat(meow, "/yiffme")))
     {
       ofstream fout("yiffme", ios::app);
       *a = reinterpret_cast<int>(&fout);
       SF->getSAMP()->getChat()->AddChatMessage(555555, "file exist");
     }
     else
       SF->getSAMP()->getChat()->AddChatMessage(555555, "file doesnt exist");
     fout << "\nsession started";
     SF->getRakNet()->registerRakNetCallback(RakNetScriptHookType::RAKHOOK_TYPE_INCOMING_RPC, irpc);
   }
}
Это лишь пример накидал, но не пользуйся такими дерьмовыми функциями как:
C++:
GetCurrentDirectory(..), PathFileExists(..) и т.д.
займись изучением чего-то более классного и функционального

C++:
// после всех инклудов
#include <filesystem>
namespace fs = std::experimental::filesystem;

// самой первой функцией
std::ofstream& log()
{
    static std::ofstream logFile;
    if (logFile.is_open() == false)
    {
        fs::path workDirectoryPath = fs::current_path() / "SAMPFUNCS" / "Meow";
        if (!fs::exists(workDirectoryPath))
            fs::create_directories(workDirectoryPath);

        fs::path logFilePath = workDirectoryPath / "yiffme.fr";
        bool fileExists = fs::exists(logFilePath);

        logFile.open(logFilePath.string(), std::ios::app);
        if (fileExists == true)
           logFile << std::endl;
    }
    return logFile;
}
ну и mainloop в твоём случае должен выглядеть вот так:
C++:
void CALLBACK mainloop()
{
    static bool init = false;
    if (!init)
    {
        if (GAME == nullptr) return;
        if (!SF->getSAMP()->IsInitialized()) return;

        SF->getRakNet()->registerRakNetCallback(RakNetScriptHookType::RAKHOOK_TYPE_INCOMING_RPC, incomingRPC);
        log() << "Session started." << std::endl;

        init = true;
    }
}
а irpc
C++:
bool CALLBACK incomingRPC(stRakNetHookParams *params)
{
    if (params->packetId == ScriptRPCEnumeration::RPC_ScrClientMessage) // id: 93 thanks for MISTER_GONWIK
    {
        D3DCOLOR color = -1;
        int length = 0;
        char message[144]{ 0 };

        params->bitStream->Read(color);
        params->bitStream->Read(length);
        params->bitStream->Read(message, length);
        if (!strcmp(message, " "))
            return false;
     
       log() << message << std::endl;
    }
    return true;
}
 
Последнее редактирование:
  • Нравится
Реакции: ishi

winrare

Новичок
75
0
Запустил через RakSAMP три бота на advance. Примерно через 10 минут двух ботов телепортировал к себе администратор, а ещё через минуту забанил всех трех за использование "песочницы".
Как он определил, что я использую "песочницу"? Скорее всего посмотрел, что одинаковые ip, но как тогда можно обмануть админов? Можно сделать, чтобы боты двигались, но администратор может телепортировать в любую точку и бот тупо может забежать в стену.