-- ============================================================================= -- Функция получения первого октета IP адреса игрока -- Возвращает: IP адрес и числовое значение первого октета -- ============================================================================= function GetIP1(RoleID) -- Проверка входных параметров if not RoleID or RoleID == "" then return nil end local con = Sql_con() if not con then return nil end -- SQL запрос для получения первого октета IP адреса local sql = string.format([[SELECT ip,CONVERT(SUBSTRING_INDEX(ip,'.',-4),UNSIGNED INTEGER) AS ip FROM sm_db.roledata INNER JOIN sm_login.login_log ON sm_login.login_log.accountID = sm_db.roledata.AccountID WHERE sm_db.roledata.RoleID = '%s' AND sm_login.login_log.action = 'login' AND CAST(sm_login.login_log.time AS date) = CURDATE() ORDER BY sm_login.login_log.time DESC LIMIT 1]], RoleID) local rows = con:execute(sql) local ip1 = nil if rows then ip1 = rows:fetch() end con:close() return ip1 end -- ============================================================================= -- Функция получения второго октета IP адреса игрока -- Возвращает: IP адрес и числовое значение второго октета -- ============================================================================= function GetIP2(RoleID) -- Проверка входных параметров if not RoleID or RoleID == "" then return nil end local con = Sql_con() if not con then return nil end -- SQL запрос для получения второго октета IP адреса local sql = string.format([[SELECT ip,CONVERT(SUBSTRING_INDEX(ip,'.',-3),UNSIGNED INTEGER) AS ip FROM sm_db.roledata INNER JOIN sm_login.login_log ON sm_login.login_log.accountID = sm_db.roledata.AccountID WHERE sm_db.roledata.RoleID = '%s' AND sm_login.login_log.action = 'login' AND CAST(sm_login.login_log.time AS date) = CURDATE() ORDER BY sm_login.login_log.time DESC LIMIT 1]], RoleID) local rows = con:execute(sql) local ip2 = nil if rows then ip2 = rows:fetch() end con:close() return ip2 end -- ============================================================================= -- Функция получения третьего октета IP адреса игрока -- Возвращает: IP адрес и числовое значение третьего октета -- ============================================================================= function GetIP3(RoleID) -- Проверка входных параметров if not RoleID or RoleID == "" then return nil end local con = Sql_con() if not con then return nil end -- SQL запрос для получения третьего октета IP адреса local sql = string.format([[SELECT ip,CONVERT(SUBSTRING_INDEX(ip,'.',-2),UNSIGNED INTEGER) AS ip FROM sm_db.roledata INNER JOIN sm_login.login_log ON sm_login.login_log.accountID = sm_db.roledata.AccountID WHERE sm_db.roledata.RoleID = '%s' AND sm_login.login_log.action = 'login' AND CAST(sm_login.login_log.time AS date) = CURDATE() ORDER BY sm_login.login_log.time DESC LIMIT 1]], RoleID) local rows = con:execute(sql) local ip3 = nil if rows then ip3 = rows:fetch() end con:close() return ip3 end -- ============================================================================= -- Функция получения четвертого октета IP адреса игрока -- Возвращает: IP адрес и числовое значение четвертого октета -- ============================================================================= function GetIP4(RoleID) -- Проверка входных параметров if not RoleID or RoleID == "" then return nil end local con = Sql_con() if not con then return nil end -- SQL запрос для получения четвертого октета IP адреса local sql = string.format([[SELECT ip,CONVERT(SUBSTRING_INDEX(ip,'.',-1),UNSIGNED INTEGER) AS ip FROM sm_db.roledata INNER JOIN sm_login.login_log ON sm_login.login_log.accountID = sm_db.roledata.AccountID WHERE sm_db.roledata.RoleID = '%s' AND sm_login.login_log.action = 'login' AND CAST(sm_login.login_log.time AS date) = CURDATE() ORDER BY sm_login.login_log.time DESC LIMIT 1]], RoleID) local rows = con:execute(sql) local ip4 = nil if rows then ip4 = rows:fetch() end con:close() return ip4 end -- ============================================================================= -- Функция проверки IP адреса игрока для арены Frontir -- Возвращает: addId и IP адрес последнего входа -- ============================================================================= function Check_ArenaIP(RoleID) -- Проверка входных параметров if not RoleID or RoleID == "" then return nil, nil end local con = Sql_con() if not con then return nil, nil end -- SQL запрос для получения информации о последнем входе local sql = string.format([[SELECT sm_login.login_log.addId, sm_login.login_log.ip FROM sm_db.roledata INNER JOIN sm_login.login_log ON sm_login.login_log.accountID = sm_db.roledata.AccountID WHERE sm_db.roledata.RoleID = '%s' AND sm_login.login_log.action = 'login' AND CAST(sm_login.login_log.time AS date) = CURDATE() ORDER BY sm_login.login_log.time DESC LIMIT 1]], RoleID) local rows = con:execute(sql) local addId, ip = nil, nil if rows then addId, ip = rows:fetch() end -- Получение различных октетов IP для дополнительной проверки local ip1 = GetIP1(RoleID) -- Первый октет local ip2 = GetIP2(RoleID) -- Второй октет local ip3 = GetIP3(RoleID) -- Третий октет local ip4 = GetIP4(RoleID) -- Четвертый октет con:close() return addId, ip end -- ============================================================================= -- Функция управления рейтингом арены Frontir (ежедневный рейтинг) -- Параметры: -- RoleID - ID игрока -- ArenaVictory - количество побед -- ArenaDefeat - количество поражений -- Glory - количество славы -- add - флаг добавления статистики (1 = добавить) -- Возвращает: таблицу топ-10 игроков, статистику текущего игрока -- ============================================================================= function arena_frontire_reiting_sql(RoleID, ArenaVictory, ArenaDefeat, Glory, add) -- Проверка входных параметров if not RoleID or RoleID == "" then return nil, nil end local con = Sql_con() if not con then return nil, nil end -- Подсчет количества игроков в топ-10 local sql = "SELECT Count(RoleID) As Count FROM (SELECT RoleID FROM arena_frontire ORDER BY Glory DESC LIMIT 10) as t" local rows = con:execute(sql) local rating_count = 0 if rows then rating_count = rows:fetch() end -- Проверка статуса подарка для игрока local Gift_flag = 0 if RoleID and RoleID ~= "" then sql = string.format("SELECT Gift FROM arena_frontire WHERE RoleID = '%s'", RoleID) rows = con:execute(sql) if rows then Gift_flag = rows:fetch() or 0 end end -- Управление записью статистики игрока if RoleID and RoleID ~= "" then sql = string.format("SELECT * FROM arena_frontire WHERE RoleID = '%s'", RoleID) rows = con:execute(sql) -- Если игрок не найден в таблице, создаем новую запись if not (rows and rows:fetch()) then sql = string.format("INSERT INTO arena_frontire VALUES ('%s', '%s', '%s', '%s', 0)", RoleID, ArenaVictory or 0, ArenaDefeat or 0, Glory or 0) con:execute(sql) else -- Обновление существующей записи статистики if add and add == 1 then sql = string.format("UPDATE arena_frontire SET Glory = Glory+'%s', ArenaVictory = ArenaVictory+'%s', ArenaDefeat = ArenaDefeat+'%s' WHERE RoleID = '%s'", Glory or 0, ArenaVictory or 0, ArenaDefeat or 0, RoleID) con:execute(sql) -- Установка флага получения подарка, если игрок в топе if Gift_flag and Gift_flag == 0 then sql = string.format("UPDATE arena_frontire SET Gift = 1 WHERE RoleID = '%s'", RoleID) con:execute(sql) end end end end -- Получение топ-10 игроков по славе sql = "SELECT RoleID, Glory FROM arena_frontire ORDER BY Glory DESC LIMIT 10" rows = con:execute(sql) local rankings = {} local i = 1 if rows then local RoleID_rating, Glory RoleID_rating, Glory = rows:fetch() while RoleID_rating do rankings[i] = {id = RoleID_rating, glory = Glory} i = i + 1 RoleID_rating, Glory = rows:fetch() end end -- Получение персональной статистики текущего игрока local my_stats = nil if RoleID and RoleID ~= "" then sql = string.format("SELECT Glory,ArenaVictory,ArenaDefeat FROM arena_frontire WHERE RoleID = '%s'", RoleID) rows = con:execute(sql) if rows then local Glory, ArenaVictory, ArenaDefeat = rows:fetch() if Glory then my_stats = {glory = Glory, victory = ArenaVictory, defeat = ArenaDefeat} end end end con:close() return rankings, my_stats end -- ============================================================================= -- Функция управления месячным рейтингом арены Frontir -- Параметры аналогичны arena_frontire_reiting_sql, но работает с таблицей arena_frontire_mouth -- Возвращает: таблицу топ-10 игроков, статистику текущего игрока -- ============================================================================= function arena_frontire_reiting_sql_mouth(RoleID, ArenaVictory, ArenaDefeat, Glory, add) -- Проверка входных параметров if not RoleID or RoleID == "" then return nil, nil end local con = Sql_con() if not con then return nil, nil end -- Подсчет количества игроков в топ-10 local sql = "SELECT Count(RoleID) As Count FROM (SELECT RoleID FROM arena_frontire_mouth ORDER BY Glory DESC LIMIT 10) as t" local rows = con:execute(sql) local rating_count = 0 if rows then rating_count = rows:fetch() end -- Проверка статуса подарка для игрока local Gift_flag = 0 if RoleID and RoleID ~= "" then sql = string.format("SELECT Gift FROM arena_frontire_mouth WHERE RoleID = '%s'", RoleID) rows = con:execute(sql) if rows then Gift_flag = rows:fetch() or 0 end end -- Управление записью статистики игрока if RoleID and RoleID ~= "" then sql = string.format("SELECT * FROM arena_frontire_mouth WHERE RoleID = '%s'", RoleID) rows = con:execute(sql) -- Если игрок не найден в таблице, создаем новую запись if not (rows and rows:fetch()) then sql = string.format("INSERT INTO arena_frontire_mouth VALUES ('%s', '%s', '%s', '%s', 0)", RoleID, ArenaVictory or 0, ArenaDefeat or 0, Glory or 0) con:execute(sql) else -- Обновление существующей записи статистики if add and add == 1 then sql = string.format("UPDATE arena_frontire_mouth SET Glory = Glory+'%s', ArenaVictory = ArenaVictory+'%s', ArenaDefeat = ArenaDefeat+'%s' WHERE RoleID = '%s'", Glory or 0, ArenaVictory or 0, ArenaDefeat or 0, RoleID) con:execute(sql) -- Установка флага получения подарка, если игрок в топе if Gift_flag and Gift_flag == 0 then sql = string.format("UPDATE arena_frontire_mouth SET Gift = 1 WHERE RoleID = '%s'", RoleID) con:execute(sql) end end end end -- Получение топ-10 игроков по славе sql = "SELECT RoleID, Glory FROM arena_frontire_mouth ORDER BY Glory DESC LIMIT 10" rows = con:execute(sql) local rankings = {} local i = 1 if rows then local RoleID_rating, Glory RoleID_rating, Glory = rows:fetch() while RoleID_rating do rankings[i] = {id = RoleID_rating, glory = Glory} i = i + 1 RoleID_rating, Glory = rows:fetch() end end -- Получение персональной статистики текущего игрока local my_stats = nil if RoleID and RoleID ~= "" then sql = string.format("SELECT Glory,ArenaVictory,ArenaDefeat FROM arena_frontire_mouth WHERE RoleID = '%s'", RoleID) rows = con:execute(sql) if rows then local Glory, ArenaVictory, ArenaDefeat = rows:fetch() if Glory then my_stats = {glory = Glory, victory = ArenaVictory, defeat = ArenaDefeat} end end end con:close() return rankings, my_stats end -- ============================================================================= -- Функция очистки таблицы рейтинга арены Frontir -- Возвращает: true при успешной очистке, false при ошибке -- ============================================================================= function clear_reiting_sql() local con = Sql_con() if not con then return false end -- Очистка таблицы ежедневного рейтинга local sql = "TRUNCATE TABLE arena_frontire" local success = con:execute(sql) con:close() return success ~= nil end -- ============================================================================= -- Экспорт функций модуля -- ============================================================================= local FrontirSQL_Module = { -- Функции получения IP октетов GetIP1 = GetIP1, GetIP2 = GetIP2, GetIP3 = GetIP3, GetIP4 = GetIP4, -- Функции проверки и управления рейтингом Check_ArenaIP = Check_ArenaIP, arena_frontire_reiting_sql = arena_frontire_reiting_sql, arena_frontire_reiting_sql_mouth = arena_frontire_reiting_sql_mouth, -- Служебные функции clear_reiting_sql = clear_reiting_sql } return FrontirSQL_Module