yoya99 Posted October 6, 2018 Share Posted October 6, 2018 Good day, I am currently resorting on the moddownloader created by xXMADEXx in order to load large sized vehicle replacments. The problem I want to face up to is that every server player needs to activate the replacements with a command /mods (a gui opens up). I would like to modify this, resulting in making the mods useable automatically right after every single one is downloaded. For example: I have currenty one car mod. After it finished downloading, I need to type the comman /mods to enable the replacement over the GUI. Can' t it just activate itself without typing any command? Thanks in advance for hints Link to comment
Dimos7 Posted October 7, 2018 Share Posted October 7, 2018 (edited) Yes it can you can use https://wiki.multitheftauto.com/wiki/onClientFileDowloadComplete Edited October 7, 2018 by Dimos7 Link to comment
Dimos7 Posted October 7, 2018 Share Posted October 7, 2018 https://wiki.multitheftauto.com/wiki/OnClientFileDownloadComplete Link to comment
yoya99 Posted October 7, 2018 Author Share Posted October 7, 2018 8 hours ago, Dimos7 said: https://wiki.multitheftauto.com/wiki/OnClientFileDownloadComplete I dont know where to add it into the many lua files.. I am really new. But this script is too complicated.. Maybe you could show it to me where to add it... It is in the resources section and is called "moddownloader". Link to comment
yoya99 Posted October 10, 2018 Author Share Posted October 10, 2018 On 07/10/2018 at 05:56, Dimos7 said: https://wiki.multitheftauto.com/wiki/OnClientFileDownloadComplete Please help me.. If you would be so kind to look after it.. Can you text me inside? Any payment is possible as well. Thanks Link to comment
Dimos7 Posted October 10, 2018 Share Posted October 10, 2018 9 minutes ago, yoya99 said: Please help me.. If you would be so kind to look after it.. Can you text me inside? Any payment is possible as well. Thanks We are not here make your codes i suggestion hire someone or find someone do it for you Link to comment
LilDawage Posted October 10, 2018 Share Posted October 10, 2018 Enabled mods after downloading , make dat Event OnClientFileDownloadComplete Create table For mods on server side and make stats Enabled or no + Downloaded or no if Donwloaded == true then Enabled mod = True but make sur that you need to loop are your Mods ( for i v in pairs (table mods) .... Link to comment
yoya99 Posted October 12, 2018 Author Share Posted October 12, 2018 I understand that, but how to adapt these function into the moddownloader system made by xxxmadexx Downloader = { } Downloader.Mods = { } Downloader.Files = { } Downloader.isRenderText = false; Downloader.gotResponse = false; -- Downloader Constructor function Downloader:Downloader ( ) end -- Downloader:RequestList -> Used to request vehicle mod list from server function Downloader:RequestList ( ) triggerServerEvent ( "ModDownloader:RequestFilesFromServer", localPlayer, localPlayer ); end -- Downloader:GetList -> Used to get the mods list downloaded from server function Downloader:GetList ( ) return Downloader.Mods; end -- Downloader:HandleRequest -> Used to handle response from the server for the mod list function Downloader.HandleResponse ( list ) Downloader.gotResponse = true; Downloader.Mods = list; Mods:PhraseList ( ); end addEvent ( "ModDownloader:OnServerSendClientModList", true ); addEventHandler ( "ModDownloader:OnServerSendClientModList", root, Downloader.HandleResponse ); function Downloader:AddDownload ( src ) if ( Downloader.Files [ src ] ) then return false; end Downloader.Files [ src ] = true; if ( not Downloader.isRenderText ) then Downloader.isRenderText = true; addEventHandler ( "onClientRender", root, Downloader.onClientRender ); end local b = downloadFile ( src ) if ( not b ) then Downloader.onFinish ( src, false ); end return b end function Downloader:GetDownloads ( ) return Downloader.Files; end function Downloader.onFinish ( file, success ) if ( Downloader.Files [ file ] ) then Downloader.Files [ file ] = nil; end if ( success ) then outputDebugString ( file.." has been downloaded!" ); else outputDebugString ( file .." has failed to download!" ); outputChatBox ( "Failed to download file '"..tostring(file).."'", 255, 0, 0 ); end if ( table.len ( Downloader:GetDownloads ( ) ) == 0 and Downloader.isRenderText ) then Downloader.isRenderText = false; removeEventHandler ( "onClientRender", root, Downloader.onClientRender ); end end addEventHandler ( "onClientFileDownloadComplete", root, Downloader.onFinish ); local sx, sy = guiGetScreenSize ( ); function Downloader.onClientRender ( ) dxDrawText ( "Downloading "..tostring ( table.len(Downloader:GetDownloads()) ).." files...", 0, 0, sx/1.1+2, sy/1.1+2, tocolor ( 0, 0, 0, 200 ), 2, "default-bold", "right", "bottom" ); dxDrawText ( "Downloading "..tostring ( table.len(Downloader:GetDownloads()) ).." files...", 0, 0, sx/1.1, sy/1.1, tocolor ( 0, 255, 255, 200 ), 2, "default-bold", "right", "bottom" ); end function table.len ( tb ) local l = 0; for _ in pairs ( tb ) do l = l + 1; end return l; end local __outputDebugString = _G['outputDebugString']; function outputDebugString ( msg, r, g, b ) if not r then r = 0 end if not g then g = 255 end if not b then b = 0 end __outputDebugString ( msg, 0, r, g, b ); end local sx, sy = guiGetScreenSize ( ); Inter = { }; Inter.btn = { }; Inter.grid = { }; Inter.window = guiCreateWindow((sx/2)-333, (sy/2)-333, 666, 510, "Mod Downloader Interface", false) guiWindowSetSizable(Inter.window, false) Inter.window.visible = false; Inter.grid.list = guiCreateGridList(9, 24, 643, 364, false, Inter.window) guiGridListAddColumn(Inter.grid.list, "Replace", 0.3) guiGridListAddColumn(Inter.grid.list, "New", 0.35) guiGridListAddColumn(Inter.grid.list, "Enabled", 0.15) guiGridListAddColumn(Inter.grid.list, "Status", 0.15) guiGridListSetSortingEnabled ( Inter.grid.list, false ); Inter.btn.enable = guiCreateButton(13, 397, 136, 39, "Enable", false, Inter.window) Inter.btn.enableAll = guiCreateButton(13, 446, 136, 39, "Enable All", false, Inter.window) Inter.btn.disable = guiCreateButton(159, 397, 136, 39, "Disable", false, Inter.window) Inter.btn.disableAll = guiCreateButton(159, 446, 136, 39, "Disable All", false, Inter.window) Inter.btn.refresh = guiCreateButton(516, 397, 136, 39, "Refresh", false, Inter.window) Inter.btn.close = guiCreateButton(516, 446, 136, 39, "Exit", false, Inter.window) function Inter.open ( b ) if ( b == Inter.window.visible ) then return false; end Inter.window.visible = b; showCursor ( b ); if ( b ) then Inter.btn.enable.enabled = false; Inter.btn.disable.enabled = false; Inter.refresh ( ); addEventHandler ( "onClientGUIClick", root, Inter.onEvent ); else removeEventHandler ( "onClientGUIClick", root, Inter.onEvent ); end end function Inter.onEvent ( ) if ( source == Inter.btn.close ) then Inter.open ( false ); elseif ( source == Inter.btn.refresh ) then Inter.refresh ( ); elseif ( source == Inter.grid.list ) then local row, _ = guiGridListGetSelectedItem ( Inter.grid.list ); Inter.btn.enable.enabled = ( ( row ~= -1 ) and ( guiGridListGetItemText( Inter.grid.list, row, 3 ) == "No" ) ); Inter.btn.disable.enabled = ( ( row ~= -1 ) and ( guiGridListGetItemText( Inter.grid.list, row, 3 ) == "Yes" ) ); elseif ( source == Inter.btn.enableAll or source == Inter.btn.disableAll ) then if ( localPlayer:getOccupiedVehicle ( ) ) then return outputChatBox ( "Please exit your vehicle before enabling or disabling mods", 255, 255, 0 ); end for i, v in pairs ( Downloader.Mods ) do Mods.SetModEnabled ( i, source == Inter.btn.enableAll ); end Inter.refresh ( ); elseif ( source == Inter.btn.enable or source == Inter.btn.disable ) then if ( localPlayer:getOccupiedVehicle ( ) ) then return outputChatBox ( "Please exit your vehicle before enabling or disabling mods", 255, 255, 0 ); end local row, _ = guiGridListGetSelectedItem ( Inter.grid.list ); if ( row == - 1 ) then return end Mods.SetModEnabled ( guiGridListGetItemText ( Inter.grid.list, row, 2 ), source == Inter.btn.enable ); Inter.refresh ( ); end --end end function Inter.refresh ( ) local _row, col = guiGridListGetSelectedItem ( Inter.grid.list ); guiGridListClear ( Inter.grid.list ); local t = Downloader.Mods; local skins = { } local vehs = { } local weaps = { } -- Loop the downloaded mods and seperate mod types for index, var in pairs ( t ) do local t = tostring ( var.type ):lower ( ); if ( t == "skins" ) then table.insert ( skins, var ) elseif ( t == "vehicles" ) then table.insert ( vehs, var ) elseif ( t == "weapons" ) then table.insert ( weaps, var ) end end guiGridListSetItemText ( Inter.grid.list, guiGridListAddRow ( Inter.grid.list ), 1, "Vehicle Mods", true, true ) for i, v in pairs ( vehs ) do local r, g, b = 0, 255, 0 -- Assume its downloaded and ready local enabled = v.enabled or false local status = "Ready"; if ( not enabled ) then r, g, b = 255, 0, 0 enabled = "No"; else enabled = "Yes"; end if ( not File.exists ( v.txd ) or not File.exists ( v.dff ) ) then status = "Downloading"; r, g, b = 255, 255, 0 end local row = guiGridListAddRow ( Inter.grid.list ); guiGridListSetItemText ( Inter.grid.list, row, 1, getVehicleNameFromModel ( v.replace ), false, false ); guiGridListSetItemText ( Inter.grid.list, row, 2, tostring ( v.name ), false, false ); guiGridListSetItemText ( Inter.grid.list, row, 3, tostring ( enabled ), false, false ); guiGridListSetItemText ( Inter.grid.list, row, 4, tostring ( status ), false, false ); for i = 1, 4 do guiGridListSetItemColor ( Inter.grid.list, row, i, r, g, b ); end if ( row == _row )then guiGridListSetSelectedItem ( Inter.grid.list, row, col ); triggerEvent ( "onClientGUIClick", Inter.grid.list ); end end guiGridListSetItemText ( Inter.grid.list, guiGridListAddRow ( Inter.grid.list ), 1, "Weapon Mods", true, true ) for i, v in pairs ( weaps ) do local r, g, b = 0, 255, 0 -- Assume its downloaded and ready local enabled = v.enabled or false local status = "Ready"; if ( not enabled ) then r, g, b = 255, 0, 0 enabled = "No"; else enabled = "Yes"; end if ( not File.exists ( v.txd ) or not File.exists ( v.dff ) ) then status = "Downloading"; r, g, b = 255, 255, 0 end local row = guiGridListAddRow ( Inter.grid.list ); guiGridListSetItemText ( Inter.grid.list, row, 1, engineGetModelNameFromID ( v.replace ) or tostring ( v.replace ), false, false ); guiGridListSetItemText ( Inter.grid.list, row, 2, tostring ( v.name ), false, false ); guiGridListSetItemText ( Inter.grid.list, row, 3, tostring ( enabled ), false, false ); guiGridListSetItemText ( Inter.grid.list, row, 4, tostring ( status ), false, false ); for i = 1, 4 do guiGridListSetItemColor ( Inter.grid.list, row, i, r, g, b ); end if ( row == _row )then guiGridListSetSelectedItem ( Inter.grid.list, row, col ); triggerEvent ( "onClientGUIClick", Inter.grid.list ); end end guiGridListSetItemText ( Inter.grid.list, guiGridListAddRow ( Inter.grid.list ), 1, "Skin Mods", true, true ) for i, v in pairs ( skins ) do local r, g, b = 0, 255, 0 -- Assume its downloaded and ready local enabled = v.enabled or false local status = "Ready"; if ( not enabled ) then r, g, b = 255, 0, 0 enabled = "No"; else enabled = "Yes"; end if ( not File.exists ( v.txd ) or not File.exists ( v.dff ) ) then status = "Downloading"; r, g, b = 255, 255, 0 end local row = guiGridListAddRow ( Inter.grid.list ); guiGridListSetItemText ( Inter.grid.list, row, 1, tostring ( v.replace ), false, false ); guiGridListSetItemText ( Inter.grid.list, row, 2, tostring ( v.name ), false, false ); guiGridListSetItemText ( Inter.grid.list, row, 3, tostring ( enabled ), false, false ); guiGridListSetItemText ( Inter.grid.list, row, 4, tostring ( status ), false, false ); for i = 1, 4 do guiGridListSetItemColor ( Inter.grid.list, row, i, r, g, b ); end if ( row == _row )then guiGridListSetSelectedItem ( Inter.grid.list, row, col ); triggerEvent ( "onClientGUIClick", Inter.grid.list ); end end end addCommandHandler ( "mods", function ( ) if ( not Downloader.gotResponse ) then outputChatBox ( "We're still waiting for the server to accept our request. Please wait", 255, 255, 0 ); return false; end Inter.open ( not Inter.window.visible ); end ); -- Don't store txd and dff files in the XML - Prevent hackers from changing file names Mods = { }; Mods.FromXML = { }; -- Mods Constructor function Mods:Mods ( ) Mods:PhraseXML ( ); if ( isTimer ( checkServerTimer ) ) then killTimer ( checkServerTimer ); end setTimer ( function ( ) -- Did the server have time to load the list?? Downloader:RequestList ( ); -- Get list from server end, 500, 1 ); end function Mods:PhraseXML ( ) -- Create the user cmods.xml for saving of enabled/disabled -- Create if it doesn't exist if ( not File.exists ( "@cmods.xml" ) ) then local t = File.new ( "@cmods.xml" ); t:write ( "<mods></mods>" ); t:close ( ); end -- Attempt to load XML file local xml = XML.load ( "@cmods.xml" ); -- if XML failed to load, delete it and try again if ( not xml ) then File.delete ( "@cmods.xml" ); Mods:Mods ( ); return end -- If it exists, loop the children and collect info for index, child in pairs ( xml.children ) do -- Is it a mod child? if ( child.name == "mod" ) then local name = child:getAttribute ( "name" ); local enabled = child:getAttribute ( "enabled" ); -- Do all of our attributes exist? if ( name and enabled ) then -- Was this already loaded? if ( not Mods.FromXML [ name ] ) then Mods.FromXML [ name ] = ( tostring ( enabled ):lower ( ) == "true" ); else child:destroy ( ); end else child:destroy ( ); end end end -- Save and unload xml file xmlSaveFile ( xml ); xmlUnloadFile ( xml ); end function Mods.SaveXML ( ) if ( File.exists ( "@cmods.xml" ) ) then File.delete ( "@cmods.xml" ); end local str= "<mods>\n <!-- It's suggested to not edit this file -->\n %s \n</mods>"; local _str = ""; for i, v in pairs ( Downloader.Mods ) do _str = _str .. "\n" .. string.format ( '<mod name="%s" enabled="%s" />', i, tostring ( v.enabled ) ); end local f = File.new ( "@cmods.xml" ); f:write ( str:format ( _str ) ); f:close ( ); end setTimer ( Mods.SaveXML, 5000000, 0 ); addEventHandler ( "onClientResourceStop", resourceRoot, Mods.SaveXML ); -- Mods:PhraseList -> Used to check mods list for enabled mods function Mods:PhraseList ( ) --Downloader.Mods = { } -- Loop through the list and find completed downloaded files for name, mod in pairs ( Downloader.Mods ) do local txd = mod.txd; local dff = mod.dff; local replace = mod.replace; Downloader.Mods [ name ].enabled = false; -- Check if the txd file is downloaded local bothExist = false; if ( File.exists ( tostring ( txd ) ) ) then -- if so, load it local temp = File( txd, true ); -- is it out-dated? doDelete = ( tostring ( md5 ( temp:read ( temp.size ) ) ):lower ( ) ~= tostring ( mod.txd_hash ):lower( ) ); temp:close ( ); -- if outdated, then delete if ( doDelete ) then File.delete ( txd ); outputDebugString ( txd.." was deleted - hash doesn't match with server" ); bothExist = false; else outputDebugString ( txd.." has been successfully listed" ); bothExist = true; end else outputDebugString ( tostring ( txd ).. " not present - beginning download" ); Downloader:AddDownload ( tostring ( txd ) ); end -- Check if the dff file is downloaded if ( File.exists ( tostring ( dff ) ) ) then -- if so, load it local temp = File( dff, true ); -- is it out-dated? doDelete = ( md5 ( temp:read ( temp.size ) ):lower() ~= mod.dff_hash:lower() ); temp:close ( ); -- if outdated, then delete if ( doDelete ) then File.delete ( dff ); outputDebugString ( dff.." was deleted - hash doesn't match with server" ); bothExist = false; else outputDebugString ( dff.." has been successfully listed" ); if ( bothExist ) then bothExist = true; end end else outputDebugString ( tostring ( dff ).. " not present - beginning download" ); Downloader:AddDownload ( tostring ( dff ) ); end if ( bothExist ) then --outputDebugString ( name.." - both files loaded. Enabled: "..tostring ( Mods.FromXML [ name ] ) ); if ( Mods.FromXML [ name ] ) then Mods.SetModEnabled ( name, true ); end end end end function Mods.SetModEnabled ( mod, enabled ) if ( not Downloader.Mods [ mod ] ) then return outputDebugString ( string.format ( "Attempted to enable mod '%s' - doesn't exist in Downloader.Mods", mod ), 255, 0, 0 ); end if ( ( enabled and Downloader.Mods [ mod ].enabled ) or ( not enabled and not Downloader.Mods [ mod ].enabled ) ) then -- check current state return false; -- cancel if is already current state end Downloader.Mods [ mod ].enabled = enabled; if ( enabled ) then if ( File.exists ( Downloader.Mods [ mod ].dff ) and File.exists ( Downloader.Mods [ mod ].txd ) ) then local txd = engineLoadTXD ( Downloader.Mods [ mod ].txd ) engineImportTXD ( txd, Downloader.Mods [ mod ].replace ) local dff = engineLoadDFF ( Downloader.Mods [ mod ].dff, 0 ) engineReplaceModel ( dff, Downloader.Mods [ mod ].replace ) end else engineRestoreModel ( Downloader.Mods [ mod ].replace ); end end --addEventHandler ( "onClientResourceStart", resourceRoot, Mods.Mods ); addEvent ( "ModLoader:OnServerReadyAccepts", true ); addEventHandler ( "ModLoader:OnServerReadyAccepts", root, Mods.Mods ); checkServerTimer = setTimer ( function ( ) outputDebugString ( "Sending server request" ); triggerServerEvent ( "ModDownloader:TestServerReadyForClient", localPlayer ); end, 2000, 0 ) these above are client files these are server side files: Loader = { } local mods = { } local isReady = false; --[[ Format: mods['New Mod Name'] = { name = "New Mod Name", dff = "file_to_dff.dff", txd = "file_to_txd.txd", replace = vehicle_replace_id, dff_hash = MD5_of_dff_file, txd_hash = MD5_of_txd_file } ]] -- Loader Constructor function Loader:Loader ( ) mods = { } if ( not ( File.exists ( "smods.xml" ) ) ) then -- File functions are a lot easier to use than XML functions -- smods.xml doesnt exist - create new local t = File.new ( "smods.xml" ); local str = [[ <mods> <!-- ADDING CUSTOM VEHICLES ----------------------------------------------------------------------------------- This is the mod list file. This file is used to get the modded files for the clients Add your mod by adding: <mod name="Modded Vehicle Name" txd="path to txd file" dff="path to dff file" replace="replace vehicle id" /> name: This is the name of the new vehicle, the name that the clients will see txd: This is the load path for the modded (don't include "mods/vehicles") skin txd file inside mods folder dff: This is the load path for the modded (don't include "mods/vehicles") skin dff file inside mods folder replace: The vehicle replace ID. Find GTA SA vehicle ids @ https://wiki.multitheftauto.com/wiki/Vehicle_IDs ----------------------------------------------------------------------------------- <vehicles> <!-- Examples (Won't work because you don't have the txd/dff files) <mod name="Alpha123" txd="alpha.txd" dff="alpha.dff" replace="602" /> </vehicles> <!-- ADDING CUSTOM SKINS ----------------------------------------------------------------------------------- This is the mod list file. This file is used to get the modded files for the clients Add your mod by adding: <mod name="Modded Skin Name" txd="path to txd file" dff="path to dff file" replace="replace skin id" /> name: This is the name of the new skin, the name that the clients will see txd: This is the load path for the modded (don't include "mods/skins") skin txd file inside mods folder dff: This is the load path for the modded (don't include "mods/skins") skin dff file inside mods folder replace: The skin replace ID. Find GTA SA skin ids @ https://wiki.sa-mp.com/wiki/Skins:All ----------------------------------------------------------------------------------- --> <skins> <!-- Examples (Won't work because you don't have the txd/dff files) <mod name="Kokoro Arsenal Clothes" txd="hfyri.txd" dff="hfyri.dff" replace="40" /> --> </skins> <!-- ADDING CUSTOM WEAPONS ----------------------------------------------------------------------------------- This is the mod list file. This file is used to get the modded files for the clients Add your mod by adding: <mod name="Modded Weapon Name" txd="path to txd file" dff="path to dff file" replace="replace weapon model" /> name: This is the name of the new weapon, the name that the clients will see txd: This is the load path for the modded (don't include "mods/weapons") weapon txd file inside mods folder dff: This is the load path for the modded (don't include "mods/weapons") weapon dff file inside mods folder replace: The weapon replace Model (NOT ID!!!!). Find GTA SA weapon models @ https://wiki.sa-mp.com/wiki/Weapons ----------------------------------------------------------------------------------- --> <weapons> <!-- Examples (Won't work because you don't have the txd/dff files) <mod name="Improved Fire Extinguisher" txd="366.txd" dff="366.dff" replace="366" /> --> </weapons> </mods> ]] t:write ( str ); t:close ( ); t = nil; outputDebugString ( "smods.xml wasn't detected, but has been created!" ); end local metaFiles = { } local meta = XML.load ( "meta.xml" ); for i, v in pairs ( meta.children ) do if ( v.name == "file" and v:getAttribute ( "src" ) ) then metaFiles [ v:getAttribute ( "src" ) ] = true; end end -- Load server-side mod list file (smods.xml) local xml = XML.load ( "smods.xml" ); -- Check to make sure the XML was successfully loaded, if not delete & retry if ( not xml ) then File.delete ( "smods.xml" ); Loader:Loader ( ); outputDebugString ( "smods.xml was unable to be loaded. Deleted file, retrying." ); return; end -- Loop all the "mod" children local changesMade = false; for _index, _childNode in pairs ( xml.children ) do for findex, childNode in pairs ( _childNode.children ) do local index = _index..":"..findex; local category = tostring ( childNode.parent.name ):lower(); -- Confirm it's a "mod" child if ( childNode.name == "mod" ) then -- Check if it has all the attributes local temp = { } temp.name = childNode:getAttribute ( "name" ); temp.txd = childNode:getAttribute ( "txd" ); temp.dff = childNode:getAttribute ( "dff" ); temp.replace = childNode:getAttribute ( "replace" ); temp.type = category; if ( temp.type == "skins" or temp.type == "vehicles" or temp.type == "weapons" ) then if ( temp.name and temp.txd and temp.dff and temp.replace ) then -- confirm txd file exists if ( File.exists ( "mods/" .. category .. "/" .. temp.txd ) ) then temp.txd = "mods/" .. category .."/".. temp.txd; -- confirm dff file exists if ( File.exists ( "mods/" .. category .. "/".. temp.dff ) ) then temp.dff = "mods/" .. category .."/".. temp.dff; -- confirm replace is an integer, and a valid vehicle model temp.replace = tonumber ( temp.replace ); if ( ( temp.type == "vehicles" and temp.replace and math.floor ( temp.replace ) == temp.replace and temp.replace >= 400 and temp.replace <= 611 ) or ( temp.type == "skins" and temp.replace and math.floor ( temp.replace ) == temp.replace and temp.replace >= 0 and temp.replace <= 311 ) or ( temp.type == "weapons" and temp.replace and math.floor ( temp.replace ) == temp.replace and temp.replace >= 321 and temp.replace <= 372 ) ) then -- Confirm there's actually a name if ( temp.name:gsub ( " ", "" ) ~= "" ) then -- Confirm name isn't already in use if ( not mods [ temp.name ] ) then -- all checks are OK -- Encrypt and add to mod list local tmp = File( temp.txd, true ); temp.txd_hash = md5 ( tmp:read ( tmp.size ) ); tmp:close ( ); local tmp = File( temp.dff, true ); temp.dff_hash = md5 ( tmp:read ( tmp.size ) ); tmp:close ( ); tmp = nil; if ( not metaFiles [ temp.txd ] ) then outputDebugString ( temp.txd.. " not found in meta -- adding now" ); local c = meta:createChild ( "file" ); c:setAttribute ( 'src', temp.txd ); c:setAttribute ( "download", "false" ); changesMade = true; end if ( not metaFiles [ temp.dff ] ) then outputDebugString ( temp.dff.. " not found in meta -- adding now" ); local c = meta:createChild ( "file" ); c:setAttribute ( 'src', temp.dff ); c:setAttribute ( "download", "false" ); changesMade = true; end outputDebugString ( "Successfully loaded mod #"..tostring(index).." - "..tostring ( temp.name ).. "!" ); mods [ temp.name ] = temp; else outputDebugString ( "Failed to load #"..tostring(index).." ("..tostring(temp.name)..") - Mod name already used" ); end else outputDebugString ( "Failed to load #"..tostring(index).." ("..tostring(temp.name)..") - Invalid name" ); end else if ( temp.type == "vehicles" ) then outputDebugString ( "Failed to load #"..tostring(index).." ("..tostring(temp.name)..") - replace must be an integer from 400-611" ); elseif ( temp.type == "skins" ) then outputDebugString ( "Failed to load #"..tostring(index).." ("..tostring(temp.name)..") - replace must be an integer from 0-311" ); elseif ( temp.type == "weapons" ) then outputDebugString ( "Failed to load #"..tostring(index).." ("..tostring(temp.name)..") - replace must be an integer from 331-371" ); end end else outputDebugString ( "Failed to load #"..tostring(index).." ("..tostring(temp.name)..") - dff file not found on server" ); end else outputDebugString ( "Failed to load #"..tostring(index).." ("..tostring(temp.name)..") - txd file not found on server" ); end else outputDebugString ( "Failed to load #"..tostring(index).." ("..tostring(temp.name)..") - not all attributes found" ); end else outputDebugString ( "Failed to load #"..tostring(index).." ("..tostring(temp.name)..") - Unknown mod type, valid: skins, vehicles, weapons" ); end end end end xmlSaveFile( meta ); xmlUnloadFile ( meta ); xmlSaveFile ( xml ); xmlUnloadFile ( xml ); if ( changesMade ) then outputDebugString ( "CHANGES HAVE BEEN MADE TO META.XML! RESTARTING RESOURCE...", 0, 255, 255, 255 ); restartResource ( getThisResource ( ) ); return; end isReady = true; end setTimer ( Loader.Loader, 2000, 1 ); -- Loader:HandleRequest -> Handles request of mod files from client -- Sends client new mod list function Loader:HandleRequest ( plr ) triggerClientEvent ( source, "ModDownloader:OnServerSendClientModList", source, mods ); end addEvent ( "ModDownloader:RequestFilesFromServer", true ); addEventHandler ( "ModDownloader:RequestFilesFromServer", root, Loader.HandleRequest ); --addEventHandler ( "onResourceStart", resourceRoot, Loader.Loader ); addEvent ( "ModDownloader:TestServerReadyForClient", true ); addEventHandler ( "ModDownloader:TestServerReadyForClient", root, function ( ) if ( not isReady ) then return; end -- Make sure we're ready for a connection triggerClientEvent ( source, "ModLoader:OnServerReadyAccepts", source ); end ); Quote Updater = { } function Updater.Notify ( msg ) outputDebugString ( msg ); end function Updater.Check ( ) Updater.Notify ( "Checking for Mod Downloader updates "); local called = callRemote("https://community.multitheftauto.com/mta/resources.php", function(_, version) if ( md5 ( tostring ( version ) ) ~= md5 ( getResourceInfo ( getThisResource(), "version" ) ) ) then Updater.Notify ( "====================================" ); Updater.Notify ( "= ModDownloader version doesn't match community" ); Updater.Notify ( "====================================" ); Updater.Notify ( "= Your version: ".. getResourceInfo ( getThisResource(), "version" ) ) Updater.Notify ( "= Current version: ".. version ) Updater.Notify ( "= View https://forum.multitheftauto.com/viewtopic.php?f=108&t=86587" ); Updater.Notify ( "====================================" ); end end, "version", "moddownloader" ) if not called then outputDebugString ( "FAILED TO CHECK VERSION UPDATE! PLEASE ALLOW ".. getResourceName(getThisResource()) .." ACCESS TO function.callRemote", 1 ); end end Updater.Check ( ); setTimer ( Updater.Check, 1000000, 0 ); I really would appreciate your support. I would be willing to pay a little as a sign of my gratitude for your work. Please help me. Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now