/*
* PtokaX - hub server for Direct Connect peer to peer network.
* Copyright (C) 2004-2022 Petr Kozelka, PPK at PtokaX dot org
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3
* as published by the Free Software Foundation.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
#include "stdinc.h"
//---------------------------------------------------------------------------
#include "LuaInc.h"
//---------------------------------------------------------------------------
#include "colUsers.h"
#include "eventqueue.h"
#include "GlobalDataQueue.h"
#include "hashUsrManager.h"
#include "LanguageManager.h"
#include "LuaScriptManager.h"
#include "ProfileManager.h"
#include "ServerManager.h"
#include "SettingManager.h"
#include "UdpDebug.h"
#include "User.h"
#include "utility.h"
//---------------------------------------------------------------------------
#ifdef _WIN32
#pragma hdrstop
#endif
//---------------------------------------------------------------------------
#include "LuaScript.h"
//---------------------------------------------------------------------------
#include "IP2Country.h"
#include "LuaCoreLib.h"
#include "LuaBanManLib.h"
#include "LuaIP2CountryLib.h"
#include "LuaProfManLib.h"
#include "LuaRegManLib.h"
#include "LuaScriptManLib.h"
#include "LuaSetManLib.h"
#include "LuaTmrManLib.h"
#include "LuaUDPDbgLib.h"
#include "ResNickManager.h"
//---------------------------------------------------------------------------
#ifdef _BUILD_GUI
#include "../gui.win/GuiUtil.h"
#include "../gui.win/MainWindowPageScripts.h"
#endif
//---------------------------------------------------------------------------
char ScriptTimer::m_sDefaultTimerFunc[] = "OnTimer";
//---------------------------------------------------------------------------
static int ScriptPanic(lua_State * pLua)
{
GlobalDataQueue::m_Ptr->PrometheusLuaInc(__func__);
size_t szLen = 0;
const char * stmp = (char*)lua_tolstring(pLua, -1, &szLen);
const string sMsg = "[LUA] At panic -> " + string(stmp, szLen);
AppendLog(sMsg);
return 0;
}
//------------------------------------------------------------------------------
ScriptBot::ScriptBot() : m_pPrev(NULL), m_pNext(NULL), m_sNick(NULL), m_sMyINFO(NULL), m_bIsOP(false)
{
ScriptManager::m_Ptr->m_ui8BotsCount++;
}
//------------------------------------------------------------------------------
ScriptBot::~ScriptBot()
{
free(m_sNick);
free(m_sMyINFO);
ScriptManager::m_Ptr->m_ui8BotsCount--;
}
//------------------------------------------------------------------------------
ScriptBot * ScriptBot::CreateScriptBot(const char * sBotNick, const size_t szNickLen, const char * sDescription, const size_t szDscrLen, const char * sEmail, const size_t szEmailLen, const bool bOP)
{
ScriptBot * pScriptBot = new (std::nothrow) ScriptBot();
if (pScriptBot == NULL)
{
AppendDebugLog("%s - [MEM] Cannot allocate new pScriptBot in ScriptBot::CreateScriptBot\n");
return NULL;
}
pScriptBot->m_sNick = (char *)malloc(szNickLen + 1);
if (pScriptBot->m_sNick == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes for pScriptBot->m_sNick in ScriptBot::CreateScriptBot\n", szNickLen+1);
delete pScriptBot;
return NULL;
}
memcpy(pScriptBot->m_sNick, sBotNick, szNickLen);
pScriptBot->m_sNick[szNickLen] = '\0';
pScriptBot->m_bIsOP = bOP;
size_t szWantLen = 24+szNickLen+szDscrLen+szEmailLen;
pScriptBot->m_sMyINFO = (char *)malloc(szWantLen);
if (pScriptBot->m_sMyINFO == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes for pScriptBot->m_sMyINFO in ScriptBot::CreateScriptBot\n", szWantLen);
delete pScriptBot;
return NULL;
}
if (snprintf(pScriptBot->m_sMyINFO, szWantLen, "$MyINFO $ALL %s %s$ $$%s$$|", sBotNick, sDescription != NULL ? sDescription : "", sEmail != NULL ? sEmail : "") <= 0)
{
pScriptBot->m_sMyINFO[0] = '\0';
}
return pScriptBot;
}
//------------------------------------------------------------------------------
// alex82 ... RegBot / �������� �������������� ������� ��� �������� ���� � ����������� $MyINFO
ScriptBot * ScriptBot::CreateScriptBot(const char * sBotNick, const size_t szNickLen, const char * sBotMyINFO, const size_t szMyINFOLen, const bool bOP)
{
ScriptBot * pScriptBot = new (std::nothrow) ScriptBot();
if (pScriptBot == NULL)
{
AppendDebugLog("%s - [MEM] Cannot allocate new pScriptBot in ScriptBot::CreateScriptBot\n");
return NULL;
}
pScriptBot->m_sNick = (char *)malloc(szNickLen + 1);
if (pScriptBot->m_sNick == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes for m_sNick in ScriptBot::CreateScriptBot\n", szNickLen + 1);
delete pScriptBot;
return NULL;
}
memcpy(pScriptBot->m_sNick, sBotNick, szNickLen);
pScriptBot->m_sNick[szNickLen] = '\0';
pScriptBot->m_bIsOP = bOP;
bool bAddPipe = false;
if (sBotMyINFO[szMyINFOLen - 1] != '|') bAddPipe = true;
size_t szWantLen = szMyINFOLen + 1;
if (bAddPipe == true) szWantLen++;
pScriptBot->m_sMyINFO = (char *)malloc(szWantLen);
if (pScriptBot->m_sMyINFO == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes for m_sMyINFO in ScriptBot::CreateScriptBot\n", szWantLen);
delete pScriptBot;
return NULL;
}
memcpy(pScriptBot->m_sMyINFO, sBotMyINFO, szMyINFOLen);
if (bAddPipe == true) pScriptBot->m_sMyINFO[szMyINFOLen] = '|';
pScriptBot->m_sMyINFO[0] = '\0';
return pScriptBot;
}
//------------------------------------------------------------------------------
ScriptTimer::ScriptTimer() :
#if defined(_WIN32) && !defined(_WIN_IOT)
m_uiTimerId(NULL),
#else
m_ui64Interval(0), m_ui64LastTick(0),
#endif
m_pPrev(NULL), m_pNext(NULL), m_pLua(NULL), m_sFunctionName(NULL), m_iFunctionRef(0)
{
// ...
}
//------------------------------------------------------------------------------
ScriptTimer::~ScriptTimer()
{
if (m_sFunctionName != m_sDefaultTimerFunc)
{
free(m_sFunctionName);
}
}
//------------------------------------------------------------------------------
#if defined(_WIN32) && !defined(_WIN_IOT)
ScriptTimer * ScriptTimer::CreateScriptTimer(UINT_PTR uiTmrId, const char * sFunctName, const size_t szLen, const int iRef, lua_State * pLuaState)
{
#else
ScriptTimer * ScriptTimer::CreateScriptTimer(const char * sFunctName, const size_t szLen, const int iRef, lua_State * pLuaState)
{
#endif
ScriptTimer * pScriptTimer = new (std::nothrow) ScriptTimer();
if (pScriptTimer == NULL)
{
AppendDebugLog("%s - [MEM] Cannot allocate new pScriptTimer in ScriptTimer::CreateScriptTimer\n");
return NULL;
}
pScriptTimer->m_pLua = pLuaState;
if (sFunctName != NULL)
{
if (sFunctName != m_sDefaultTimerFunc)
{
pScriptTimer->m_sFunctionName = (char *)malloc(szLen + 1);
if (pScriptTimer->m_sFunctionName == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes for pScriptTimer->m_sFunctionName in ScriptTimer::CreateScriptTimer\n", szLen+1);
delete pScriptTimer;
return NULL;
}
memcpy(pScriptTimer->m_sFunctionName, sFunctName, szLen);
pScriptTimer->m_sFunctionName[szLen] = '\0';
}
else
{
pScriptTimer->m_sFunctionName = m_sDefaultTimerFunc;
}
}
else
{
pScriptTimer->m_iFunctionRef = iRef;
}
#if defined(_WIN32) && !defined(_WIN_IOT)
pScriptTimer->m_uiTimerId = uiTmrId;
#endif
return pScriptTimer;
}
//------------------------------------------------------------------------------
Script::Script() : m_pPrev(NULL), m_pNext(NULL), m_pBotList(NULL), m_pLua(NULL), m_sName(NULL), m_ui32DataArrivals(4294967295U), m_ui16Functions(65535),
m_bEnabled(false), m_bRegUDP(false), m_bProcessed(false)
{
// ...
}
//------------------------------------------------------------------------------
Script::~Script()
{
if (m_bRegUDP == true)
{
UdpDebug::m_Ptr->Remove(m_sName);
m_bRegUDP = false;
}
if (m_pLua != NULL)
{
lua_close(m_pLua);
}
free(m_sName);
}
//------------------------------------------------------------------------------
Script * Script::CreateScript(const char * sName, const bool enabled)
{
Script * pScript = new (std::nothrow) Script();
if (pScript == NULL)
{
AppendDebugLog("%s - [MEM] Cannot allocate new pScript in Script::CreateScript\n");
return NULL;
}
#ifdef _WIN32
string ExtractedFilename(ExtractFileName(sName));
size_t szNameLen = ExtractedFilename.size();
#else
size_t szNameLen = strlen(sName);
#endif
pScript->m_sName = (char *)malloc(szNameLen + 1);
if (pScript->m_sName == NULL)
{
AppendDebugLogFormat("[MEM] Cannot allocate %zu bytes in Script::CreateScript\n", szNameLen+1);
delete pScript;
return NULL;
}
#ifdef _WIN32
memcpy(pScript->m_sName, ExtractedFilename.c_str(), ExtractedFilename.size());
#else
memcpy(pScript->m_sName, sName, szNameLen);
#endif
pScript->m_sName[szNameLen] = '\0';
pScript->m_bEnabled = enabled;
return pScript;
}
//------------------------------------------------------------------------------
static int OsExit(lua_State * /* pLua*/)
{
GlobalDataQueue::m_Ptr->PrometheusLuaInc(__func__);
EventQueue::m_Ptr->AddNormal(EventQueue::EVENT_SHUTDOWN, NULL);
return 0;
}
//------------------------------------------------------------------------------
static void AddSettingIds(lua_State * pLua)
{
int iTable = lua_gettop(pLua);
lua_newtable(pLua);
int iNewTable = lua_gettop(pLua);
const uint8_t ui8Bools[] = { SETBOOL_ANTI_MOGLO, SETBOOL_AUTO_START, SETBOOL_REDIRECT_ALL, SETBOOL_REDIRECT_WHEN_HUB_FULL, SETBOOL_AUTO_REG, SETBOOL_REG_ONLY,
SETBOOL_REG_ONLY_REDIR, SETBOOL_SHARE_LIMIT_REDIR, SETBOOL_SLOTS_LIMIT_REDIR, SETBOOL_HUB_SLOT_RATIO_REDIR, SETBOOL_MAX_HUBS_LIMIT_REDIR,
SETBOOL_MODE_TO_MYINFO, SETBOOL_MODE_TO_DESCRIPTION, SETBOOL_STRIP_DESCRIPTION, SETBOOL_STRIP_TAG, SETBOOL_STRIP_CONNECTION,
SETBOOL_STRIP_EMAIL, SETBOOL_REG_BOT, SETBOOL_USE_BOT_NICK_AS_HUB_SEC, SETBOOL_REG_OP_CHAT, SETBOOL_TEMP_BAN_REDIR, SETBOOL_PERM_BAN_REDIR,
SETBOOL_ENABLE_SCRIPTING, SETBOOL_KEEP_SLOW_USERS, SETBOOL_CHECK_NEW_RELEASES, SETBOOL_ENABLE_TRAY_ICON, SETBOOL_START_MINIMIZED,
SETBOOL_FILTER_KICK_MESSAGES, SETBOOL_SEND_KICK_MESSAGES_TO_OPS, SETBOOL_SEND_STATUS_MESSAGES, SETBOOL_SEND_STATUS_MESSAGES_AS_PM,
SETBOOL_ENABLE_TEXT_FILES, SETBOOL_SEND_TEXT_FILES_AS_PM, SETBOOL_STOP_SCRIPT_ON_ERROR, SETBOOL_MOTD_AS_PM, SETBOOL_DEFLOOD_REPORT,
SETBOOL_REPLY_TO_HUB_COMMANDS_AS_PM, SETBOOL_DISABLE_MOTD, SETBOOL_DONT_ALLOW_PINGERS, SETBOOL_REPORT_PINGERS, SETBOOL_REPORT_3X_BAD_PASS,
SETBOOL_ADVANCED_PASS_PROTECTION, SETBOOL_BIND_ONLY_SINGLE_IP, SETBOOL_RESOLVE_TO_IP, SETBOOL_NICK_LIMIT_REDIR, SETBOOL_BAN_MSG_SHOW_IP,
SETBOOL_BAN_MSG_SHOW_RANGE, SETBOOL_BAN_MSG_SHOW_NICK, SETBOOL_BAN_MSG_SHOW_REASON, SETBOOL_BAN_MSG_SHOW_BY, SETBOOL_REPORT_SUSPICIOUS_TAG,
SETBOOL_LOG_SCRIPT_ERRORS, SETBOOL_NO_QUACK_SUPPORTS, SETBOOL_HASH_PASSWORDS,
#if defined(_WITH_SQLITE) || defined(_WITH_POSTGRES) || defined(_WITH_MYSQL)
SETBOOL_ENABLE_DATABASE,
#endif
};
const char * pBoolsNames[] = { "AntiMoGlo", "AutoStart", "RedirectAll", "RedirectWhenHubFull", "AutoReg", "RegOnly",
"RegOnlyRedir", "ShareLimitRedir", "SlotLimitRedir", "HubSlotRatioRedir", "MaxHubsLimitRedir",
"ModeToMyInfo", "ModeToDescription", "StripDescription", "StripTag", "StripConnection",
"StripEmail", "RegBot", "UseBotAsHubSec", "RegOpChat", "TempBanRedir", "PermBanRedir",
"EnableScripting", "KeepSlowUsers", "CheckNewReleases", "EnableTrayIcon", "StartMinimized",
"FilterKickMessages", "SendKickMessagesToOps", "SendStatusMessages", "SendStatusMessagesAsPm",
"EnableTextFiles", "SendTextFilesAsPm", "StopScriptOnError", "SendMotdAsPm", "DefloodReport",
"ReplyToHubCommandsAsPm", "DisableMotd", "DontAllowPingers", "ReportPingers", "Report3xBadPass",
"AdvancedPassProtection", "ListenOnlySingleIp", "ResolveToIp", "NickLimitRedir", "BanMsgShowIp",
"BanMsgShowRange", "BanMsgShowNick", "BanMsgShowReason", "BanMsgShowBy", "ReportSuspiciousTag",
"LogScriptErrors", "DisallowBadSupports", "HashPasswords",
#if defined(_WITH_SQLITE) || defined(_WITH_POSTGRES) || defined(_WITH_MYSQL)
"EnableDatabase",
#endif
};
for (uint8_t ui8i = 0; ui8i < sizeof(ui8Bools); ui8i++)
{
lua_pushinteger(pLua, ui8Bools[ui8i]);
lua_setfield(pLua, iNewTable, pBoolsNames[ui8i]);
}
lua_setfield(pLua, iTable, "tBooleans");
lua_newtable(pLua);
iNewTable = lua_gettop(pLua);
const uint8_t ui8Numbers[] = { SETSHORT_MAX_USERS, SETSHORT_MIN_SHARE_LIMIT, SETSHORT_MIN_SHARE_UNITS, SETSHORT_MAX_SHARE_LIMIT, SETSHORT_MAX_SHARE_UNITS,
SETSHORT_MIN_SLOTS_LIMIT, SETSHORT_MAX_SLOTS_LIMIT, SETSHORT_HUB_SLOT_RATIO_HUBS, SETSHORT_HUB_SLOT_RATIO_SLOTS, SETSHORT_MAX_HUBS_LIMIT,
SETSHORT_NO_TAG_OPTION, SETSHORT_FULL_MYINFO_OPTION, SETSHORT_MAX_CHAT_LEN, SETSHORT_MAX_CHAT_LINES, SETSHORT_MAX_PM_LEN,
SETSHORT_MAX_PM_LINES, SETSHORT_DEFAULT_TEMP_BAN_TIME, SETSHORT_MAX_PASIVE_SR, SETSHORT_MYINFO_DELAY, SETSHORT_MAIN_CHAT_MESSAGES,
SETSHORT_MAIN_CHAT_TIME, SETSHORT_MAIN_CHAT_ACTION, SETSHORT_SAME_MAIN_CHAT_MESSAGES, SETSHORT_SAME_MAIN_CHAT_TIME, SETSHORT_SAME_MAIN_CHAT_ACTION,
SETSHORT_SAME_MULTI_MAIN_CHAT_MESSAGES, SETSHORT_SAME_MULTI_MAIN_CHAT_LINES, SETSHORT_SAME_MULTI_MAIN_CHAT_ACTION, SETSHORT_PM_MESSAGES, SETSHORT_PM_TIME,
SETSHORT_PM_ACTION, SETSHORT_SAME_PM_MESSAGES, SETSHORT_SAME_PM_TIME, SETSHORT_SAME_PM_ACTION, SETSHORT_SAME_MULTI_PM_MESSAGES,
SETSHORT_SAME_MULTI_PM_LINES, SETSHORT_SAME_MULTI_PM_ACTION, SETSHORT_SEARCH_MESSAGES, SETSHORT_SEARCH_TIME, SETSHORT_SEARCH_ACTION,
SETSHORT_SAME_SEARCH_MESSAGES, SETSHORT_SAME_SEARCH_TIME, SETSHORT_SAME_SEARCH_ACTION, SETSHORT_MYINFO_MESSAGES, SETSHORT_MYINFO_TIME,
SETSHORT_MYINFO_ACTION, SETSHORT_GETNICKLIST_MESSAGES, SETSHORT_GETNICKLIST_TIME, SETSHORT_GETNICKLIST_ACTION, SETSHORT_NEW_CONNECTIONS_COUNT,
SETSHORT_NEW_CONNECTIONS_TIME, SETSHORT_DEFLOOD_WARNING_COUNT, SETSHORT_DEFLOOD_WARNING_ACTION, SETSHORT_DEFLOOD_TEMP_BAN_TIME, SETSHORT_GLOBAL_MAIN_CHAT_MESSAGES,
SETSHORT_GLOBAL_MAIN_CHAT_TIME, SETSHORT_GLOBAL_MAIN_CHAT_TIMEOUT, SETSHORT_GLOBAL_MAIN_CHAT_ACTION, SETSHORT_MIN_SEARCH_LEN, SETSHORT_MAX_SEARCH_LEN,
SETSHORT_MIN_NICK_LEN, SETSHORT_MAX_NICK_LEN, SETSHORT_BRUTE_FORCE_PASS_PROTECT_BAN_TYPE, SETSHORT_BRUTE_FORCE_PASS_PROTECT_TEMP_BAN_TIME, SETSHORT_MAX_PM_COUNT_TO_USER,
SETSHORT_MAX_SIMULTANEOUS_LOGINS, SETSHORT_MAIN_CHAT_MESSAGES2, SETSHORT_MAIN_CHAT_TIME2, SETSHORT_MAIN_CHAT_ACTION2, SETSHORT_PM_MESSAGES2,
SETSHORT_PM_TIME2, SETSHORT_PM_ACTION2, SETSHORT_SEARCH_MESSAGES2, SETSHORT_SEARCH_TIME2, SETSHORT_SEARCH_ACTION2,
SETSHORT_MYINFO_MESSAGES2, SETSHORT_MYINFO_TIME2, SETSHORT_MYINFO_ACTION2, SETSHORT_MAX_MYINFO_LEN, SETSHORT_CTM_MESSAGES,
SETSHORT_CTM_TIME, SETSHORT_CTM_ACTION, SETSHORT_CTM_MESSAGES2, SETSHORT_CTM_TIME2, SETSHORT_CTM_ACTION2,
SETSHORT_RCTM_MESSAGES, SETSHORT_RCTM_TIME, SETSHORT_RCTM_ACTION, SETSHORT_RCTM_MESSAGES2, SETSHORT_RCTM_TIME2,
SETSHORT_RCTM_ACTION2, SETSHORT_MAX_CTM_LEN, SETSHORT_MAX_RCTM_LEN, SETSHORT_SR_MESSAGES, SETSHORT_SR_TIME,
SETSHORT_SR_ACTION, SETSHORT_SR_MESSAGES2, SETSHORT_SR_TIME2, SETSHORT_SR_ACTION2, SETSHORT_MAX_SR_LEN,
SETSHORT_MAX_DOWN_ACTION, SETSHORT_MAX_DOWN_KB, SETSHORT_MAX_DOWN_TIME, SETSHORT_MAX_DOWN_ACTION2, SETSHORT_MAX_DOWN_KB2,
SETSHORT_MAX_DOWN_TIME2, SETSHORT_CHAT_INTERVAL_MESSAGES, SETSHORT_CHAT_INTERVAL_TIME, SETSHORT_PM_INTERVAL_MESSAGES, SETSHORT_PM_INTERVAL_TIME,
SETSHORT_SEARCH_INTERVAL_MESSAGES, SETSHORT_SEARCH_INTERVAL_TIME, SETSHORT_MAX_CONN_SAME_IP, SETSHORT_MIN_RECONN_TIME,
#if defined(_WITH_SQLITE) || defined(_WITH_POSTGRES) || defined(_WITH_MYSQL)
SETSHORT_DB_REMOVE_OLD_RECORDS,
#endif
};
const char * pNumbersNames[] = { "MaxUsers", "MinShareLimit", "MinShareUnits", "MaxShareLimit", "MaxShareUnits",
"MinSlotsLimit", "MaxSlotsLimit", "HubSlotRatioHubs", "HubSlotRatioSlots", "MaxHubsLimit",
"NoTagOption", "LongMyinfoOption", "MaxChatLen", "MaxChatLines", "MaxPmLen",
"MaxPmLines", "DefaultTempBanTime", "MaxPasiveSr", "MyInfoDelay", "MainChatMessages",
"MainChatTime", "MainChatAction", "SameMainChatMessages", "SameMainChatTime", "SameMainChatAction",
"SameMultiMainChatMessages", "SameMultiMainChatLines", "SameMultiMainChatAction", "PmMessages", "PmTime",
"PmAction", "SamePmMessages", "SamePmTime", "SamePmAction", "SameMultiPmMessages",
"SameMultiPmLines", "SameMultiPmAction", "SearchMessages", "SearchTime", "SearchAction",
"SameSearchMessages", "SameSearchTime", "SameSearchAction", "MyinfoMessages", "MyinfoTime",
"MyinfoAction", "GetnicklistMessages", "GetnicklistTime", "GetnicklistAction", "NewConnectionsCount",
"NewConnectionsTime", "DefloodWarningCount", "DefloodWarningAction", "DefloodTempBanTime", "GlobalMainChatMessages",
"GlobalMainChatTime", "GlobalMainChatTimeout", "GlobalMainChatAction", "MinSearchLen", "MaxSearchLen",
"MinNickLen", "MaxNickLen", "BruteForcePassProtectBanType", "BruteForcePassProtectTempBanTime", "MaxPmCountToUser",
"MaxSimultaneousLogins", "MainChatMessages2", "MainChatTime2", "MainChatAction2", "PmMessages2",
"PmTime2", "PmAction2", "SearchMessages2", "SearchTime2", "SearchAction2",
"MyinfoMessages2", "MyinfoTime2", "MyinfoAction2", "MaxMyinfoLen", "CtmMessages",
"CtmTime", "CtmAction", "CtmMessages2", "CtmTime2", "CtmAction2",
"RctmMessages", "RctmTime", "RctmAction", "RctmMessages2", "RctmTime2",
"RctmAction2", "MaxCtmLen", "MaxRctmLen", "SrMessages", "SrTime",
"SrAction", "SrMessages2", "SrTime2", "SrAction2", "MaxSrLen",
"MaxDownAction", "MaxDownKB", "MaxDownTime", "MaxDownAction2", "MaxDownKB2",
"MaxDownTime2", "ChatIntervalMessages", "ChatIntervalTime", "PmIntervalMessages", "PmIntervalTime",
"SearchIntervalMessages", "SearchIntervalTime", "MaxConnsSameIp", "MinReconnTime",
#if defined(_WITH_SQLITE) || defined(_WITH_POSTGRES) || defined(_WITH_MYSQL)
"DbRemoveOldRecords",
#endif
};
for (uint8_t ui8i = 0; ui8i < sizeof(ui8Numbers); ui8i++)
{
lua_pushinteger(pLua, ui8Numbers[ui8i]);
lua_setfield(pLua, iNewTable, pNumbersNames[ui8i]);
}
lua_setfield(pLua, iTable, "tNumbers");
lua_newtable(pLua);
iNewTable = lua_gettop(pLua);
const uint8_t ui8Strings[] = { SETTXT_HUB_NAME, SETTXT_ADMIN_NICK, SETTXT_HUB_ADDRESS, SETTXT_TCP_PORTS, SETTXT_UDP_PORT, SETTXT_HUB_DESCRIPTION, SETTXT_REDIRECT_ADDRESS,
SETTXT_REGISTER_SERVERS, SETTXT_REG_ONLY_MSG, SETTXT_REG_ONLY_REDIR_ADDRESS, SETTXT_HUB_TOPIC, SETTXT_SHARE_LIMIT_MSG, SETTXT_SHARE_LIMIT_REDIR_ADDRESS,
SETTXT_SLOTS_LIMIT_MSG, SETTXT_SLOTS_LIMIT_REDIR_ADDRESS, SETTXT_HUB_SLOT_RATIO_MSG, SETTXT_HUB_SLOT_RATIO_REDIR_ADDRESS, SETTXT_MAX_HUBS_LIMIT_MSG,
SETTXT_MAX_HUBS_LIMIT_REDIR_ADDRESS, SETTXT_NO_TAG_MSG, SETTXT_NO_TAG_REDIR_ADDRESS, SETTXT_BOT_NICK, SETTXT_BOT_DESCRIPTION, SETTXT_BOT_EMAIL,
SETTXT_OP_CHAT_NICK, SETTXT_OP_CHAT_DESCRIPTION, SETTXT_OP_CHAT_EMAIL, SETTXT_TEMP_BAN_REDIR_ADDRESS, SETTXT_PERM_BAN_REDIR_ADDRESS,
SETTXT_CHAT_COMMANDS_PREFIXES, SETTXT_HUB_OWNER_EMAIL, SETTXT_NICK_LIMIT_MSG, SETTXT_NICK_LIMIT_REDIR_ADDRESS, SETTXT_MSG_TO_ADD_TO_BAN_MSG,
SETTXT_LANGUAGE, SETTXT_IPV4_ADDRESS, SETTXT_IPV6_ADDRESS, SETTXT_ENCODING,
#ifdef _WITH_POSTGRES
SETTXT_POSTGRES_HOST, SETTXT_POSTGRES_PORT, SETTXT_POSTGRES_DBNAME, SETTXT_POSTGRES_USER, SETTXT_POSTGRES_PASS,
#elif _WITH_MYSQL
SETTXT_MYSQL_HOST, SETTXT_MYSQL_PORT, SETTXT_MYSQL_DBNAME, SETTXT_MYSQL_USER, SETTXT_MYSQL_PASS,
#endif
};
const char * pStringsNames[] = { "HubName", "AdminNick", "HubAddress", "TCPPorts", "UDPPort", "HubDescription", "MainRedirectAddress",
"HublistRegisterAddresses", "RegOnlyMessage", "RegOnlyRedirAddress", "HubTopic", "ShareLimitMessage", "ShareLimitRedirAddress",
"SlotLimitMessage", "SlotLimitRedirAddress", "HubSlotRatioMessage", "HubSlotRatioRedirAddress", "MaxHubsLimitMessage",
"MaxHubsLimitRedirAddress", "NoTagMessage", "NoTagRedirAddress", "HubBotNick", "HubBotDescription", "HubBotEmail",
"OpChatNick", "OpChatDescription", "OpChatEmail", "TempBanRedirAddress", "PermBanRedirAddress",
"ChatCommandsPrefixes", "HubOwnerEmail", "NickLimitMessage", "NickLimitRedirAddress", "MessageToAddToBanMessage",
"Language", "IPv4Address", "IPv6Address", "Encoding",
#ifdef _WITH_POSTGRES
"PostgresHost", "PostgresPort", "PostgresDBName", "PostgresUser", "PostgresPass",
#elif _WITH_MYSQL
"MySQLHost", "MySQLPort", "MySQLDBName", "MySQLUser", "MySQLPass",
#endif
};
for (uint8_t ui8i = 0; ui8i < sizeof(ui8Strings); ui8i++)
{
lua_pushinteger(pLua, ui8Strings[ui8i]);
lua_setfield(pLua, iNewTable, pStringsNames[ui8i]);
}
lua_setfield(pLua, iTable, "tStrings");
lua_pop(pLua, 1);
}
//------------------------------------------------------------------------------
static void AddPermissionsIds(lua_State * pLua)
{
int iTable = lua_gettop(pLua);
lua_newtable(pLua);
int iNewTable = lua_gettop(pLua);
const uint8_t ui8Permissions[] = { ProfileManager::HASKEYICON, ProfileManager::NODEFLOODGETNICKLIST, ProfileManager::NODEFLOODMYINFO, ProfileManager::NODEFLOODSEARCH, ProfileManager::NODEFLOODPM,
ProfileManager::NODEFLOODMAINCHAT, ProfileManager::MASSMSG, ProfileManager::TOPIC, ProfileManager::TEMP_BAN, ProfileManager::REFRESHTXT,
ProfileManager::NOTAGCHECK, ProfileManager::TEMP_UNBAN, ProfileManager::DELREGUSER, ProfileManager::ADDREGUSER, ProfileManager::NOCHATLIMITS,
ProfileManager::NOMAXHUBCHECK, ProfileManager::NOSLOTHUBRATIO, ProfileManager::NOSLOTCHECK, ProfileManager::NOSHARELIMIT, ProfileManager::CLRPERMBAN,
ProfileManager::CLRTEMPBAN, ProfileManager::GETINFO, ProfileManager::GETBANLIST, ProfileManager::RSTSCRIPTS, ProfileManager::RSTHUB,
ProfileManager::TEMPOP, ProfileManager::GAG, ProfileManager::REDIRECT, ProfileManager::BAN, ProfileManager::KICK, ProfileManager::DROP,
ProfileManager::ENTERFULLHUB, ProfileManager::ENTERIFIPBAN, ProfileManager::ALLOWEDOPCHAT, ProfileManager::SENDALLUSERIP, ProfileManager::RANGE_BAN,
ProfileManager::RANGE_UNBAN, ProfileManager::RANGE_TBAN, ProfileManager::RANGE_TUNBAN, ProfileManager::GET_RANGE_BANS, ProfileManager::CLR_RANGE_BANS,
ProfileManager::CLR_RANGE_TBANS, ProfileManager::UNBAN, ProfileManager::NOSEARCHLIMITS, ProfileManager:: SENDFULLMYINFOS, ProfileManager::NOIPCHECK,
ProfileManager::CLOSE, ProfileManager::NODEFLOODCTM, ProfileManager::NODEFLOODRCTM, ProfileManager::NODEFLOODSR, ProfileManager::NODEFLOODRECV,
ProfileManager::NOCHATINTERVAL, ProfileManager::NOPMINTERVAL, ProfileManager::NOSEARCHINTERVAL, ProfileManager::NOUSRSAMEIP, ProfileManager::NORECONNTIME
};
const char * pPermissionsNames[] = { "IsOperator", "NoDefloodGetnicklist", "NoDefloodMyinfo", "NoDefloodSearch", "NoDefloodPm",
"NoDefloodMainChat", "MassMsg", "Topic", "TempBan", "ReloadTxtFiles",
"NoTagCheck", "TempUnban", "DelRegUser", "AddRegUser", "NoChatLimits",
"NoMaxHubsCheck", "NoSlotHubRatioCheck", "NoSlotCheck", "NoShareLimit", "ClrPermBan",
"ClrTempBan", "GetInfo", "GetBans", "ScriptControl", "RstHub",
"TempOp", "GagUngag", "Redirect", "Ban", "Kick", "Drop",
"EnterIfHubFull", "EnterIfIpBan", "AllowedOpChat", "SendAllUsersIp", "RangeBan",
"RangeUnban", "RangeTempBan", "RangeTempUnban", "GetRangeBans", "ClrRangePermBans",
"ClrRangeTempBans", "Unban", "NoSearchLimits", "SendLongMyinfos", "NoIpCheck",
"Close", "NoDefloodCtm", "NoDefloodRctm", "NoDefloodSr", "NoDefloodRecv",
"NoChatInterval", "NoPmInterval", "NoSearchInterval", "NoMaxUsrSameIp", "NoReconnTime"
};
for (uint8_t ui8i = 0; ui8i < sizeof(ui8Permissions); ui8i++)
{
lua_pushinteger(pLua, ui8Permissions[ui8i]);
lua_setfield(pLua, iNewTable, pPermissionsNames[ui8i]);
}
lua_setfield(pLua, iTable, "tPermissions");
lua_pop(pLua, 1);
}
//------------------------------------------------------------------------------
bool ScriptStart(Script * pScript)
{
pScript->m_ui16Functions = 65535;
pScript->m_ui32DataArrivals = 4294967295U;
pScript->m_pPrev = NULL;
pScript->m_pNext = NULL;
#ifdef _WIN32
pScript->m_pLua = lua_newstate(LuaAlocator, NULL);
#else
pScript->m_pLua = luaL_newstate();
#endif
if (pScript->m_pLua == NULL)
{
return false;
}
luaL_openlibs(pScript->m_pLua);
lua_atpanic(pScript->m_pLua, ScriptPanic);
// replace internal lua os.exit with correct shutdown
lua_getglobal(pScript->m_pLua, "os");
if (lua_istable(pScript->m_pLua, -1))
{
lua_pushcfunction(pScript->m_pLua, OsExit);
lua_setfield(pScript->m_pLua, -2, "exit");
lua_pop(pScript->m_pLua, 1);
}
#if LUA_VERSION_NUM > 501
luaL_requiref(pScript->m_pLua, "Core", RegCore, 1);
lua_pop(pScript->m_pLua, 1);
luaL_requiref(pScript->m_pLua, "SetMan", RegSetMan, 1);
AddSettingIds(pScript->m_pLua);
luaL_requiref(pScript->m_pLua, "RegMan", RegRegMan, 1);
lua_pop(pScript->m_pLua, 1);
luaL_requiref(pScript->m_pLua, "BanMan", RegBanMan, 1);
lua_pop(pScript->m_pLua, 1);
luaL_requiref(pScript->m_pLua, "ProfMan", RegProfMan, 1);
AddPermissionsIds(pScript->m_pLua);
luaL_requiref(pScript->m_pLua, "TmrMan", RegTmrMan, 1);
lua_pop(pScript->m_pLua, 1);
luaL_requiref(pScript->m_pLua, "UDPDbg", RegUDPDbg, 1);
lua_pop(pScript->m_pLua, 1);
luaL_requiref(pScript->m_pLua, "ScriptMan", RegScriptMan, 1);
lua_pop(pScript->m_pLua, 1);
luaL_requiref(pScript->m_pLua, "IP2Country", RegIP2Country, 1);
lua_pop(pScript->m_pLua, 1);
#else
RegCore(pScript->m_pLua);
RegSetMan(pScript->m_pLua);
lua_getglobal(pScript->m_pLua, "SetMan");
if (lua_istable(pScript->m_pLua, -1))
{
AddSettingIds(pScript->m_pLua);
}
RegRegMan(pScript->m_pLua);
RegBanMan(pScript->m_pLua);
RegProfMan(pScript->m_pLua);
lua_getglobal(pScript->m_pLua, "ProfMan");
if (lua_istable(pScript->m_pLua, -1))
{
AddPermissionsIds(pScript->m_pLua);
}
RegTmrMan(pScript->m_pLua);
RegUDPDbg(pScript->m_pLua);
RegScriptMan(pScript->m_pLua);
RegIP2Country(pScript->m_pLua);
#endif
if (luaL_dofile(pScript->m_pLua, (ServerManager::m_sScriptPath + pScript->m_sName).c_str()) == 0)
{
#ifdef _BUILD_GUI
RichEditAppendText(MainWindowPageScripts::m_Ptr->m_hWndPageItems[MainWindowPageScripts::REDT_SCRIPTS_ERRORS],
(string(LanguageManager::m_Ptr->m_sTexts[LAN_NO_SYNERR_IN_SCRIPT_FILE], (size_t)LanguageManager::m_Ptr->m_ui16TextsLens[LAN_NO_SYNERR_IN_SCRIPT_FILE]) + " " + string(pScript->m_sName)).c_str());
#endif
return true;
}
else
{
size_t szLen = 0;
const char * stmp = (char*)lua_tolstring(pScript->m_pLua, -1, &szLen);
const string sMsg(stmp, szLen);
#ifdef _BUILD_GUI
RichEditAppendText(MainWindowPageScripts::m_Ptr->m_hWndPageItems[MainWindowPageScripts::REDT_SCRIPTS_ERRORS],
(string(LanguageManager::m_Ptr->m_sTexts[LAN_SYNTAX], (size_t)LanguageManager::m_Ptr->m_ui16TextsLens[LAN_SYNTAX]) + " " + sMsg).c_str());
#endif
UdpDebug::m_Ptr->BroadcastFormat("[LUA] %s", sMsg.c_str());
if (SettingManager::m_Ptr->m_bBools[SETBOOL_LOG_SCRIPT_ERRORS] == true)
{
AppendLog(sMsg, true);
}
lua_close(pScript->m_pLua);
pScript->m_pLua = NULL;
return false;
}
}
//------------------------------------------------------------------------------
void ScriptStop(Script * pScript)
{
if (pScript->m_bRegUDP == true)
{
UdpDebug::m_Ptr->Remove(pScript->m_sName);
pScript->m_bRegUDP = false;
}
ScriptTimer * pCurTmr = NULL,
* pNextTmr = ScriptManager::m_Ptr->m_pTimerListS;
while (pNextTmr != NULL)
{
pCurTmr = pNextTmr;
pNextTmr = pCurTmr->m_pNext;
if (pScript->m_pLua == pCurTmr->m_pLua)
{
#if defined(_WIN32) && !defined(_WIN_IOT)
if (pCurTmr->m_uiTimerId != 0)
{
KillTimer(NULL, pCurTmr->m_uiTimerId);
}
#endif
if (pCurTmr->m_pPrev == NULL)
{
if (pCurTmr->m_pNext == NULL)
{
ScriptManager::m_Ptr->m_pTimerListS = NULL;
ScriptManager::m_Ptr->m_pTimerListE = NULL;
}
else
{
ScriptManager::m_Ptr->m_pTimerListS = pCurTmr->m_pNext;
ScriptManager::m_Ptr->m_pTimerListS->m_pPrev = NULL;
}
}
else if (pCurTmr->m_pNext == NULL)
{
ScriptManager::m_Ptr->m_pTimerListE = pCurTmr->m_pPrev;
ScriptManager::m_Ptr->m_pTimerListE->m_pNext = NULL;
}
else
{
pCurTmr->m_pPrev->m_pNext = pCurTmr->m_pNext;
pCurTmr->m_pNext->m_pPrev = pCurTmr->m_pPrev;
}
delete pCurTmr;
}
}
if (pScript->m_pLua != NULL)
{
lua_close(pScript->m_pLua);
pScript->m_pLua = NULL;
}
ScriptBot * pBot = NULL,
* next = pScript->m_pBotList;
while (next != NULL)
{
pBot = next;
next = pBot->m_pNext;
ReservedNicksManager::m_Ptr->DelReservedNick(pBot->m_sNick, true);
if (ServerManager::m_bServerRunning == true)
{
Users::m_Ptr->DelFromNickList(pBot->m_sNick, pBot->m_bIsOP);
Users::m_Ptr->DelBotFromMyInfos(pBot->m_sMyINFO);
int iMsgLen = snprintf(ServerManager::m_pGlobalBuffer, ServerManager::m_szGlobalBufferSize, "$Quit %s|", pBot->m_sNick);
if (iMsgLen > 0)
{
GlobalDataQueue::m_Ptr->AddQueueItem(ServerManager::m_pGlobalBuffer, iMsgLen, NULL, 0, GlobalDataQueue::CMD_QUIT);
}
}
delete pBot;
}
pScript->m_pBotList = NULL;
}
//------------------------------------------------------------------------------
int ScriptGetGC(Script * pScript)
{
return lua_gc(pScript->m_pLua, LUA_GCCOUNT, 0);
}
//------------------------------------------------------------------------------
void ScriptOnStartup(Script * pScript)
{
lua_pushcfunction(pScript->m_pLua, ScriptTraceback);
int iTraceback = lua_gettop(pScript->m_pLua);
lua_getglobal(pScript->m_pLua, "OnStartup");
int i = lua_gettop(pScript->m_pLua);
if (lua_isfunction(pScript->m_pLua, i) == 0)
{
pScript->m_ui16Functions &= ~Script::ONSTARTUP;
lua_settop(pScript->m_pLua, 0);
return;
}
if (lua_pcall(pScript->m_pLua, 0, 0, iTraceback) != 0)
{
ScriptError(pScript);
lua_settop(pScript->m_pLua, 0);
return;
}
// clear the stack for sure
lua_settop(pScript->m_pLua, 0);
}
//------------------------------------------------------------------------------
void ScriptOnExit(Script * pScript)
{
lua_pushcfunction(pScript->m_pLua, ScriptTraceback);
int iTraceback = lua_gettop(pScript->m_pLua);
lua_getglobal(pScript->m_pLua, "OnExit");
int i = lua_gettop(pScript->m_pLua);
if (lua_isfunction(pScript->m_pLua, i) == 0)
{
pScript->m_ui16Functions &= ~Script::ONEXIT;
lua_settop(pScript->m_pLua, 0);
return;
}
if (lua_pcall(pScript->m_pLua, 0, 0, iTraceback) != 0)
{
ScriptError(pScript);
lua_settop(pScript->m_pLua, 0);
return;
}
// clear the stack for sure
lua_settop(pScript->m_pLua, 0);
}
//------------------------------------------------------------------------------
static bool ScriptOnError(Script * pScript, const char * sErrorMsg, const size_t szMsgLen)
{
lua_pushcfunction(pScript->m_pLua, ScriptTraceback);
int iTraceback = lua_gettop(pScript->m_pLua);
lua_getglobal(pScript->m_pLua, "OnError");
int i = lua_gettop(pScript->m_pLua);
if (lua_isfunction(pScript->m_pLua, i) == 0)
{
pScript->m_ui16Functions &= ~Script::ONERROR;
lua_settop(pScript->m_pLua, 0);
return true;
}
ScriptManager::m_Ptr->m_pActualUser = NULL;
lua_pushlstring(pScript->m_pLua, sErrorMsg, szMsgLen);
if (lua_pcall(pScript->m_pLua, 1, 0, iTraceback) != 0) // 1 passed parameters, zero returned
{
size_t szLen = 0;
const char * stmp = (char*)lua_tolstring(pScript->m_pLua, -1, &szLen);
const string sMsg(stmp, szLen);
#ifdef _BUILD_GUI
RichEditAppendText(MainWindowPageScripts::m_Ptr->m_hWndPageItems[MainWindowPageScripts::REDT_SCRIPTS_ERRORS],
(string(LanguageManager::m_Ptr->m_sTexts[LAN_SYNTAX], (size_t)LanguageManager::m_Ptr->m_ui16TextsLens[LAN_SYNTAX]) + " " + sMsg).c_str());
RichEditAppendText(MainWindowPageScripts::m_Ptr->m_hWndPageItems[MainWindowPageScripts::REDT_SCRIPTS_ERRORS],
(string(LanguageManager::m_Ptr->m_sTexts[LAN_FATAL_ERR_SCRIPT], (size_t)LanguageManager::m_Ptr->m_ui16TextsLens[LAN_FATAL_ERR_SCRIPT]) + " " + string(pScript->m_sName) + " ! " +
string(LanguageManager::m_Ptr->m_sTexts[LAN_SCRIPT_STOPPED], (size_t)LanguageManager::m_Ptr->m_ui16TextsLens[LAN_SCRIPT_STOPPED]) + "!").c_str());
#endif
if (SettingManager::m_Ptr->m_bBools[SETBOOL_LOG_SCRIPT_ERRORS] == true)
{
AppendLog(sMsg, true);
}
lua_settop(pScript->m_pLua, 0);
return false;
}
// clear the stack for sure
lua_settop(pScript->m_pLua, 0);
return true;
}
//------------------------------------------------------------------------------
void ScriptPushUser(lua_State * pLua, User * pUser, const bool bFullTable/* = false*/)
{
lua_checkstack(pLua, 3); // we need 3 (1 table, 2 id, 3 value) empty slots in stack, check it to be sure
lua_newtable(pLua);
int i = lua_gettop(pLua);
lua_pushliteral(pLua, "sNick");
lua_pushlstring(pLua, pUser->m_sNick, pUser->m_ui8NickLen);
lua_rawset(pLua, i);
lua_pushliteral(pLua, "uptr");
lua_pushlightuserdata(pLua, (void *)pUser);
lua_rawset(pLua, i);
lua_pushliteral(pLua, "sIP");
lua_pushlstring(pLua, pUser->m_sIP, pUser->m_ui8IpLen);
lua_rawset(pLua, i);
lua_pushliteral(pLua, "iProfile");
lua_pushinteger(pLua, pUser->m_i32Profile);
lua_rawset(pLua, i);
if (bFullTable == true)
{
ScriptPushUserExtended(pLua, pUser, i);
}
}
//------------------------------------------------------------------------------
void ScriptPushUserExtended(lua_State * pLua, User * pUser, const int iTable)
{
lua_pushliteral(pLua, "sMode");
if (pUser->m_sModes[0] != '\0')
{
lua_pushstring(pLua, pUser->m_sModes);
}
else
{
lua_pushnil(pLua);
}
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "sMyInfoString");
if (pUser->m_sMyInfoOriginal != NULL)
{
lua_pushlstring(pLua, pUser->m_sMyInfoOriginal, pUser->m_ui16MyInfoOriginalLen);
}
else
{
lua_pushnil(pLua);
}
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "sDescription");
if (pUser->m_sDescription != NULL)
{
lua_pushlstring(pLua, pUser->m_sDescription, (size_t)pUser->m_ui8DescriptionLen);
}
else
{
lua_pushnil(pLua);
}
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "sTag");
if (pUser->m_sTag != NULL)
{
lua_pushlstring(pLua, pUser->m_sTag, (size_t)pUser->m_ui8TagLen);
}
else
{
lua_pushnil(pLua);
}
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "sConnection");
if (pUser->m_sConnection != NULL)
{
lua_pushlstring(pLua, pUser->m_sConnection, (size_t)pUser->m_ui8ConnectionLen);
}
else
{
lua_pushnil(pLua);
}
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "sEmail");
if (pUser->m_sEmail != NULL)
{
lua_pushlstring(pLua, pUser->m_sEmail, (size_t)pUser->m_ui8EmailLen);
}
else
{
lua_pushnil(pLua);
}
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "sClient");
if (pUser->m_sClient != NULL)
{
lua_pushlstring(pLua, pUser->m_sClient, (size_t)pUser->m_ui8ClientLen);
}
else
{
lua_pushnil(pLua);
}
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "sClientVersion");
if (pUser->m_sTagVersion != NULL)
{
lua_pushlstring(pLua, pUser->m_sTagVersion, (size_t)pUser->m_ui8TagVersionLen);
}
else
{
lua_pushnil(pLua);
}
lua_rawset(pLua, iTable);
#ifdef FLYLINKDC_USE_VERSION
lua_pushliteral(pLua, "sVersion");
if (pUser->m_sVersion != NULL)
{
lua_pushstring(pLua, pUser->m_sVersion);
}
else
{
lua_pushnil(pLua);
}
lua_rawset(pLua, iTable);
#endif
lua_pushliteral(pLua, "sCountryCode");
if (IpP2Country::m_Ptr->m_ui32Count != 0)
{
lua_pushlstring(pLua, IpP2Country::m_Ptr->GetCountry(pUser->m_ui8Country, false), 2);
}
else
{
lua_pushnil(pLua);
}
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "bConnected");
pUser->m_ui8State == User::STATE_ADDED ? lua_pushboolean(pLua, 1) : lua_pushboolean(pLua, 0);
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "bActive");
if ((pUser->m_ui32BoolBits & User::BIT_IPV6) == User::BIT_IPV6)
{
(pUser->m_ui32BoolBits & User::BIT_IPV6_ACTIVE) == User::BIT_IPV6_ACTIVE ? lua_pushboolean(pLua, 1) : lua_pushboolean(pLua, 0);
}
else
{
(pUser->m_ui32BoolBits & User::BIT_IPV4_ACTIVE) == User::BIT_IPV4_ACTIVE ? lua_pushboolean(pLua, 1) : lua_pushboolean(pLua, 0);
}
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "bOperator");
(pUser->m_ui32BoolBits & User::BIT_OPERATOR) == User::BIT_OPERATOR ? lua_pushboolean(pLua, 1) : lua_pushboolean(pLua, 0);
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "bUserCommand");
(pUser->m_ui32SupportBits & User::SUPPORTBIT_USERCOMMAND) == User::SUPPORTBIT_USERCOMMAND ? lua_pushboolean(pLua, 1) : lua_pushboolean(pLua, 0);
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "bQuickList");
(pUser->m_ui32SupportBits & User::SUPPORTBIT_QUICKLIST) == User::SUPPORTBIT_QUICKLIST ? lua_pushboolean(pLua, 1) : lua_pushboolean(pLua, 0);
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "bSuspiciousTag");
(pUser->m_ui32BoolBits & User::BIT_HAVE_BADTAG) == User::BIT_HAVE_BADTAG ? lua_pushboolean(pLua, 1) : lua_pushboolean(pLua, 0);
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "iShareSize");
#if LUA_VERSION_NUM < 503
lua_pushnumber(pLua, (double)pUser->m_ui64SharedSize);
#else
lua_pushinteger(pLua, pUser->m_ui64SharedSize);
#endif
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "iHubs");
#if LUA_VERSION_NUM < 503
lua_pushnumber(pLua, pUser->m_ui32Hubs);
#else
lua_pushinteger(pLua, pUser->m_ui32Hubs);
#endif
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "iNormalHubs");
#if LUA_VERSION_NUM < 503
(pUser->m_ui32BoolBits & User::BIT_OLDHUBSTAG) == User::BIT_OLDHUBSTAG ? lua_pushnil(pLua) : lua_pushnumber(pLua, pUser->m_ui32NormalHubs);
#else
(pUser->m_ui32BoolBits & User::BIT_OLDHUBSTAG) == User::BIT_OLDHUBSTAG ? lua_pushnil(pLua) : lua_pushinteger(pLua, pUser->m_ui32NormalHubs);
#endif
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "iRegHubs");
#if LUA_VERSION_NUM < 503
(pUser->m_ui32BoolBits & User::BIT_OLDHUBSTAG) == User::BIT_OLDHUBSTAG ? lua_pushnil(pLua) : lua_pushnumber(pLua, pUser->m_ui32RegHubs);
#else
(pUser->m_ui32BoolBits & User::BIT_OLDHUBSTAG) == User::BIT_OLDHUBSTAG ? lua_pushnil(pLua) : lua_pushinteger(pLua, pUser->m_ui32RegHubs);
#endif
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "iOpHubs");
#if LUA_VERSION_NUM < 503
(pUser->m_ui32BoolBits & User::BIT_OLDHUBSTAG) == User::BIT_OLDHUBSTAG ? lua_pushnil(pLua) : lua_pushnumber(pLua, pUser->m_ui32OpHubs);
#else
(pUser->m_ui32BoolBits & User::BIT_OLDHUBSTAG) == User::BIT_OLDHUBSTAG ? lua_pushnil(pLua) : lua_pushinteger(pLua, pUser->m_ui32OpHubs);
#endif
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "iSlots");
#if LUA_VERSION_NUM < 503
lua_pushnumber(pLua, pUser->m_ui32Slots);
#else
lua_pushinteger(pLua, pUser->m_ui32Slots);
#endif
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "iLlimit");
#if LUA_VERSION_NUM < 503
lua_pushnumber(pLua, pUser->m_ui32LLimit);
#else
lua_pushinteger(pLua, pUser->m_ui32LLimit);
#endif
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "iDefloodWarns");
#if LUA_VERSION_NUM < 503
lua_pushnumber(pLua, pUser->m_ui32DefloodWarnings);
#else
lua_pushinteger(pLua, pUser->m_ui32DefloodWarnings);
#endif
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "iMagicByte");
#if LUA_VERSION_NUM < 503
lua_pushnumber(pLua, pUser->m_ui8MagicByte);
#else
lua_pushinteger(pLua, pUser->m_ui8MagicByte);
#endif
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "iLoginTime");
#if LUA_VERSION_NUM < 503
lua_pushnumber(pLua, (double)pUser->m_tLoginTime);
#else
lua_pushinteger(pLua, pUser->m_tLoginTime);
#endif
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "sMac");
char sMac[18];
sMac[0] = 0;
if (GetMacAddress(pUser->m_sIP, sMac) == true)
{
lua_pushlstring(pLua, sMac, 17);
}
else
{
lua_pushnil(pLua);
}
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "bDescriptionChanged");
(pUser->m_ui32InfoBits & User::INFOBIT_DESCRIPTION_CHANGED) == User::INFOBIT_DESCRIPTION_CHANGED ? lua_pushboolean(pLua, 1) : lua_pushboolean(pLua, 0);
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "bTagChanged");
(pUser->m_ui32InfoBits & User::INFOBIT_TAG_CHANGED) == User::INFOBIT_TAG_CHANGED ? lua_pushboolean(pLua, 1) : lua_pushboolean(pLua, 0);
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "bConnectionChanged");
(pUser->m_ui32InfoBits & User::INFOBIT_CONNECTION_CHANGED) == User::INFOBIT_CONNECTION_CHANGED ? lua_pushboolean(pLua, 1) : lua_pushboolean(pLua, 0);
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "bEmailChanged");
(pUser->m_ui32InfoBits & User::INFOBIT_EMAIL_CHANGED) == User::INFOBIT_EMAIL_CHANGED ? lua_pushboolean(pLua, 1) : lua_pushboolean(pLua, 0);
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "bShareChanged");
(pUser->m_ui32InfoBits & User::INFOBIT_SHARE_CHANGED) == User::INFOBIT_SHARE_CHANGED ? lua_pushboolean(pLua, 1) : lua_pushboolean(pLua, 0);
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "sScriptedDescriptionShort");
if (pUser->m_sChangedDescriptionShort != NULL)
{
lua_pushlstring(pLua, pUser->m_sChangedDescriptionShort, pUser->m_ui8ChangedDescriptionShortLen);
}
else
{
lua_pushnil(pLua);
}
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "sScriptedDescriptionLong");
if (pUser->m_sChangedDescriptionLong != NULL)
{
lua_pushlstring(pLua, pUser->m_sChangedDescriptionLong, pUser->m_ui8ChangedDescriptionLongLen);
}
else
{
lua_pushnil(pLua);
}
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "sScriptedTagShort");
if (pUser->m_sChangedTagShort != NULL)
{
lua_pushlstring(pLua, pUser->m_sChangedTagShort, pUser->m_ui8ChangedTagShortLen);
}
else
{
lua_pushnil(pLua);
}
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "sScriptedTagLong");
if (pUser->m_sChangedTagLong != NULL)
{
lua_pushlstring(pLua, pUser->m_sChangedTagLong, pUser->m_ui8ChangedTagLongLen);
}
else
{
lua_pushnil(pLua);
}
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "sScriptedConnectionShort");
if (pUser->m_sChangedConnectionShort != NULL)
{
lua_pushlstring(pLua, pUser->m_sChangedConnectionShort, pUser->m_ui8ChangedConnectionShortLen);
}
else
{
lua_pushnil(pLua);
}
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "sScriptedConnectionLong");
if (pUser->m_sChangedConnectionLong != NULL)
{
lua_pushlstring(pLua, pUser->m_sChangedConnectionLong, pUser->m_ui8ChangedConnectionLongLen);
}
else
{
lua_pushnil(pLua);
}
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "sScriptedEmailShort");
if (pUser->m_sChangedEmailShort != NULL)
{
lua_pushlstring(pLua, pUser->m_sChangedEmailShort, pUser->m_ui8ChangedEmailShortLen);
}
else
{
lua_pushnil(pLua);
}
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "sScriptedEmailLong");
if (pUser->m_sChangedEmailLong != NULL)
{
lua_pushlstring(pLua, pUser->m_sChangedEmailLong, pUser->m_ui8ChangedEmailLongLen);
}
else
{
lua_pushnil(pLua);
}
lua_rawset(pLua, iTable);
#ifdef USE_FLYLINKDC_EXT_JSON
lua_pushliteral(pLua, "sExtJson");
if (pUser->m_user_ext_info && pUser->m_user_ext_info->GetExtJSONCommand().length())
{
lua_pushlstring(pLua, pUser->m_user_ext_info->GetExtJSONCommand().c_str(), (size_t)pUser->m_user_ext_info->GetExtJSONCommand().length());
}
else
{
lua_pushnil(pLua);
}
lua_rawset(pLua, iTable);
#endif
lua_pushliteral(pLua, "iScriptediShareSizeShort");
#if LUA_VERSION_NUM < 503
lua_pushnumber(pLua, (double)pUser->m_ui64ChangedSharedSizeShort);
#else
lua_pushinteger(pLua, pUser->m_ui64ChangedSharedSizeShort);
#endif
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "iScriptediShareSizeLong");
#if LUA_VERSION_NUM < 503
lua_pushnumber(pLua, (double)pUser->m_ui64ChangedSharedSizeLong);
#else
lua_pushinteger(pLua, pUser->m_ui64ChangedSharedSizeLong);
#endif
lua_rawset(pLua, iTable);
lua_pushliteral(pLua, "tIPs");
lua_newtable(pLua);
int t = lua_gettop(pLua);
#if LUA_VERSION_NUM < 503
lua_pushnumber(pLua, 1);
#else
lua_pushinteger(pLua, 1);
#endif
lua_pushlstring(pLua, pUser->m_sIP, pUser->m_ui8IpLen);
lua_rawset(pLua, t);
if (pUser->m_sIPv4[0] != '\0')
{
#if LUA_VERSION_NUM < 503
lua_pushnumber(pLua, 2);
#else
lua_pushinteger(pLua, 2);
#endif
lua_pushlstring(pLua, pUser->m_sIPv4, pUser->m_ui8IPv4Len);
lua_rawset(pLua, t);
}
lua_rawset(pLua, iTable);
// alex82 ... HideUser / ������� �����
lua_pushliteral(pLua, "bHidden");
(pUser->m_ui32InfoBits & User::INFOBIT_HIDDEN) == User::INFOBIT_HIDDEN ? lua_pushboolean(pLua, 1) : lua_pushboolean(pLua, 0);
lua_rawset(pLua, iTable);
// alex82 ... NoQuit / ��������� $Quit ��� �����
lua_pushliteral(pLua, "bNoQuit");
(pUser->m_ui32InfoBits & User::INFOBIT_NO_QUIT) == User::INFOBIT_NO_QUIT ? lua_pushboolean(pLua, 1) : lua_pushboolean(pLua, 0);
lua_rawset(pLua, iTable);
// alex82 ... HideUserKey / ������ ���� �����
lua_pushliteral(pLua, "bHiddenKey");
(pUser->m_ui32InfoBits & User::INFOBIT_HIDE_KEY) == User::INFOBIT_HIDE_KEY ? lua_pushboolean(pLua, 1) : lua_pushboolean(pLua, 0);
lua_rawset(pLua, iTable);
}
//------------------------------------------------------------------------------
User * ScriptGetUser(lua_State * pLua, const int iTop, const char * sFunction)
{
lua_pushliteral(pLua, "uptr");
lua_gettable(pLua, 1);
if (lua_gettop(pLua) != iTop + 1 || lua_type(pLua, iTop + 1) != LUA_TLIGHTUSERDATA)
{
luaL_error(pLua, "bad argument #1 to '%s' (it's not user table)", sFunction);
return NULL;
}
User *u = reinterpret_cast<User *>(lua_touserdata(pLua, iTop + 1));
if (u == NULL)
{
return NULL;
}
if (u != ScriptManager::m_Ptr->m_pActualUser)
{
lua_pushliteral(pLua, "sNick");
lua_gettable(pLua, 1);
if (lua_gettop(pLua) != iTop + 2 || lua_type(pLua, iTop + 2) != LUA_TSTRING)
{
luaL_error(pLua, "bad argument #1 to '%s' (it's not user table)", sFunction);
return NULL;
}
size_t szNickLen;
const char * sNick = lua_tolstring(pLua, iTop + 2, &szNickLen);
if (u != HashManager::m_Ptr->FindUser(sNick, szNickLen))
{
return NULL;
}
}
return u;
}
//------------------------------------------------------------------------------
void ScriptError(Script * pScript)
{
size_t szLen = 0;
const char * stmp = (char*)lua_tolstring(pScript->m_pLua, -1, &szLen);
const string sMsg(stmp, szLen);
#ifdef _BUILD_GUI
RichEditAppendText(MainWindowPageScripts::m_Ptr->m_hWndPageItems[MainWindowPageScripts::REDT_SCRIPTS_ERRORS],
(string(LanguageManager::m_Ptr->m_sTexts[LAN_SYNTAX], (size_t)LanguageManager::m_Ptr->m_ui16TextsLens[LAN_SYNTAX]) + " " + sMsg).c_str());
#endif
UdpDebug::m_Ptr->BroadcastFormat("[LUA] %s", sMsg.c_str());
if (SettingManager::m_Ptr->m_bBools[SETBOOL_LOG_SCRIPT_ERRORS] == true)
{
AppendLog(sMsg, true);
}
if ((((pScript->m_ui16Functions & Script::ONERROR) == Script::ONERROR) == true && ScriptOnError(pScript, stmp, szLen) == false) ||
SettingManager::m_Ptr->m_bBools[SETBOOL_STOP_SCRIPT_ON_ERROR] == true)
{
// PPK ... stop buggy script ;)
EventQueue::m_Ptr->AddNormal(EventQueue::EVENT_STOPSCRIPT, pScript->m_sName);
}
}
//------------------------------------------------------------------------------
#if defined(_WIN32) && !defined(_WIN_IOT)
void ScriptOnTimer(const UINT_PTR& uiTimerId)
{
#else
void ScriptOnTimer(const uint64_t &ui64ActualMillis)
{
#endif
lua_State * pLuaState = NULL;
ScriptTimer * pCurTmr = NULL,
* pNextTmr = ScriptManager::m_Ptr->m_pTimerListS;
while (pNextTmr != NULL)
{
pCurTmr = pNextTmr;
pNextTmr = pCurTmr->m_pNext;
#if defined(_WIN32) && !defined(_WIN_IOT)
if (pCurTmr->m_uiTimerId == uiTimerId)
{
#else
while ((pCurTmr->m_ui64LastTick < ui64ActualMillis) && (ui64ActualMillis - pCurTmr->m_ui64LastTick) >= pCurTmr->m_ui64Interval)
{
pCurTmr->m_ui64LastTick += pCurTmr->m_ui64Interval;
#endif
lua_pushcfunction(pCurTmr->m_pLua, ScriptTraceback);
int iTraceback = lua_gettop(pCurTmr->m_pLua);
if (pCurTmr->m_sFunctionName != NULL)
{
lua_getglobal(pCurTmr->m_pLua, pCurTmr->m_sFunctionName);
int i = lua_gettop(pCurTmr->m_pLua);
if (lua_isfunction(pCurTmr->m_pLua, i) == 0)
{
lua_settop(pCurTmr->m_pLua, 0);
#if defined(_WIN32) && !defined(_WIN_IOT)
return;
#else
continue;
#endif
}
}
else
{
lua_rawgeti(pCurTmr->m_pLua, LUA_REGISTRYINDEX, pCurTmr->m_iFunctionRef);
}
ScriptManager::m_Ptr->m_pActualUser = NULL;
lua_checkstack(pCurTmr->m_pLua, 1); // we need 1 empty slots in stack, check it to be sure
#if defined(_WIN32) && !defined(_WIN_IOT)
lua_pushlightuserdata(pCurTmr->m_pLua, (void *)uiTimerId);
#else
lua_pushlightuserdata(pCurTmr->m_pLua, (void *)pCurTmr);
#endif
pLuaState = pCurTmr->m_pLua; // For case when timer will be removed in OnTimer
// 1 passed parameters, 0 returned
if (lua_pcall(pCurTmr->m_pLua, 1, 0, iTraceback) != 0)
{
ScriptError(ScriptManager::m_Ptr->FindScript(pLuaState));
lua_settop(pLuaState, 0);
#if defined(_WIN32) && !defined(_WIN_IOT)
return;
#else
if (pNextTmr == NULL)
{
if (ScriptManager::m_Ptr->m_pTimerListE != pCurTmr)
{
break;
}
}
else if (pNextTmr->m_pPrev != pCurTmr)
{
break;
}
continue;
#endif
}
// clear the stack for sure
lua_settop(pLuaState, 0);
#if defined(_WIN32) && !defined(_WIN_IOT)
return;
#else
if (pNextTmr == NULL)
{
if (ScriptManager::m_Ptr->m_pTimerListE != pCurTmr)
{
break;
}
}
else if (pNextTmr->m_pPrev != pCurTmr)
{
break;
}
continue;
#endif
}
}
}
//------------------------------------------------------------------------------
int ScriptTraceback(lua_State *pLua)
{
#if LUA_VERSION_NUM > 501
const char * sMsg = lua_tostring(pLua, 1);
if (sMsg != NULL)
{
luaL_traceback(pLua, pLua, sMsg, 1);
return 1;
}
return 0;
#else
if (!lua_isstring(pLua, 1))
{
return 1;
}
lua_getfield(pLua, LUA_GLOBALSINDEX, "debug");
if (!lua_istable(pLua, -1))
{
lua_pop(pLua, 1);
return 1;
}
lua_getfield(pLua, -1, "traceback");
if (lua_isfunction(pLua, -1) == 0)
{
lua_pop(pLua, 2);
return 1;
}
lua_pushvalue(pLua, 1);
lua_pushinteger(pLua, 2);
lua_call(pLua, 2, 1);
return 1;
#endif
}
//------------------------------------------------------------------------------
↑ V1042 This file is marked with copyleft license, which requires you to open the derived source code.
↑ V538 The line contains control character 0x0B (vertical tabulation).