Hi everyone,
So recently I was working on my own Anti-Cheat system for GTA
, and I noticed that both GTA and Rappelz make strong use of Lua scripting.
That inspired me to try applying some of the same concepts in Rappelz, to see if I could achieve similar results.
In GTA there are already methods to hook Anti-Cheat with Discord (for example: sending alerts/logs directly to a channel).
So I decided to build something similar for Rappelz private servers.
🔹 What I have so far:
- Connected Rappelz server events (Chat, Logs, Cheat alerts, etc.) with Discord via Webhook.
- Right now, it’s one-way integration (Server → Discord).
- My plan is to extend it later into a two-way bridge (Discord ↔ Server).
🔹 Why this could be useful:
- Easy monitoring of chat & logs directly in Discord.
-
Instant notifications for suspicious activity or cheat attempts.
- Makes server management more convenient without staying in-game 24/7.
I’m still testing, but it looks promising.
I wanted to share the idea here and get feedback from the community.
🔹 Showcase:
So recently I was working on my own Anti-Cheat system for GTA
That inspired me to try applying some of the same concepts in Rappelz, to see if I could achieve similar results.
In GTA there are already methods to hook Anti-Cheat with Discord (for example: sending alerts/logs directly to a channel).
So I decided to build something similar for Rappelz private servers.
🔹 What I have so far:
- Connected Rappelz server events (Chat, Logs, Cheat alerts, etc.) with Discord via Webhook.
- Right now, it’s one-way integration (Server → Discord).
- My plan is to extend it later into a two-way bridge (Discord ↔ Server).
🔹 Why this could be useful:
- Easy monitoring of chat & logs directly in Discord.
-
- Makes server management more convenient without staying in-game 24/7.
I’m still testing, but it looks promising.
I wanted to share the idea here and get feedback from the community.
🔹 Showcase:
PHP Code:
#include <windows.h>
#include <winhttp.h>
#include <string>
#include <vector>
#include <memory>
#pragma comment(lib, "winhttp.lib")
static bool ConvertToUtf8(const std::string& src, UINT codePage, std::string& out)
{
if (src.empty()) { out.clear(); return true; }
// جرّب التحويل إلى UTF-16
int wlen = MultiByteToWideChar(codePage, MB_ERR_INVALID_CHARS, src.data(), (int)src.size(), nullptr, 0);
if (wlen <= 0) return false;
std::wstring wstr(wlen, L'\0');
if (MultiByteToWideChar(codePage, MB_ERR_INVALID_CHARS, src.data(), (int)src.size(), &wstr[0], wlen) <= 0)
return false;
// ثم UTF-16 إلى UTF-8
int u8len = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wlen, nullptr, 0, nullptr, nullptr);
if (u8len <= 0) return false;
out.assign(u8len, '\0');
if (WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), wlen, &out[0], u8len, nullptr, nullptr) <= 0)
return false;
return true;
}
// دالة تحويل ANSI إلى UTF-8
static std::string ToUTF8(const std::string& s) {
// الأولوية: UTF-8 -> 1256 -> ACP
std::string out;
if (ConvertToUtf8(s, CP_UTF8, out)) return out;
#ifndef CP_ARABIC
#define CP_ARABIC 1256
#endif
if (ConvertToUtf8(s, CP_ARABIC, out)) return out;
if (ConvertToUtf8(s, CP_ACP, out)) return out;
// فشل كل شيء: أعد النص كما هو
return s;
}
std::wstring ToWide(const std::string& narrow) {
int wideSize = MultiByteToWideChar(CP_UTF8, 0, narrow.c_str(), -1, nullptr, 0);
if (wideSize == 0) return L"";
std::wstring wideStr(wideSize, 0);
MultiByteToWideChar(CP_UTF8, 0, narrow.c_str(), -1, &wideStr[0], wideSize);
return wideStr;
}
#include <string>
#include <stdio.h>
static std::string JsonEscape(const std::string& s) {
std::string out;
out.reserve(s.size() + 16); // موجود من C++98 فما فوق، لكن يمكننا الإبقاء عليها لأنها مجرد optimization
for (std::string::size_type i = 0; i < s.size(); ++i) {
unsigned char c = (unsigned char)s[i];
switch (c) {
case '\"': out += "\\\""; break;
case '\\': out += "\\\\"; break;
case '\b': out += "\\b"; break;
case '\f': out += "\\f"; break;
case '\n': out += "\\n"; break;
case '\r': out += "\\r"; break;
case '\t': out += "\\t"; break;
default:
if (c < 0x20) {
char buf[7];
sprintf(buf, "\\u%04X", c); // بدل sprintf_s
out += buf;
}
else {
out += (char)c;
}
}
}
return out;
}
// هيكل لنقل البيانات إلى الـ thread
struct DiscordData {
std::string sender;
std::string text;
std::string webhookUrl; // إضافة حقل لرابط الويب هوك
DiscordData(const char* szSender, const char* szText, const char* szWebhookUrl)
: sender(szSender ? szSender : ""), text(szText ? szText : ""), webhookUrl(szWebhookUrl ? szWebhookUrl : "") {
}
};
DWORD WINAPI DiscordThreadFunction(LPVOID lpParam) {
std::unique_ptr<DiscordData> data(static_cast<DiscordData*>(lpParam));
// إذا لم يكن هناك رابط ويب هوك، لا ترسل أي شيء
if (data->webhookUrl.empty()) return 1;
HINTERNET hSession = WinHttpOpen(L"DiscordWebhook/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);
if (!hSession) return 1;
HINTERNET hConnect = WinHttpConnect(hSession, L"discord.com",
INTERNET_DEFAULT_HTTPS_PORT, 0);
if (!hConnect) {
WinHttpCloseHandle(hSession);
return 1;
}
// استخراج المسار من رابط الويب هوك
std::wstring webhookUrlW = ToWide(data->webhookUrl);
std::wstring path = L"/api/webhooks" + webhookUrlW.substr(webhookUrlW.find(L"/api/webhooks") + 13);
HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"POST",
path.c_str(),
NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
WINHTTP_FLAG_SECURE);
if (!hRequest) {
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return 1;
}
// تحويل النصوص إلى UTF-8 بشكل موثوق
std::string utf8Sender = ToUTF8(data->sender);
std::string utf8Text = ToUTF8(data->text);
// إنشاء المحتوى ثم تهريبه لJSON
std::string content;
if (!utf8Sender.empty()) {
content += utf8Sender;
content += ": ";
}
content += utf8Text;
std::string jsonPayload = "{\"content\":\"";
jsonPayload += JsonEscape(content);
jsonPayload += "\"}";
// تعيين headers
LPCWSTR headers = L"Content-Type: application/json; charset=utf-8";
// إرسال الطلب
BOOL bResults = WinHttpSendRequest(hRequest, headers, -1,
(LPVOID)jsonPayload.data(),
(DWORD)jsonPayload.size(),
(DWORD)jsonPayload.size(), 0);
if (bResults) {
WinHttpReceiveResponse(hRequest, NULL);
}
WinHttpCloseHandle(hRequest);
WinHttpCloseHandle(hConnect);
WinHttpCloseHandle(hSession);
return 0;
}
void SendToDiscordWebhook(const char* szSender, const char* szText, const char* szWebhookUrl) {
// إنشاء نسخة من البيانات لإرسالها إلى الـ thread
DiscordData* data = new DiscordData(szSender, szText, szWebhookUrl);
// إنشاء thread منفصل
CreateThread(NULL, 0, DiscordThreadFunction, data, 0, NULL);
}






