├── html ├── bg.jpg ├── bg-dark.jpg ├── laptopbg.png ├── laptopbg.psd ├── tabletbg.png ├── tabletbg.psd ├── icons │ ├── menu.png │ ├── tuner.png │ ├── filemgr.jpg │ └── firefox.png ├── config.js ├── laptopscreenbg.jpg ├── textanim.css ├── textanim.js ├── custom.css ├── index.css ├── index.js └── index.html ├── tabletbg.png ├── item.sql ├── __resource.lua ├── README.md ├── server.lua └── client.lua /html/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nertigel/esx_tuner_laptop/HEAD/html/bg.jpg -------------------------------------------------------------------------------- /tabletbg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nertigel/esx_tuner_laptop/HEAD/tabletbg.png -------------------------------------------------------------------------------- /html/bg-dark.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nertigel/esx_tuner_laptop/HEAD/html/bg-dark.jpg -------------------------------------------------------------------------------- /html/laptopbg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nertigel/esx_tuner_laptop/HEAD/html/laptopbg.png -------------------------------------------------------------------------------- /html/laptopbg.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nertigel/esx_tuner_laptop/HEAD/html/laptopbg.psd -------------------------------------------------------------------------------- /html/tabletbg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nertigel/esx_tuner_laptop/HEAD/html/tabletbg.png -------------------------------------------------------------------------------- /html/tabletbg.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nertigel/esx_tuner_laptop/HEAD/html/tabletbg.psd -------------------------------------------------------------------------------- /html/icons/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nertigel/esx_tuner_laptop/HEAD/html/icons/menu.png -------------------------------------------------------------------------------- /html/icons/tuner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nertigel/esx_tuner_laptop/HEAD/html/icons/tuner.png -------------------------------------------------------------------------------- /html/config.js: -------------------------------------------------------------------------------- 1 | var Config = { 2 | appName: "ECU Tuning", 3 | monitorBrand: "Roosta Boosta" 4 | }; -------------------------------------------------------------------------------- /html/icons/filemgr.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nertigel/esx_tuner_laptop/HEAD/html/icons/filemgr.jpg -------------------------------------------------------------------------------- /html/icons/firefox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nertigel/esx_tuner_laptop/HEAD/html/icons/firefox.png -------------------------------------------------------------------------------- /html/laptopscreenbg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nertigel/esx_tuner_laptop/HEAD/html/laptopscreenbg.jpg -------------------------------------------------------------------------------- /item.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO `items` (`name`, `label`, `limit`, `rare`, `can_remove`) VALUES ('tuning_laptop', 'Tuner Laptop', '1', '0', '1'); 2 | ALTER TABLE `owned_vehicles` ADD `tunerdata` LONGTEXT NOT NULL; -------------------------------------------------------------------------------- /__resource.lua: -------------------------------------------------------------------------------- 1 | resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' 2 | 3 | client_script "client.lua" 4 | server_script "@mysql-async/lib/MySQL.lua" 5 | server_script "server.lua" 6 | 7 | files { 8 | "html/index.html", 9 | "html/index.js", 10 | "html/config.js", 11 | "html/textanim.js", 12 | "html/index.css", 13 | "html/custom.css", 14 | "html/textanim.css", 15 | "html/laptopscreenbg.jpg", 16 | "html/tabletbg.png", 17 | } 18 | 19 | ui_page "html/index.html" 20 | 21 | dependency "es_extended" -------------------------------------------------------------------------------- /html/textanim.css: -------------------------------------------------------------------------------- 1 | .var-highlight{ 2 | color: #008ae6; 3 | } 4 | .string-highlight{ 5 | color: #008ae6; 6 | } 7 | 8 | #typewriter{ 9 | padding-top: 5px; 10 | font-size: 10px; 11 | color: #fff; 12 | margin: 0; 13 | overflow: hidden; 14 | font-family: "Lucida Sans Typewriter", "Lucida Console", Monaco, "Bitstream Vera Sans Mono", monospace; 15 | 16 | &:after{ 17 | content: "|"; 18 | animation: blink 500ms linear infinite alternate; 19 | } 20 | } 21 | 22 | @-webkit-keyframes blink{ 23 | 0%{opacity: 0;} 24 | 100%{opacity: 1;} 25 | } 26 | 27 | @-moz-keyframes blink{ 28 | 0%{opacity: 0;} 29 | 100%{opacity: 1;} 30 | } 31 | 32 | @keyframes blink{ 33 | 0%{opacity: 0;} 34 | 100%{opacity: 1;} 35 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Credits: 2 | ## 3 | ## Nertigel | Nertigel#5391 | AlphaVeta 4 | ## https://discord.gg/JaZDPQr 5 | ### ModFreakz for scamming. 6 | 7 | ## Requirements 8 | - es_extended - https://github.com/ESX-Org/es_extended 9 | - esx_vehicleshop - https://github.com/ESX-Org/esx_vehicleshop 10 | - progressBars - https://github.com/chipsahoy6/progressBars 11 | 12 | ## Installation 13 | - Import SQL file. 14 | - Rename `esx_tuner_laptop` to `tunerchip` 15 | - Place tunerchip folder into resources folder. 16 | - ensure tunerchip in server.cfg 17 | - If you're not using my version of esx_inventoryhud make sure you add `tuning_laptop` to `esx_inventoryhud\config.lua`, `Config.CloseUIItems` 18 | 19 | ### Instructions 20 | - Use `tuner_laptop` item, Modify to your liking and click `SAVE`. 21 | - To make it into default you could press on `DEFAULT` and then `SAVE`. 22 | - If you want to delete the a tune from a car that you're sitting in simply type `/untune`. 23 | -------------------------------------------------------------------------------- /html/textanim.js: -------------------------------------------------------------------------------- 1 | function setupTypewriter(HTML, t) { 2 | t.innerHTML = ""; 3 | 4 | var cursorPosition = 0, 5 | tag = "", 6 | writingTag = false, 7 | tagOpen = false, 8 | typeSpeed = 1, 9 | tempTypeSpeed = 0; 10 | 11 | 12 | var type = function() { 13 | 14 | if (writingTag === true) { 15 | tag += HTML[cursorPosition]; 16 | } 17 | 18 | if (HTML[cursorPosition] === "<") { 19 | tempTypeSpeed = 0; 20 | if (tagOpen) { 21 | tagOpen = false; 22 | writingTag = true; 23 | } else { 24 | tag = ""; 25 | tagOpen = true; 26 | writingTag = true; 27 | tag += HTML[cursorPosition]; 28 | } 29 | } 30 | if (!writingTag && tagOpen) { 31 | tag.innerHTML += HTML[cursorPosition]; 32 | } 33 | if (!writingTag && !tagOpen) { 34 | if (HTML[cursorPosition] === " ") { 35 | tempTypeSpeed = 0; 36 | } 37 | else { 38 | tempTypeSpeed = (Math.random() * typeSpeed) + 0; 39 | } 40 | t.innerHTML += HTML[cursorPosition]; 41 | } 42 | if (writingTag === true && HTML[cursorPosition] === ">") { 43 | tempTypeSpeed = (Math.random() * typeSpeed) + 0; 44 | writingTag = false; 45 | if (tagOpen) { 46 | var newSpan = document.createElement("span"); 47 | t.appendChild(newSpan); 48 | newSpan.innerHTML = tag; 49 | tag = newSpan.firstChild; 50 | } 51 | } 52 | 53 | cursorPosition += 1; 54 | if (cursorPosition < HTML.length - 1) { 55 | setTimeout(type, tempTypeSpeed); 56 | } 57 | 58 | }; 59 | 60 | return { 61 | type: type 62 | }; 63 | } -------------------------------------------------------------------------------- /server.lua: -------------------------------------------------------------------------------- 1 | ESX = nil 2 | TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) 3 | 4 | local cS,dS,wDS 5 | ESX.RegisterUsableItem("tuning_laptop",function(source) 6 | if not cS then return; end 7 | local _source = source 8 | TriggerClientEvent("tuning:useLaptop",source) 9 | end) 10 | 11 | ESX.RegisterServerCallback("tuning:CheckStats",function(source,cb,veh) 12 | MySQL.Async.fetchAll('SELECT * FROM owned_vehicles WHERE plate=@plate',{['@plate'] = veh.plate},function(retData) 13 | if retData and retData[1] and cS then 14 | cb(true,json.decode(retData[1].tunerdata)) 15 | else 16 | cb(false,false) 17 | end 18 | end) 19 | end) 20 | 21 | RegisterNetEvent('tuning:SetData') 22 | AddEventHandler('tuning:SetData', function(data,veh) 23 | MySQL.Async.fetchAll('SELECT * FROM owned_vehicles WHERE plate=@plate',{['@plate'] = veh.plate},function(retData) 24 | if retData and retData[1] and wDS then 25 | MySQL.Async.execute('UPDATE owned_vehicles SET tunerdata=@tunerdata WHERE plate=@plate',{['@tunerdata'] = json.encode(data),['@plate'] = veh.plate},function(data) 26 | end) 27 | end 28 | end) 29 | end) 30 | 31 | RegisterNetEvent('tuning:UnSetData') 32 | AddEventHandler('tuning:UnSetData', function(veh) 33 | MySQL.Async.fetchAll('SELECT * FROM owned_vehicles WHERE plate=@plate',{['@plate'] = veh.plate},function(retData) 34 | if retData and retData[1] and wDS then 35 | MySQL.Async.execute('UPDATE owned_vehicles SET tunerdata=@tunerdata WHERE plate=@plate',{['@tunerdata'] = '',['@plate'] = veh.plate},function(data) 36 | end) 37 | end 38 | end) 39 | end) 40 | 41 | xPlyId = function(source) 42 | local tick = 0 43 | while not xPlayer and tick < 1000 do 44 | tick = tick + 1 45 | xPlayer = ESX.GetPlayerFromId(source) 46 | Citizen.Wait(0) 47 | end 48 | return xPlayer or false 49 | end 50 | 51 | local CT = Citizen.CreateThread 52 | DoAwake = function(...) 53 | while not ESX do Citizen.Wait(0); end 54 | DSP(true) 55 | dS = true 56 | sT() 57 | end 58 | ErrorLog = function(msg) print(msg) end 59 | DSP = function(val) cS = val; end 60 | sT = function(...) if dS and cS then wDS = 1; end; end 61 | CT(function(...) DoAwake(...); end) 62 | -------------------------------------------------------------------------------- /html/custom.css: -------------------------------------------------------------------------------- 1 | .col { 2 | color: #fff; 3 | } 4 | 5 | .text-muted { 6 | color: #fff!important; 7 | } 8 | 9 | .btn-success { 10 | background-color: #dd2232; 11 | border-color: #dd2232; 12 | user-select: none; 13 | border-radius: 0px; 14 | cursor: default; 15 | } 16 | 17 | .btn-success:hover { 18 | color: #fff; 19 | background-color: #b71c28; 20 | border-color: #b71c28; 21 | } 22 | 23 | .btn-success:disabled { 24 | color: #fff; 25 | background-color: #b71c28; 26 | border-color: #b71c28; 27 | } 28 | 29 | button#savebtn:active { 30 | color: #fff; 31 | background: #dd2232; 32 | border-color: #dd2232; 33 | cursor: default; 34 | } 35 | 36 | button#savebtn:focus { 37 | color: #fff; 38 | background: #dd2232; 39 | border-color: #dd2232; 40 | cursor: default; 41 | box-shadow: none; 42 | } 43 | 44 | button#defaultbtn:active { 45 | color: #fff; 46 | background-color: #dd2232; 47 | border-color: #dd2232; 48 | } 49 | 50 | button#defaultbtn:focus { 51 | background-color: #dd2232; 52 | border-color: #dd2232; 53 | color: #fff; 54 | box-shadow: none; 55 | } 56 | 57 | .ui-widget-content { 58 | border: 1px solid; 59 | border-color: #fff; 60 | background-color: #b71c28; 61 | background: none; 62 | user-select: none; 63 | } 64 | 65 | .ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { 66 | border: 1px solid #fff; 67 | user-select: none; 68 | } 69 | 70 | .ui-slider .ui-slider-handle:active { 71 | position: absolute; 72 | z-index: 2; 73 | width: 1.2em; 74 | height: 1.2em; 75 | cursor: default; 76 | background-image: linear-gradient(#dd2232, #b71c28); 77 | user-select: none; 78 | } 79 | 80 | .slider { 81 | border: 1px solid; 82 | border-color: #fff; 83 | background-color: #fff; 84 | user-select: none; 85 | } 86 | 87 | .ui-slider { 88 | position: relative; 89 | text-align: left; 90 | user-select: none; 91 | } 92 | .ui-slider .ui-slider-handle { 93 | position: absolute; 94 | z-index: 2; 95 | width: 1.2em; 96 | height: 1.2em; 97 | cursor: default; 98 | user-select: none; 99 | } 100 | .ui-slider .ui-slider-range { 101 | position: absolute; 102 | z-index: 1; 103 | font-size: .7em; 104 | display: block; 105 | border: 0; 106 | background-position: 0 0; 107 | user-select: none; 108 | } -------------------------------------------------------------------------------- /html/index.css: -------------------------------------------------------------------------------- 1 | .monitor { 2 | display:block; 3 | background-image: url("tabletbg.png"); 4 | background-size: 103%; 5 | background-repeat: no-repeat; 6 | position: absolute; 7 | margin-top: 5%; 8 | left: 380px; 9 | height:700px; 10 | width:100%; 11 | padding:0 !important; 12 | z-index: 2; 13 | user-select: none; 14 | } 15 | 16 | .monitor-brand { 17 | display:block; 18 | position:fixed; 19 | text-align:center; 20 | height:100%; 21 | width:100%; 22 | top:81%; 23 | font-size:24px; 24 | font-weight: 700; 25 | font-family: "YaHei UI"; 26 | user-select: none; 27 | } 28 | 29 | .program { 30 | display:block; 31 | position:relative; 32 | top: 108px; 33 | left: 181.5px; 34 | height: 440px; 35 | width: 804px; 36 | background-image: url("laptopscreenbg.jpg"); 37 | background-repeat: no-repeat; 38 | background-size: 100%; 39 | border-radius: 5px; 40 | overflow: hidden; 41 | padding-bottom:19px; 42 | user-select: none; 43 | } 44 | 45 | .program-top-bar { 46 | display:block; 47 | padding-left:310px; 48 | padding-right:10px; 49 | padding-top:3px; 50 | width:100%; 51 | height:40px; 52 | color:white; 53 | background-image: linear-gradient(to bottom left, #2c070a, #b71c28); 54 | font-family: roboto; 55 | font-weight: 600; 56 | font-size: 20px; 57 | user-select: none; 58 | } 59 | 60 | .colbtns { 61 | left: 440px; 62 | bottom: 260px; 63 | position: relative; 64 | width: 140px; 65 | z-index: 3; 66 | user-select: none; 67 | border-radius: 0px; 68 | } 69 | 70 | .colbtns:hover { 71 | color: #fff; 72 | background-color: #b71c28; 73 | border-color: #b71c28; 74 | user-select: none; 75 | } 76 | 77 | .colbtnd { 78 | left: 620px; 79 | bottom: 297px; 80 | position: relative; 81 | width: 140px; 82 | z-index: 3; 83 | user-select: none; 84 | } 85 | 86 | .ecutext-container { 87 | background-color: #000000; 88 | border-radius: 5px; 89 | position: relative; 90 | height: 235px; 91 | width: 380px; 92 | left: 413px; 93 | bottom: 290px; 94 | z-index: 1; 95 | user-select: none; 96 | } 97 | 98 | .massbg { 99 | background: none; 100 | position: center; 101 | left: 900px; 102 | } -------------------------------------------------------------------------------- /html/index.js: -------------------------------------------------------------------------------- 1 | var HTML; 2 | 3 | function sliderUpdated(event,ui) { 4 | } 5 | 6 | function getSliderValues() { 7 | return {boost:$("#boost").slider("value"),fuelmix:$("#fuelmix").slider("value"),gearchange:$("#gearchange").slider("value"),braking:$("#braking").slider("value"),drivetrain:$("#drivetrain").slider("value"),brakeforce:$("#brakeforce").slider("value")}; 8 | } 9 | 10 | function setSliderValues(values) { 11 | $(".slider").each(function(){ 12 | if(values[this.id]!=null) { 13 | $(this).slider("value",values[this.id]); 14 | } 15 | }); 16 | sliderUpdated(); 17 | } 18 | 19 | function menuToggle(bool,send=false) { 20 | if(bool) { 21 | $("body").show(); 22 | } else { 23 | $("body").hide(); 24 | } 25 | if(send){ 26 | $.post('http://tunerchip/togglemenu', JSON.stringify({state:false})); 27 | } 28 | } 29 | 30 | $(function(){ 31 | $("body").hide(); 32 | $("#appName").text(Config.appName); 33 | $("#boost").slider({min:0.05,value:0.25,step:0.01,max:0.30,change:sliderUpdated}); 34 | $("#fuelmix").slider({min:1,value:1.3,step:0.01,max:2,change:sliderUpdated}); 35 | $("#gearchange").slider({min:1,value:12,max:50,step:12,change:sliderUpdated}); 36 | $("#braking").slider({min:0.0,value:0.5,max:1,step:0.05,change:sliderUpdated}); 37 | $("#drivetrain").slider({min:0.0,value:0.5,max:1,step:0.5,change:sliderUpdated}); 38 | $("#brakeforce").slider({min:0.01,value:1.4,max:2,step:0.01,change:sliderUpdated}); 39 | $("#defaultbtn").click(function(){setSliderValues({boost:0.25,fuelmix:1.3,gearchange:9,braking:0.5,drivetrain:0.5,brakeforce:1.4});}); 40 | $("#savebtn").click(function(){ 41 | initiateTyepwriter(); 42 | $.post('http://tunerchip/save', JSON.stringify(getSliderValues())); 43 | }); 44 | $("#exitProgram").click(function(){ 45 | menuToggle(false,true); 46 | }); 47 | $("#shutDown").click(function(){ 48 | menuToggle(false,true); 49 | }); 50 | document.onkeyup = function (data) { 51 | if (data.which == 27) { 52 | menuToggle(false,true); 53 | } 54 | }; 55 | window.addEventListener('message', function(event){ 56 | if(event.data.type=="togglemenu") { 57 | menuToggle(event.data.state,false); 58 | if(event.data.data!=null) { 59 | setSliderValues(event.data.data); 60 | } 61 | } 62 | }); 63 | }); 64 | 65 | $(document).ready(function() { 66 | var typewriter = document.getElementById("typewriter"); 67 | HTML = typewriter.innerHTML; 68 | 69 | typewriter.innerHTML = ""; 70 | 71 | }); 72 | 73 | function initiateTyepwriter() { 74 | var t = document.getElementById("typewriter"); 75 | 76 | typewriter = setupTypewriter(HTML, t); 77 | typewriter.type(); 78 | 79 | toggleButton(1); 80 | setTimeout(function() {toggleButton(0); }, 5000); 81 | } 82 | 83 | function toggleButton(bool) { 84 | var btnSave = document.getElementById("savebtn"); 85 | btnSave.disabled = bool; 86 | } -------------------------------------------------------------------------------- /client.lua: -------------------------------------------------------------------------------- 1 | local menu = false 2 | ESX = nil 3 | 4 | function getVehData(veh) 5 | if not DoesEntityExist(veh) then return nil end 6 | local lvehstats = { 7 | boost = GetVehicleHandlingFloat(veh, "CHandlingData", "fInitialDriveForce"), 8 | fuelmix = GetVehicleHandlingFloat(veh, "CHandlingData", "fDriveInertia"), 9 | braking = GetVehicleHandlingFloat(veh ,"CHandlingData", "fBrakeBiasFront"), 10 | drivetrain = GetVehicleHandlingFloat(veh, "CHandlingData", "fDriveBiasFront"), 11 | brakeforce = GetVehicleHandlingFloat(veh, "CHandlingData", "fBrakeForce") 12 | } 13 | return lvehstats 14 | end 15 | 16 | function setVehData(veh,data) 17 | if not DoesEntityExist(veh) or not data then return nil end 18 | SetVehicleHandlingFloat(veh, "CHandlingData", "fInitialDriveForce", data.boost*1.0) 19 | SetVehicleHandlingFloat(veh, "CHandlingData", "fDriveInertia", data.fuelmix*1.0) 20 | SetVehicleEnginePowerMultiplier(veh, data.gearchange*1.0) 21 | SetVehicleHandlingFloat(veh, "CHandlingData", "fBrakeBiasFront", data.braking*1.0) 22 | SetVehicleHandlingFloat(veh, "CHandlingData", "fDriveBiasFront", data.drivetrain*1.0) 23 | SetVehicleHandlingFloat(veh, "CHandlingData", "fBrakeForce", data.brakeforce*1.0) 24 | 25 | TriggerServerEvent('tuning:SetData',data,ESX.Game.GetVehicleProperties(veh)) 26 | end 27 | 28 | Citizen.CreateThread(function() 29 | while ESX == nil do 30 | TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) 31 | Citizen.Wait(0) 32 | end 33 | end) 34 | 35 | function toggleMenu(b,send) 36 | menu = b 37 | SetNuiFocus(b,b) 38 | local vehData = getVehData(GetVehiclePedIsIn(GetPlayerPed(-1),false)) 39 | if send then SendNUIMessage(({type = "togglemenu", state = b, data = vehData})) end 40 | end 41 | 42 | RegisterNUICallback("togglemenu",function(data,cb) 43 | toggleMenu(data.state,false) 44 | end) 45 | 46 | RegisterNUICallback("save",function(data,cb) 47 | local veh = GetVehiclePedIsIn(GetPlayerPed(-1),false) 48 | if not IsPedInAnyVehicle(GetPlayerPed(-1)) or GetPedInVehicleSeat(veh, -1)~=GetPlayerPed(-1) then return end 49 | setVehData(veh,data) 50 | lastVeh = veh 51 | lastStats = stats 52 | end) 53 | 54 | RegisterNetEvent("tuning:useLaptop") 55 | AddEventHandler("tuning:useLaptop", function() 56 | if not menu then 57 | exports['progressBars']:startUI(2500, "Connecting Tuner Chip") 58 | TriggerEvent('esx_inventoryhud:doClose') 59 | Citizen.Wait(2500) 60 | TriggerEvent('esx_inventoryhud:doClose') 61 | local ped = GetPlayerPed(-1) 62 | toggleMenu(true,true) 63 | while IsPedInAnyVehicle(ped, false) and GetPedInVehicleSeat(GetVehiclePedIsIn(ped, false), -1)==ped do 64 | Citizen.Wait(100) 65 | end 66 | toggleMenu(false,true) 67 | else 68 | return 69 | end 70 | end) 71 | 72 | RegisterNetEvent("tuning:closeMenu") 73 | AddEventHandler("tuning:closeMenu",function() 74 | toggleMenu(false,true) 75 | end) 76 | 77 | local lastVeh = false 78 | local lastData = false 79 | local gotOut = false 80 | Citizen.CreateThread(function(...) 81 | while not ESX do Citizen.Wait(0); end 82 | while not ESX.IsPlayerLoaded() do Citizen.Wait(0); end 83 | while true do 84 | Citizen.Wait(30) 85 | if IsPedInAnyVehicle(GetPlayerPed(-1)) then 86 | local veh = GetVehiclePedIsIn(GetPlayerPed(-1),false) 87 | if veh ~= lastVeh or gotOut then 88 | if gotOut then gotOut = false; end 89 | local responded = false 90 | ESX.TriggerServerCallback('tuning:CheckStats', function(doTune,stats) 91 | if doTune then 92 | setVehData(veh,stats) 93 | lastStats = stats 94 | else 95 | if lastVeh and veh and lastVeh == veh and lastData then 96 | setVehData(veh,lastData) 97 | end 98 | end 99 | lastVeh = veh 100 | responded = true 101 | end, ESX.Game.GetVehicleProperties(veh)) 102 | while not responded do Citizen.Wait(0); end 103 | end 104 | else 105 | if not gotOut then 106 | gotOut = true 107 | end 108 | end 109 | end 110 | end) 111 | 112 | RegisterCommand("untune", function(source, args) 113 | TriggerServerEvent('tuning:UnSetData', ESX.Game.GetVehicleProperties(GetVehiclePedIsIn(GetPlayerPed(-1),false))) 114 | end) -------------------------------------------------------------------------------- /html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |
21 |
22 |
23 |
LS Customs
24 |
25 |
26 |
27 |
28 |
29 |
30 |

Turbo PSI ( 0PSI - 32 PSI )

31 |

32 |

Ignition Timing ( Retard - Advance )

33 |

34 |

Transmission ( 1 - 5 )

35 |

36 |

Brake Force ( Rear / Front )

37 |

38 |

Drive Bias ( Rear / Front )

39 |
40 |
41 | 42 |
43 |

Brake Force ( Weak - Strong )

44 |
45 |
46 |
47 |
48 |
49 |
50 |     Init lmECU.exe
51 |     --------------------------------
52 |     lmECU:\ validating engineer key
53 |     lmECU:\ validation success
54 |     lmECU:\ accessing sensors
55 |     lmECU:\ parsing senslog.xml
56 |     lmECU-senslog:\ running diagnostics
57 |                      0 faults detected
58 |     lmECU:\ applying modifications...
59 |     lmECU:\ generating senslog.xml
60 |     lmECU:\ parsing senslog.xml
61 |     lmECU-senslog:\ running diagnostics
62 |                      0 faults detected
63 |     lmECU:\ ECU remap successful
64 |     lmECU:\ end lmECU.exe
65 |                             

66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | 75 | 76 | 77 | 78 | 79 | --------------------------------------------------------------------------------