Jump to content

Modloader System by madex


yoya99

Recommended Posts

Posted

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

 

Posted
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

Posted

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) ....

Posted

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.

 

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...