Customize the Loader

About the Loader

We have a standard loader that will have your logo only, this loader can be used by both customers and your team. In addition to the standard loader, we have an opensource project that will allow you to create your own loader with your design (or integrate with your existing loader if you have other providers). You will receive the project link when you are within our resale system. See the customization tutorial below:

Features

  • Imgui UI
  • Automatic requirements check
  • Version checking and automatic updater
  • Block the use of keys that are not from your store
  • Customization of the cheat menu color
  • Injector using our GUI-less loader

Customization

We have provided a simple tutorial on how to fully customize the project.

  • To customize the automatic updates, edit the file located at Includes/Version/Version.cpp.
  • To customize the requirements check, edit the file located at Includes/Requirements/Requirements.cpp.
  • To customize the user interface, edit the file located at Includes/Menu/Menu.cpp.
  • To customize the key blocking feature, edit the file located at Includes/Server/Server.cpp.
  • To customize the cheat menu color, use the file located at Includes/Server/Server.cpp.
  • To setup your store Includes/Menu/Menu.h.
  • This loader was made for both customers and your team, customers will use a login key and your team will use the email and password registered on the panel. You will need to compile the loader twice, to switch between client mode and team mode, change the variable IsForTeam which is located in the file Includes/Menu/Menu.h
  • For your team's loader, you need to configure the store_id variable with your store's ID, which you can find in the dashboard URL.

Tutorial for Customization

1. Configuring Requirement Checker

Step 1: Open the requirements file

Go to the file Loader/Includes/Requirements/Requirements.cpp.

Step 2: Locate the requirements check code

Starting from line 84, you will find the following code:

bool Requeriments::CheckRequeriments() {
  if (!CheckDefender())
    return false;
  if (!CheckUEFI())
    return false;
  return true;
}

The verification functions are separated by:

  • CheckDefender: Checks if Windows Defender is disabled.
  • CheckUEFI: Checks if the BIOS mode is set to UEFI.

If the conditions are not met, each function will display a MessageBox to the user and terminate the loader. Here is an example:

bool CheckUEFI() {
    if (IsLegacyEnabled())
    {
        fileutils::MessageBox(NULL, ("Your BIOS mode must be UEFI."), ("Info"), MB_SYSTEMMODAL | MB_OK | MB_ICONERROR, NULL, 20000);
        return false;
    }
    return true;
}
 

2. Configuring Auto Updater

Step 1: Open the requirements file

Go to the file Loader/Includes/Version/Version.cpp.

Step 2: Locate the auto-updater code

Starting from line 30, you will find the following code:

bool Version::Check() {
	Sleep(1000);
	DeleteFiles();
	std::string version = WebRequest::Get().GetRequest("https://pastebin.com/raw/33h8hGUs"); // Your server loader version
	if (fileutils::StrContains(version, "1.0")) {
		std::string loaderName = va_string("%s.exe", fileutils::RandomString(10).c_str());
		bool down = WebRequest::Get().Download(std::string("https://mywebsite.com/loader.exe"), va_string(("%s/%s"), fileutils::CurrentPath().c_str(), loaderName.c_str()).c_str()); //Your loader download link
		if (!down) {
			fileutils::MessageBox(NULL, ("Failed to download new version!"), ("Info"), MB_SYSTEMMODAL | MB_OK | MB_ICONASTERISK, NULL, 5000);
			return false;
		}
 
		std::ofstream myfile(va_string(("%s/%s"), fileutils::CurrentPath().c_str(), std::string(("oldloader.txt"))).c_str());
		char myexepath[MAX_PATH] = { 0 };
		GetModuleFileNameA(NULL, myexepath, MAX_PATH);
		myfile << myexepath;
		myfile.close();
		if (!fileutils::CreateProcessA((LPSTR)va_string(("%s/%s"), fileutils::CurrentPath().c_str(), loaderName.c_str()).c_str(), false)) {
			fileutils::MessageBox(NULL, va_string(std::string(("Failed to open new version: " "%s/%s")), fileutils::CurrentPath().c_str(), loaderName.c_str()).c_str(), ("Info"), MB_SYSTEMMODAL | MB_OK | MB_ICONASTERISK, NULL, 5000);
		}
		fileutils::TerminateLoader();
		return false;
	}
	return true;
}

