diff --git a/README.md b/README.md index a8250da..a0e4c6c 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ -# knxr-antitroll - -![Image](https://i.imgur.com/ugH2X8D.png) - -## Features -- Admin Command to Toggle antitroll: /troll -- AntiVDM -- Disable DriveBy -- Disable Punching / Disable Punching Damage - -## Installation -- Downloaded! -- Move it to your Resources folder. -- Have Fun! :D +# knxr-antitroll + +![Image](https://i.imgur.com/ugH2X8D.png) + +## Features +- Admin Command to Toggle antitroll: /troll +- AntiVDM +- Disable DriveBy +- Disable Punching / Disable Punching Damage + +## Installation +- Downloaded! +- Move it to your Resources folder. +- Have Fun! :D diff --git a/client/cl_functions.lua b/client/cl_functions.lua index 82bfa28..ad63ad1 100644 --- a/client/cl_functions.lua +++ b/client/cl_functions.lua @@ -1,117 +1,118 @@ -local isTimerInstance = false -function setUiShow(bool) - SendNUIMessage({ - type = "show", - show = bool - }) -end - -function updateUiTime(timeLeft) - SendNUIMessage({ - type = "update", - minleft = timeLeft - }) -end - -function updateTimeToDatabase(overrideTime) - TriggerServerEvent("knxr-antitroll:updateTime", overrideTime or timeLeft) -end - -function startTimer() - local interval = timeToSafe - - updateTimeToDatabase() - - CreateThread(function() - isTimerInstance = true - while hasProtection do - - if interval == timeToSafe or timeLeft <= 0 then - interval = 0 - setUiShow(true) - updateTimeToDatabase() - end - - interval = interval + 1 - - if timeLeft <= 0 then - stopAntiTroll() - isTimerInstance = false - return - end - - timeLeft = timeLeft - 1 - - - updateUiTime(timeLeft) - Wait(1000 * 60) - end - end) -end - -function startAntiTroll() - if not isTimerInstance then - startTimer() - end - setUiShow(true) - - -- Anti VDM - if Config.DisableVDM then - SetWeaponDamageModifier(-1553120962, 0.0) - end - - -- Anti Driveby - if not Config.DriveBy then - SetPlayerCanDoDriveBy(PlayerId(), false) - end - - if Config.DisablePunching then - CreateThread(function() - while hasProtection do - Wait(5) - DisableControlAction(0, 140, true) - DisableControlAction(0, 141, true) - DisableControlAction(0, 142, true) - end - end) - end - - if Config.DisableShooting then - CreateThread(function() - while hasProtection do - Wait(5) - DisablePlayerFiring(player, true) - end - end) - end - - if Config.DisablePunchingDamage then - SetWeaponDamageModifier(-1569615261, 0.0) - end -end - -function stopAntiTroll() - hasProtection = false - timeLeft = 0 - - -- Anti VDM - if Config.DisableVDM then - SetWeaponDamageModifier(-1553120962, 1.0) - end - - -- Anti Driveby - if not Config.DriveBy then - SetPlayerCanDoDriveBy(PlayerId(), true) - end - - if Config.DisablePunching then - EnableControlAction(0, 140, true) - EnableControlAction(0, 141, true) - EnableControlAction(0, 142, true) - end - - if Config.DisablePunchingDamage then - SetWeaponDamageModifier(-1569615261, 1.0) - end - setUiShow(false) +local isTimerInstance = false + +function setUiShow(bool) + SendNUIMessage({ + type = "show", + show = bool + }) +end + +function updateUiTime(timeLeft) + SendNUIMessage({ + type = "update", + minleft = timeLeft + }) +end + +function updateTimeToDatabase(overrideTime) + TriggerServerEvent("knxr-antitroll:updateTime", overrideTime or timeLeft) +end + +function startTimer() + local interval = timeToSafe + + updateTimeToDatabase() + + CreateThread(function() + isTimerInstance = true + while hasProtection do + + if interval == timeToSafe or timeLeft <= 0 then + interval = 0 + setUiShow(true) + updateTimeToDatabase() + end + + interval = interval + 1 + + if timeLeft <= 0 then + stopAntiTroll() + isTimerInstance = false + return + end + + timeLeft = timeLeft - 1 + + + updateUiTime(timeLeft) + Wait(1000 * 60) + end + end) +end + +function startAntiTroll() + if not isTimerInstance then + startTimer() + end + setUiShow(true) + + -- Anti VDM + if Config.DisableVDM then + SetWeaponDamageModifier(-1553120962, 0.0) + end + + -- Anti Driveby + if not Config.DriveBy then + SetPlayerCanDoDriveBy(PlayerId(), false) + end + + if Config.DisablePunching then + CreateThread(function() + while hasProtection do + Wait(5) + DisableControlAction(0, 140, true) + DisableControlAction(0, 141, true) + DisableControlAction(0, 142, true) + end + end) + end + + if Config.DisableShooting then + CreateThread(function() + while hasProtection do + Wait(5) + DisablePlayerFiring(player, true) + end + end) + end + + if Config.DisablePunchingDamage then + SetWeaponDamageModifier(-1569615261, 0.0) + end +end + +function stopAntiTroll() + hasProtection = false + timeLeft = 0 + + -- Anti VDM + if Config.DisableVDM then + SetWeaponDamageModifier(-1553120962, 1.0) + end + + -- Anti Driveby + if not Config.DriveBy then + SetPlayerCanDoDriveBy(PlayerId(), true) + end + + if Config.DisablePunching then + EnableControlAction(0, 140, true) + EnableControlAction(0, 141, true) + EnableControlAction(0, 142, true) + end + + if Config.DisablePunchingDamage then + SetWeaponDamageModifier(-1569615261, 1.0) + end + setUiShow(false) end \ No newline at end of file diff --git a/client/cl_main.lua b/client/cl_main.lua index e8b37f3..c833d38 100644 --- a/client/cl_main.lua +++ b/client/cl_main.lua @@ -1,37 +1,37 @@ --- old esx Support -if not ESX then - ESX = nil - TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) - while ESX == nil do - Citizen.Wait(0) - end -end - -hasProtection = false -timeLeft = 0 - --- STATIC VARIABLES -timeToSafe = Config.TimeToSave - -RegisterNetEvent("knxr-antitroll:toggle", function(toggle, timeOverride) - hasProtection = toggle or not hasProtection - timeLeft = timeOverride or Config.HowLong - - if hasProtection then - startAntiTroll() - else - stopAntiTroll() - updateTimeToDatabase(0) - end -end) - -RegisterNetEvent('esx:playerLoaded') -AddEventHandler('esx:playerLoaded',function(xPlayer, isNew, skin) - TriggerServerEvent("knxr-antitroll:onjoin", isNew) -end) - -AddEventHandler("onResourceStart", function(resourceName) - if resourceName == GetCurrentResourceName() then - TriggerServerEvent("knxr-antitroll:onjoin", false) - end +-- old esx Support +if not ESX then + ESX = nil + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + while ESX == nil do + Citizen.Wait(0) + end +end + +hasProtection = false +timeLeft = 0 + +-- STATIC VARIABLES +timeToSafe = Config.TimeToSave + +RegisterNetEvent("knxr-antitroll:toggle", function(toggle, timeOverride) + hasProtection = toggle or not hasProtection + timeLeft = timeOverride or Config.HowLong + + if hasProtection then + startAntiTroll() + else + stopAntiTroll() + updateTimeToDatabase(0) + end +end) + +RegisterNetEvent('esx:playerLoaded') +AddEventHandler('esx:playerLoaded',function(xPlayer, isNew, skin) + TriggerServerEvent("knxr-antitroll:onjoin", isNew) +end) + +AddEventHandler("onResourceStart", function(resourceName) + if resourceName == GetCurrentResourceName() then + TriggerServerEvent("knxr-antitroll:onjoin", false) + end end) \ No newline at end of file diff --git a/config.lua b/config.lua index 49d50dd..6cc85f3 100644 --- a/config.lua +++ b/config.lua @@ -1,14 +1,14 @@ -Config = {} - -Config.AdminCommand = "troll" -- The Name of the Admin Command -Config.Rang = "admin" -- The Rang needed for the Admin Command - -Config.HowLong = 60 -- How Long the Player should have antitroll on -Config.TimeToSave = 5 -- How often the time should be saved in the Database - --- SETTING FOR PLAYERS WITH ANTITROLL ON -Config.DisableVDM = true -- Disables damage from cars while the player still has Troll Protection. (Players still get demage off the ground) -Config.DriveBy = false -- Activates / Deactivates Drivebys -Config.DisableShooting = false -- Disables Shooting -Config.DisablePunching = true -- Disables hitting for players still in troll protect mode +Config = {} + +Config.AdminCommand = "troll" -- The Name of the Admin Command +Config.Rang = "admin" -- The Rang needed for the Admin Command + +Config.HowLong = 60 -- How Long the Player should have antitroll on +Config.TimeToSave = 5 -- How often the time should be saved in the Database + +-- SETTING FOR PLAYERS WITH ANTITROLL ON +Config.DisableVDM = true -- Disables damage from cars while the player still has Troll Protection. (Players still get demage off the ground) +Config.DriveBy = false -- Activates / Deactivates Drivebys +Config.DisableShooting = false -- Disables Shooting +Config.DisablePunching = true -- Disables hitting for players still in troll protect mode Config.DisablePunchingDamage = true -- Disables the Damage other would get with Fists when they get Punshed \ No newline at end of file diff --git a/fxmanifest.lua b/fxmanifest.lua index 318967d..3267975 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -1,34 +1,36 @@ -fx_version "cerulean" -games { "gta5" } -lua54 "yes" -shared_script "@es_extended/imports.lua" - -ui_page "ui/ui.html" - -client_scripts { - "client/cl_main.lua", - "client/cl_functions.lua", -} - -shared_scripts { - "config.lua" -} - -files { - "ui/ui.html", - "ui/js/app.js", - "ui/css/app.css", -} - - -server_scripts { - "@oxmysql/lib/MySQL.lua", - "server/sv_main.lua", - "sv_config.lua", -} - --- Dependencies -dependencies { - "es_extended", - "oxmysql", +fx_version "cerulean" +games { "gta5" } +lua54 "yes" +shared_script "@es_extended/imports.lua" + +ui_page "ui/ui.html" + +client_scripts { + "client/cl_main.lua", + "client/cl_functions.lua", +} + +shared_scripts { + "config.lua" +} + +files { + "ui/ui.html", + "ui/js/app.js", + "ui/css/app.css", +} + + +server_scripts { + "@oxmysql/lib/MySQL.lua", + "server/sv_tests.lua", + "server/sv_functions.lua", + "server/sv_main.lua", + "sv_config.lua", +} + +-- Dependencies +dependencies { + "es_extended", + "oxmysql", } \ No newline at end of file diff --git a/server/sv_functions.lua b/server/sv_functions.lua new file mode 100644 index 0000000..ee0a78e --- /dev/null +++ b/server/sv_functions.lua @@ -0,0 +1,92 @@ +-- Types: info (default), error, warning +function cPrint(string, type) + if type == "error" then + print(("^0[^1Error^0] %s"):format(string)) + elseif type == "info" or not type then + print(("^0[^2Info^0] %s"):format(string)) + elseif type == "warning" then + print(("^0[^3Warning^0] %s"):format(string)) + end +end + +local spacing = " " +function testPrint(stringPass, stringFail, passed) + if passed then + print(("%s^0[^2✔^0] ^2%s"):format(spacing, stringPass)) + else + print(("%s^0[^1✖^0] ^1%s"):format(spacing, stringFail)) + end +end + +function createTableIfNotExist() + cPrint("Checking if table exists...", "info") + MySQL.query([[ + create table if not exists antitroll_time + ( + identifier varchar(46) not null, + hasProtection bit default 0 not null, + time_left int default 0 not null, + constraint `PRIMARY` + primary key (identifier) + );]], {}, function(result) + if result and result.warningStatus == 0 then + cPrint("Table does not exist but was created!", "warning") + else + cPrint("Table exists!", "info") + end + end) +end + +function getCommandString() + if type(Config.AdminCommand) ~= "string" then + cPrint("Config.AdminCommand is not a string, using default value 'troll'", "warning") + return "troll" + else + return string.lower(Config.AdminCommand) + end +end + +function getCommandRang() + if type(Config.Rang) ~= "string" then + cPrint("Config.Rang is not a string, using default value 'admin'", "warning") + return "admin" + else + return Config.Rang + end +end + +-- MYSQL STUFF +function insert(identifier, time) + MySQL.query.await('insert into antitroll_time (identifier, time_left) values (?, ?)', {identifier, time}) +end + +function update(identifier, time) + MySQL.query.await('update antitroll_time set time_left = ? where identifier = ?', {time, identifier}) +end + +function doesUserExist(identifier) + local result = MySQL.query.await('select * from antitroll_time where identifier = ?', {identifier}) + if result[1] then + return true + else + return false + end +end + +function getTimeLeft(identifier) + local result = MySQL.query.await('select * from antitroll_time where identifier = ?', {identifier}) + + if result[1] then + return result[1].time_left + else + return 0 + end +end + +function updateOrInsert(identifier, time) + if doesUserExist(identifier) then + update(identifier, time) + else + insert(identifier, time) + end +end \ No newline at end of file diff --git a/server/sv_main.lua b/server/sv_main.lua index 010dce2..e5fe134 100644 --- a/server/sv_main.lua +++ b/server/sv_main.lua @@ -1,139 +1,67 @@ --- old esx Support -if not ESX then - ESX = nil - TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) - while ESX == nil do - Citizen.Wait(0) - end -end - --- Types: info (default), error, warning -local function cPrint(string, type) - if type == "error" then - print(("^0[^1Error^0] %s"):format(string)) - elseif type == "info" or not type then - print(("^0[^2Info^0] %s"):format(string)) - elseif type == "warning" then - print(("^0[^3Warning^0] %s"):format(string)) - end -end - -print([[^1 - _ _ _ _____ ___ _____ ___ ___ _ _ - /_\ | \| |_ _|_ _| |_ _| _ \/ _ \| | | | - / _ \| .` | | | | | | | | / (_) | |__| |__ - /_/ \_\_|\_| |_| |___| |_| |_|_\\___/|____|____| - ^8by ZerX (github.com/ZerXGIT)^0 - ]]) - - -CreateThread(function() - cPrint("Checking if table exists...", "info") - local result = MySQL.query.await([[create table if not exists antitroll_time - ( - identifier varchar(46) not null, - hasProtection bit default 0 not null, - time_left int default 0 not null, - constraint `PRIMARY` - primary key (identifier) - );]]) - - if result.warningStatus == 0 then - cPrint("Table does not exist but was created!", "warning") - else - cPrint("Table exists! :)", "info") - end -end) - -local function getCommandString() - if type(Config.AdminCommand) ~= "string" then - cPrint("Config.AdminCommand is not a string, using default value 'troll'", "warning") - return "troll" - else - return string.lower(Config.AdminCommand) - end -end - -local function getCommandRang() - if type(Config.Rang) ~= "string" then - cPrint("Config.Rang is not a string, using default value 'admin'", "warning") - return "admin" - else - return Config.Rang - end -end - -local function insert(identifier, time) - MySQL.query.await('insert into antitroll_time (identifier, time_left) values (?, ?)', {identifier, time}) -end - -local function update(identifier, time) - MySQL.query.await('update antitroll_time set time_left = ? where identifier = ?', {time, identifier}) -end - -local function doesUserExist(identifier) - local result = MySQL.query.await('select * from antitroll_time where identifier = ?', {identifier}) - if result[1] then - return true - else - return false - end -end - -local function getTimeLeft(identifier) - local result = MySQL.query.await('select * from antitroll_time where identifier = ?', {identifier}) - - if result[1] then - return result[1].time_left - else - return 0 - end -end - -local function updateOrInsert(identifier, time) - if doesUserExist(identifier) then - update(identifier, time) - else - insert(identifier, time) - end -end - -ESX.RegisterCommand(getCommandString(), getCommandRang(), function(xPlayer, args, showError) - local id = args.id - local target = id - - if not target then - cPrint("Player not found!", "error") - return - end - - target.triggerEvent("knxr-antitroll:toggle") - cPrint("Troll protection enabled for " .. target.name .. " for " .. Config.HowLong .. " min!", "info") -end, true, {help = "Toggle Troll Protection", arguments = {{name = "id", help = "Player ID", type = "player"}}}) - -RegisterNetEvent("knxr-antitroll:updateTime", function(time) - local _source = source - local target = ESX.GetPlayerFromId(_source) - local identifier = target.getIdentifier() - - updateOrInsert(identifier, time) -end) - -RegisterNetEvent("knxr-antitroll:onjoin", function(isNew) - local target = ESX.GetPlayerFromId(source) - local identifier = target.getIdentifier() - - if isNew then - target.triggerEvent("knxr-antitroll:toggle", true) - return - end - - local time = getTimeLeft(identifier) - - if time > 0 then - target.triggerEvent("knxr-antitroll:toggle", true, time) - return - end - - updateOrInsert(identifier, time) +print([[^1 + _ _ _ _____ ___ _____ ___ ___ _ _ + /_\ | \| |_ _|_ _| |_ _| _ \/ _ \| | | | + / _ \| .` | | | | | | | | / (_) | |__| |__ + /_/ \_\_|\_| |_| |___| |_| |_|_\\___/|____|____| + ^8by ZerX (github.com/ZerXGIT)^0 +^0---------------------[^2Tests^0]---------------------]]) + + + -- old esx Support +if not ESX then + ESX = nil + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) +end + +testPrint("Oxmysql is installed.", "Oxmysql is not installed!", tests.checkForOxmysql()) +testPrint("ESX is installed.", "ESX is not installed!", tests.checkForESX()) +testPrint("Config found.", "Config not found!", tests.checkForConfig()) +print([[^0---------------------[^2Tests^0]---------------------]]) + +if tests.checkForOxmysql() and tests.checkForESX() and tests.checkForConfig() then + cPrint("All tests passed!", "info") +else + cPrint("^1One or more tests failed!^0", "error") + return +end + +createTableIfNotExist() + +ESX.RegisterCommand(getCommandString(), getCommandRang(), function(xPlayer, args, showError) + local id = args.id + local target = id + + if not target then + cPrint("Player not found!", "error") + return + end + + target.triggerEvent("knxr-antitroll:toggle") + cPrint("Troll protection enabled for " .. target.name .. " for " .. Config.HowLong .. " min!", "info") +end, true, {help = "Toggle Troll Protection", arguments = {{name = "id", help = "Player ID", type = "player"}}}) + +RegisterNetEvent("knxr-antitroll:updateTime", function(time) + local target = ESX.GetPlayerFromId(source) + local identifier = target.getIdentifier() + + updateOrInsert(identifier, time) +end) + +RegisterNetEvent("knxr-antitroll:onjoin", function(isNew) + local target = ESX.GetPlayerFromId(source) + local identifier = target.getIdentifier() + + if isNew then + target.triggerEvent("knxr-antitroll:toggle", true) + return + end + + local time = getTimeLeft(identifier) + + if time > 0 then + target.triggerEvent("knxr-antitroll:toggle", true, time) + return + end + + updateOrInsert(identifier, time) end) \ No newline at end of file diff --git a/server/sv_tests.lua b/server/sv_tests.lua new file mode 100644 index 0000000..78bcab6 --- /dev/null +++ b/server/sv_tests.lua @@ -0,0 +1,25 @@ +tests = {} + +function tests.checkForOxmysql() + if exports.oxmysql then + return true + else + return false + end +end + +function tests.checkForConfig() + if Config then + return true + else + return false + end +end + +function tests.checkForESX() + if ESX then + return true + else + return false + end +end \ No newline at end of file diff --git a/ui/css/app.css b/ui/css/app.css index 7be8e2a..535e687 100644 --- a/ui/css/app.css +++ b/ui/css/app.css @@ -1,58 +1,58 @@ -.content { - position: absolute; - bottom: 0; - right: 15vw; - width: auto; - height: 84px; - - background: linear-gradient(174deg, rgba(11,11,11,0.9) 52%, rgba(138,23,33,0.9) 100%, rgba(227,38,54,0.9) 100%); - border-radius: 5px 5px 0 0; - overflow: hidden; - - display: flex; - justify-content: space-between; - flex-wrap: nowrap; - align-items: center; -} - -.newPlayer { - font-family: 'Segoe UI'; - font-style: normal; - font-weight: 600; - font-size: 18px; - - margin-block-start: 0%; - margin-block-end: 0%; - - color: #E9E9E9; -} - -.description { - font-family: 'Segoe UI'; - font-style: normal; - font-weight: 400; - font-size: 14px; - /* line-height: 19px; */ - - margin-block-start: 0.3rem; - margin-block-end: 0.3rem; - - color: #E9E9E9; -} - -.timer { - font-family: 'Segoe UI'; - font-style: normal; - font-weight: 700; - font-size: 32px; - line-height: 43px; - margin: 11px; - /* identical to box height */ - - - color: #FFFFFF; -} - -.main-text { - margin: 11px; -} +.content { + position: absolute; + bottom: 0; + right: 15vw; + width: auto; + height: 84px; + + background: linear-gradient(174deg, rgba(11,11,11,0.9) 52%, rgba(138,23,33,0.9) 100%, rgba(227,38,54,0.9) 100%); + border-radius: 5px 5px 0 0; + overflow: hidden; + + display: flex; + justify-content: space-between; + flex-wrap: nowrap; + align-items: center; +} + +.newPlayer { + font-family: 'Segoe UI'; + font-style: normal; + font-weight: 600; + font-size: 18px; + + margin-block-start: 0%; + margin-block-end: 0%; + + color: #E9E9E9; +} + +.description { + font-family: 'Segoe UI'; + font-style: normal; + font-weight: 400; + font-size: 14px; + /* line-height: 19px; */ + + margin-block-start: 0.3rem; + margin-block-end: 0.3rem; + + color: #E9E9E9; +} + +.timer { + font-family: 'Segoe UI'; + font-style: normal; + font-weight: 700; + font-size: 32px; + line-height: 43px; + margin: 11px; + /* identical to box height */ + + + color: #FFFFFF; +} + +.main-text { + margin: 11px; +} diff --git a/ui/js/app.js b/ui/js/app.js index dc58922..fd579d8 100644 --- a/ui/js/app.js +++ b/ui/js/app.js @@ -1,22 +1,22 @@ -function main() { - return { - show: false, - minleft: 60, - - listen() { - window.addEventListener('message', (event) => { - let data = event.data - - switch(data.type) { - case 'show': - this.show = data.show; - break; - - case 'update': - this.minleft = data.minleft; - break; - } - }) - } - } +function main() { + return { + show: false, + minleft: 60, + + listen() { + window.addEventListener('message', (event) => { + let data = event.data + + switch(data.type) { + case 'show': + this.show = data.show; + break; + + case 'update': + this.minleft = data.minleft; + break; + } + }) + } + } } \ No newline at end of file diff --git a/ui/ui.html b/ui/ui.html index 3d565b3..2f18ae4 100644 --- a/ui/ui.html +++ b/ui/ui.html @@ -1,34 +1,34 @@ - - - - - - - - - - endzone- - - - -
-
-

You are a New-Player.

-

- You have to play with us for a while.
- Until then, you can't hit and shoot. -

-
-
- min -
-
- - + + + + + + + + + + endzone- + + + +
+
+

You are a New-Player.

+

+ You have to play with us for a while.
+ Until then, you can't hit and shoot. +

+
+
+ min +
+
+ +