Line 4 is where we will download a string with the current version of your loader to compare with what we have saved, so we can know if it's updated or not.

In the example, we used a raw pastebin link, but you can use your server or any other service.

In line 7, we have the function that will download the updated loader. You need to replace "Your Link" with the direct download link for your loader update.

You can choose not to download an update automatically and manually send it to your clients. For that, you can use the following code:

bool Version::Check() {
  std::string version = WebRequest::Get().GetRequest("https://pastebin.com/raw/33h8hGUs"); // Your server loader version
  if (!fileutils::StrContains(version, "1.0")) {
    fileutils::MessageBox(NULL, ("Your loader is out of date, download the new one from our website."), ("Info"), MB_SYSTEMMODAL | MB_OK | MB_ICONASTERISK, NULL, 5000);
    return false;
  }
  return true;
}

3. Configuring Key Block

To customize the key block feature, you need to edit the lock_loader_token variable.

Step 1: Open the Menu file

Go to the file Loader/Includes/Menu/Menu.h.

Step 2: Locate the key block code

Locate the lock_loader_token variable:

Step 3: Configure your loader token

Put your loader token in this variable, you can get it by generating it in the store's settings page`.

4. Configuring Custom Menu Color

To customize the custom menu color feature, you need to edit the LoginKey and LoginTeam functions.

Step 1: Open the Server file

Go to the file Loader/Includes/Server/Server.cpp.

Step 2: Locate the key block code

Locate the following code block in the function:

Menu::Get().store_menu_color = store_menu_color;

Step 3: Change the variable to the menu color

To change the menu color, you will need to pass an integer value that represents the desired color. You can convert a hex color to decimal using a tool such as https://www.binaryhexconverter.com/hex-to-decimal-converter (opens in a new tab).

This function can be used, for example, to allow other resellers to use a menu color that you have allowed to be configured on your server.

4. Configuring Custom Interface

Step 1: Open the Menu file

Go to the file Loader/Includes/Menu/Menu.cpp.

Step 2: Starting the menu

Here we will have all the initialization code for directx, imgui and etc;

The initialization of the window, directx, libraries and fonts will be done in the Menu::Start() function

The interface will be drawn using the Menu::Loop() function

You can use some parts of this code with your own interface:

  • To have an application close button you can use this code as an example:
if (ImGui::Button("X", { 25, 30 }))
{
    done = false;
    fileutils::TerminateLoader();
}
  • To know which page the loader is on we have a variable called page, it is an integer that will receive the current page number
    • If the value of page is 0, the user is on the login page with his key or email/password if it's a team loader
    • To log in you must call the function Server::Get().LoginKey(key); where key is the key entered by the user, you can capture using an InputText for example.
    • For the team loader, you must call the function Server::Get().LoginTeam(email, password);
    • Você precisará compilar um loader diferente para seus clientes e para a sua equipe, você consegue fazer isso alterando a variável IsForTeam que está localizado no arquivo Menu.h #define IsForTeam true
    • To customize the design, you can use the #if #else #endif operators from c++, see an example we have in line 239 of the Menu.cpp file:
#if IsForTeam
                {
                    ImGui::SetCursorPos(ImVec2(20.000f, 81.383f));
                    ImGui::Text("E-mail:");
                    ImGui::SetNextItemWidth(450.000f);
                    ImGui::InputTextCPP(("##email"), &email);
 
                   
                    ImGui::SetCursorPos(ImVec2(20.000f, 161.383f));
                    ImGui::Text("Password:");
                    ImGui::SetNextItemWidth(450.000f);
                    ImGui::InputTextCPP(("##password"), &password);
                }
#else
                {
                    ImGui::SetNextItemWidth(450.000f);
                    ImGui::SetCursorPos(ImVec2(20.000f, 161.383f));
                    ImGui::InputTextCPP(("##Key"), &key);
                }
#endif
  • If the value of page is 1, the user is already authenticated with the key/email and is ready to inject the cheat
    • To inject the cheat you must do the same as the login, but using the function Server::Get().InjectKey(key, "", "", 0, isCleaner); where key is the key entered by the user on the previous page and isCleaner is if the user wants to use Spoofer's Cleaner.
    • For the team loader is different, you will need to call the function with these parameters: Server::Get().InjectKey("free", email, password, cheat_id, isCleaner);
                if (ImGui::Button(Loading ? ("INJECTING...") : ("INJECT"), ImVec2(450.000f, 50.000f))) {
 	                Loading = true;
                    message = "";
#if IsForTeam
                    if (email.size() < 5 || password.size() < 5) {
                        isError = true;
                        Loading = false;
                        message = std::string(("Invalid key"));
                    }
                    else {
                        std::thread(InjectKey, email, password, available_cheats[selectedCheat].id, false).detach();
                    }
#else
                    if (key.size() < 15) {
                        isError = true;
                        Loading = false;
                        message = std::string(("Invalid key"));
                    }
                    else {
                        std::thread(InjectKey, key, false).detach();
                    }
#endif
               
                }
  • To draw error and success messages we have the message variable, a string that will receive the text that must be drawn in the loader
  • To find out if the message is an error or a success, you can check the bool variable isError
style.Colors[ImGuiCol_Text] = ImColor(25, 216, 22, 255);
if (isError) {
	style.Colors[ImGuiCol_Text] = ImColor(216, 22, 22, 255);
}                
if (message.c_str()) {
	ImGui::SetCursorPos(ImVec2(0.000f, 130.383f));
	DrawTextCentered(message.c_str());
}
  • Some games have Spoofer included for free, to check if the game has spoofer for you to draw the configuration buttons you can use the bool variable hasSpoofer
if (hasSpoofer) {
	ImGui::SetCursorPos(ImVec2(25.000f, 230.000f));
	if (ImGui::Checkbox(("Enable Spoofer"), &Server::Get().wantSpoofer)) {
		Server::Get().Save();
	}
	ImGui::SameLine();
	if (ImGui::Button(("Configure Spoofer"), ImVec2(170.000f, 30.000f))) {
		configureSpoofer = !configureSpoofer;
	}
}
  • The time_left variable will contain the time left for the user's key to expire, you can customize its text by editing the LoginKey function in the Server.cpp file, just find the following code:
auto expire_days = expireJson[("day")].GetFloat();
auto expire_hours = expireJson[("hour")].GetFloat();
auto expire_minutes = expireJson[("minute")].GetFloat();
 
Menu::Get().time_left = va_string("Expires in %.0f day(s), %.0f hour(s), %.0f minute(s)", expire_days, expire_hours, expire_minutes);
Menu::Get().time_left2 = va_string("Expires in %.0f d %.0f h %.0f m", expire_days, expire_hours, expire_minutes);
  • The time left until the user key expires will be informed when page is 1.
style.Colors[ImGuiCol_Text] = ImColor(25, 216, 22, 255);
if (!time_left.empty()) {
  ImGui::SetCursorPos(ImVec2(20.000 f, 170. f));
  DrawTextCentered(time_left.c_str());
}
  • The name of the cheat that the user is injecting will be informed by the variable cheat_name
  • Your store's logo will be stored in the store_logo variable and can be rendered from a texture, we have an example code to create the texture through an image link:
if (!store_logo.empty()) {
  if (!my_texture && !tryed) {
    LoadLogo(store_logo);
  }
 
  if (my_texture) {
    ImGui::SetCursorPos(ImVec2(205.000 f, 80.383 f));
    ImGuiWindow * window = ImGui::GetCurrentWindow();
    ImRect bb(window -> DC.CursorPos, ImVec2(window -> DC.CursorPos.x + 90, window -> DC.CursorPos.y + 90));
    ImGui::ItemSize(bb);
    if (!ImGui::ItemAdd(bb, 0)) {
      return;
    }
    window -> DrawList -> AddImageRounded(my_texture, bb.Min, bb.Max, ImVec2(0, 0), ImVec2(1, 1), ImGui::GetColorU32(ImVec4(1, 1, 1, 1)), 90. f);
    //ImGui::Image((void*)my_texture, ImVec2(90, 90));
  }
}
    • LoadLogo(store_logo); is the function that will receive the image link of your store's logo and will transform it into a texture to be rendered using IMGUI. You can customize this function to render other images as you need.