Jump to content

Citizen

Moderators
  • Posts

    1,803
  • Joined

  • Last visited

  • Days Won

    8

Everything posted by Citizen

  1. close but it should be : function kivesz (source, command) EDIT: and as we don't use 'command' neither additional parameters we can shorten it to: function kivesz (source)
  2. Citizen

    dx List

    By only giving a part of your script you are forcing us to write code from the top of our head and by doing assumptions of what your code might do behind the scene, which is not cool because making dx user interfaces is already a not so easy task to do. That's why you only get me to help you That is what I managed to do. I couldn't test it of course but it seems correct by the look of it and I hope it will work at the 1st try but if not, give me as much details as you can about the problem you have: offs = 45 valid_key = {["mouse1"] = true} opened = false event = addEventHandler remove = removeEventHandler smX, smY = 1280, 1024 sX, sY = guiGetScreenSize( ) local ammunationWeapons = { {16,3000, 5}, {22,500, 30}, {23,600, 30}, {24,1200, 15}, {25,600, 15}, {26,800, 12}, {27,1000, 10}, {28,500, 60}, {29,2000, 90}, {30,3500, 120}, {31,4500, 150}, {32,300, 60}, {33,600, 20}, {34,5000, 10}, {46,800, 1}, } local selectedRow = nil -- Used to remember the selection local _renderedRowCache = {} -- Used to keep in memory the exact rendered position and size of each weapon row addEventHandler("onClientClick", root, function (button, state, cX, cY) if button ~= "left" and state ~= "up" then return end -- accepting only left mouse button and only when it's released for k, r in ipairs(_renderedRowCache) do -- looping through the cache to see in which row we clicked local x1, x2, y1, y2 = r.x1, r.x2, r.y1, r.y2 -- getting the boundaries of the row from the cache if cx > x1 and cx < c2 and cy > y1 and cy < y2 then -- if the click is inside the row boundaries selectedRow = k -- 'k' is here the index in the cache but it should match the index in ammunationWeapons list return -- no need to test the other rows end end end) setposition = 250 function dxDrawAmmuShop() if opened == true then return false end DxDrawBorderedRectangle(64, 186, 313, 411, tocolor(0, 0, 0, 150), false) dxDrawBorderedText("USC ~ Weapons Shop", 66, 185, 377, 212, tocolor(255, 255, 255, 255), 0.80, "bankgothic", "center", "center", false, false, false, false, false) dxDrawBorderedText("Weapons", 66, 212, 269, 236, tocolor(255, 255, 255, 255), 0.70, "bankgothic", "center", "center", false, false, false, false, false) dxDrawBorderedText("Prices", 269, 212, 377, 236, tocolor(255, 255, 255, 255), 0.70, "bankgothic", "center", "center", false, false, false, false, false) -- don't render it for every weapon there is _renderedRowCache = {} -- clear the cache for i, v in ipairs ( ammunationWeapons )do name = i if selectedRow == i then -- if the selected row is that current row then r2, g2, b2, size2 = 255, 255, 255, 1 -- force the selected style else r2, g2, b2, size2 = ItemsHower() -- do the math like before end local posY = 210+(i*offs) -- optimisation by calculating it once per row instead of 2 dxDrawText(getWeaponNameFromID(v[1]), 66, posY, 269, 270, tocolor(r2, g2, b2, 255),size2, "bankgothic", "left", "center", false, false, false, false, false) dxDrawText(tocomma(v[2]).."$", 269, posY, 377, 270, tocolor(255, 255, 255, 255), 0.70, "bankgothic", "center", "center", false, false, false, false, false) -- calculating the boundaries of the entire row (weapon name + price) local rX1, rY1 = 66, posY -- top left corner of the row local rX2, rY2 = 377, rY1+offs -- bottom right corner of the row table.insert(_renderedRowCache, {x1=rX1, y1=rY1, x2=rX2, y2=rY2}) -- cache it in memory end dxDrawFixedLine(64, 240, 377, 240, tocolor(255, 255, 255, 255), 3, false) dxDrawFixedLine(269, 212, 269, 597, tocolor(255, 255, 255, 255), 3, false) dxDrawFixedLine(64, 212, 377, 212, tocolor(255, 255, 255, 255), 3, false) r, g, b, size = buttonHover() r1, g1, b1, size1= closeHover() DxDrawBorderedRectangle(64, 603, 313, 32, tocolor(0, 0, 0, 200), false) dxDrawBorderedText("Purchase", 64, 602, 221, 635, tocolor(r, g, b, 255), size, "bankgothic", "center", "center", false, false, false, false, false) dxDrawBorderedText("Close", 221, 602, 378, 635, tocolor(r1, g1, b1, 255), size1, "bankgothic", "center", "center", false, false, false, false, false) if #ammunationWeapons ~= i then dxDrawFixedRectangle(64, setposition, 312, 23, tocolor(0, 0, 0, 100), false) end end You have to modify line 53 for the values r, g, b, size you want for the weapon name text if selected (probably the same style than when the cursor is over it but heh, you didn't give us the content of ItemsHower function. Oh and you should rename ItemsHower by ItemsHover to be clean). I also extracted the following line from the loop (now at line 46) as there is no reason for that line to be in that loop: dxDrawBorderedText("Prices", 269, 212, 377, 236, tocolor(255, 255, 255, 255), 0.70, "bankgothic", "center", "center", false, false, false, false, false) Waiting for your test feedbacks. Best regards, Citizen
  3. Assuming exports.USCsql:query can return an array of rows when appropriate, this should work: function getTransactionBankLog(player) local transactions = {} -- create a list if player then local results = exports.USCsql:query( "SELECT * FROM bank_transaction WHERE accName = ?", getAccountName(getPlayerAccount(player))) if results then for transaction, i in ipairs(transactions) do -- loop the results if transaction and transaction['log'] and transaction['date'] then table.insert(transactions, {tran = transaction['log'], date = transaction['date']}) -- filling the list from each result end end end end return transactions -- return the list end You should be able to use it like this: local transactions = getTransactionBankLog(somePlayerElement) for transaction, i in ipairs(transactions) do outputChatBox("#"..i.." -> tran: "..tostring(transaction.tran)..", date: "..tostring(transaction.date)) end
  4. You might want to get a fallback value like "Guest" if the getElementData returns false: local admin = getElementData(getLocalPlayer(), "PlayerACL") or "Guest"
  5. Bonjour, Je pense sincèrement que vous aller avoir des difficultés à trouver un développeur disponible. En général les développeurs LUA compétents décident de travailler sur leurs propres projets. En plus de devoir être disponible, le développeur devra accepter moralement de travailler sur un gamemode volé ce qui rajoute une difficulté supplémentaire dans votre recherche. Cordialement, Citizen
  6. @LopSided_ You are providing incomplete chunks of reply which probably makes the original poster confused if he can't follow your logic (I understood what you were trying to do but it's incorrect as there should be one (and only one) line per row (1 row = 1 tent; but each tent can have 0 or more "itens" (items I guess, might be a typo)). For an easy solution, build key-value based array where the key will be the "itens" name and the value will be the quantity of that itens you get with the getElementData. Once the array is built, use the toJSON function to convert that array into a string. local tentItensTable = { {"Assault Rifle"}, {"Motorcycle"}, } local itens = {} for i, data in ipairs(tentItensTable) do local itenName = data[1] -- the 'iten' name local itenQuantity = getElementData(thecol, itenName) or 0 -- the 'iten' quantity (0 if 'false') table.insert(itens, { name = itenName, quantity = itenQuantity }) -- adding the 'iten' datas in the list end --[[ Here 'itens' is like a table with 2 columns that should look like this (for example): { { name = "Assault Riffle", quantity = 63 }, { name = "Motorcycle", quantity = 0 } } But now as you can't save complex types (like arrays and tables) directly, you have to convert it into a simple string using the toJSON function: --]] local itensJson = toJSON(itens) --[[ saving line --]] dbExec(thedatabase, "INSERT INTO bau_obj VALUES (?,?,?,?,?,?,?,?,?)", numeros, modelo, x, y, z, rx, ry, rz, itensJson) --[[ saving line --]] And to load the itens from database do it like this: ---- Loading the itens back somewhere else ---- local itensJson = REPLACE_ME -- Do your thing to get the 'itens' column value as string from the database in that variable -- Then convert the Json string back into our table of itens like before the save using fromJSON function: local itens = fromJSON(itensJson) -- Loop to read all itens in that tent for i, data in ipairs(itens) do local itenName = data["name"] -- the 'iten' name local itenQuantity = data["quantity"] -- the 'iten' quantity (0 if nil/false) setElementData(thecol, itenName, itenQuantity) end But for a clean/not dirty solution as above, you should use another table to only save the 'itens' with an extra column like 'bau_obj_numeros' that will store the value of the bau_obj it is related to: bau_obj table: numeros | modelo | x | y | z | rx | ry | rz 1 | 123 | 0 | 0 | 0 | 0 | 0 | 0 <-- tent 1 2 | 123 | 9 | 9 | 0 | 0 | 0 | 0 <-- tent 2 bau_obj_itens table: bau_obj_numeros | name | quantity 1 | Assault Riffle | 54 <-- tent 1 1 | Motorcycle | 1 <-- tent 1 2 | Assault Riffle | 180 <-- tent 2 2 | Motorcycle | 0 <-- tent 2 Here tent 1 has: - 54 ammos of Assault Riffle - 1 Motorcycle And tent 2 has: - 180 ammos of Assault Riffle - 0 Motorcycle See one-to-many relationship. I hope it makes sense for you. It will require more modifications of your script but that's a standard thing for storing a list for a given row in a database. Remember this: If a column needs to store a list of another thing, then create another table for that other thing. Best regards, Citizen
  7. Bonsoir CNT|BYEBYE, J'ai déplacé votre question car elle ne concernait pas le problème auquel vous avez répondu à l'origine. Pour le saut en vélo, la commande se nomme Vehicle secondary fire En revanche il n'est pas possible de sauter en voiture (sauf sur des serveurs scriptés), qu'entends-tu par là ?
  8. Ah oui nan, en réalité les erreurs que vous m'avez collées sont des erreurs produites par votre ressource huds et non pas le panel. Stoppez cette ressource et essayez de voir si le problème du panel disparaît. Sinon retournez voir votre clientscript.log et cherchez une erreur concernant votre panel. La "véritable" erreur a dû être noyée dans les logs parce que la ressource est en train de spammer les logs (juste pour info, le bug de la ressource huds se trouve dans un onClientRender (ou onClientPreRender) donc si votre jeu est à 60fps ça spam 60 erreurs par seconde (et 30fois par seconde pour 30fps).
  9. Et du coup peut on voir le contenu de client.lua ?
  10. Bonsoir, tout d'abord j'aimerais juste que vous réalisiez le manque d'information que vous nous avez fourni. L'écran noir signifie qu'il y a une erreur dans un des fichiers client du panel de login car c'est côté client que le code est censé initialiser la caméra. Pour afficher les erreurs du côté client, il faut utiliser le système de login interne du serveur avec la commande /login <user> <password> Il faut que tu sois dans le groupe Admin dans l'acl.xml pour ensuite pouvoir utiliser la commande /debugscript 3 Une autre méthode est de se rendre dans le dossier d'installation de MTA puis de rentrer ensuite dans le dossier MTA et enfin d'ouvrir le fichier clientscript.log Colle nous ensuite les erreurs que tu trouveras. Pouvez-vous également nous fournir le lien vers le panel de login utilisé ? Merci d'avance. Citizen
  11. Yeah I know right, I asked him to run a antivir scan at the same time to remove that virus. I didn't want to promote the lavasoft products I don't know of. I didn't think about that potential problem (not being able to start regedit again) even though it does make sense. What would you recommend to do for a proper, safe and complete fix ? (This could be an entry for the FAQ ?)
  12. @Dutchman101Happened to this guy as well: https://forum.multitheftauto.com/topic/90495-quand-je-lance-mta/ The posts are in french but he had the exact same problem with the exact same cause. He fixed it by modifying the registry key back to default value as suggested in the lavasoft page linked above. Thanks for the feedback Dutchman101.
  13. D'après ce post, il est possible que ça soit à cause d'un virus sur ton ordinateur: https://forum.multitheftauto.com/topic/90196-cl33-error-mtasa/#comment-819400 Pour vérifier si tu as été infecté par ce même virus, vérifies dans ton registre que tu as les même valeurs que moi pour HKEY_CLASSES_ROOT\exefile\shell\open\command Si dans la clé "(par défaut)" tu as %WinDir%\svchost.com "%1" %* au lieu de "%1" %*, c'est que tu es infecté. Modifie la valeur à sa valeur normale et lance un scan anti-virus. Dans quel dossier se trouve ton Multi Theft Auto.exe ?
  14. Bonsoir, Essaye de renommer ton "MULTIT~1.exe" en "Multi Theft Auto.exe" et réessaye de le lancer. Cordialement, Citizen
  15. Bah il y a ce forum et gtaonline.fr, les deux sont autant actifs l'un l'autre. Personnellement je ne vois pas comment un 3ème endroit fonctionnerait mieux.
  16. Bonsoir Jaber, Je n'ai pas encore eu l'occasion de développer un module sur MTA mais oui ils ont bien un SDK C++: https://wiki.multitheftauto.com/wiki/Modules Et tu trouveras des exemples de modules avec leurs codes sources ici: https://github.com/multitheftauto/multitheftauto-modules En espérant t'avoir été un peu utile Cordialement, Citizen
  17. J'en n'ai pas la moindre idée pour être honnête
  18. A mon avis ce n'est pas le bon endroit pour faire un sondage pour la communauté française. Il doit y avoir un maximum de 5 personnes qui suivent (même de loin) cette section et en plus, c'est des devs (qui, en général, ne recherchent pas de serveurs pour jouer mais là je parle peut être que pour moi).
  19. Voilà ce que tu aurais dû avoir en copiant collant ma correction: function createPanelVIP() Ventana = guiCreateWindow(389, 179, 507, 366, "Premium of bW' Clan Tactics Training Server.", false) guiWindowSetSizable(Ventana, false) guiSetAlpha(Ventana, 1.00) Info = guiCreateMemo(11, 27, 486, 92, "♦Premium Account♦\n ¤ Price: 3$/Lifetime", false, Ventana) guiMemoSetReadOnly(Info, true) Boton1 = guiCreateButton(17, 137, 101, 46, "Crossbow", false, Ventana) guiSetProperty(Boton1, "NormalTextColour", "FF05FC00") Boton2 = guiCreateButton(201, 137, 101, 46, "Desert Eagle Gold", false, Ventana) guiSetProperty(Boton2, "NormalTextColour", "FF05FC00") Boton3 = guiCreateButton(386, 137, 101, 46, "PKM(25HP/Bullet)", false, Ventana) guiSetProperty(Boton3, "NormalTextColour", "FF05FC00") Boton4 = guiCreateButton(201, 259, 101, 46, "+200 HP", false, Ventana) guiSetProperty(Boton1, "NormalTextColour", "FF05FC00") Boton5 = guiCreateButton(17, 259, 101, 46, "Shotgun Power(25HP/Bullet)", false, Ventana) guiSetProperty(Boton1, "NormalTextColour", "FF05FC00") Skin = guiCreateButton(386, 259, 101, 46, "Skin Premium", false, Ventana) guiSetProperty(Skin, "NormalTextColour", "FFFEE900") Boton6 = guiCreateButton(17, 198, 101, 46, "USAS-12 Gold", false, Ventana) guiSetProperty(Skin, "NormalTextColour", "FFFEE900") cerrar = guiCreateButton(10, 341, 487, 15, "X", false, Ventana) guiSetFont(cerrar, "default-bold-small") guiSetProperty(cerrar, "NormalTextColour", "FFFF0000") addEventHandler ("onClientGUIClick", Boton1, Pack1, false) addEventHandler ("onClientGUIClick", Boton2, Pack2, false) addEventHandler ("onClientGUIClick", Boton3, Pack3, false) addEventHandler ("onClientGUIClick", Boton4, Heal, false) addEventHandler ("onClientGUIClick", Boton5, Pack4, false) addEventHandler ("onClientGUIClick", Skin, skinwe, false) addEventHandler ("onClientGUIClick", Boton6, Pack5, false) addEventHandler ("onClientGUIClick", cerrar, exit, false) guiSetVisible(Ventana, false) -- on le cache, prêt à être affiché quand on voudra end addEventHandler("onClientResourceStart", resourceRoot, createPanelVIP) -- on crée au démarrage -------------------------------------------------------------------------- function Pack1 () showCursor (true) triggerServerEvent ( "Paquete1", getLocalPlayer() ) end -------------------------------------------------------------------------- function Pack2() showCursor (true) triggerServerEvent ( "Paquete2", getLocalPlayer() ) end -------------------------------------------------------------------------- function Pack3() showCursor (true) triggerServerEvent ( "Paquete3", getLocalPlayer() ) end -------------------------------------------------------------------------- function Pack4() showCursor (true) triggerServerEvent ( "Paquete4", getLocalPlayer() ) end -------------------------------------------------------------------------- function Heal() showCursor (true) triggerServerEvent ( "HealthVIP", getLocalPlayer() ) end -------------------------------------------------------------------------- function skinwe() showCursor (true) triggerServerEvent ( "SkinFuncional", getLocalPlayer() ) end -------------------------------------------------------------------------- function Pack5() showCursor (true) triggerServerEvent ( "Paquete5", getLocalPlayer() ) end -------------------------------------------------------------------------- function PanelVIP() showCursor (true) guiSetVisible (Ventana, true) end addEvent( "GUIVIP", true ) addEventHandler("GUIVIP", root, PanelVIP) -------------------------------------------------------------------------- function exit() showCursor (false) guiSetVisible (Ventana, false) -- On veut réellement cacher le panel end addEvent( "GUIVIP", true ) (Je viens également de corriger le false qui aurait dû être à true ligne 78) C'est la version complète de ton fichier, comme ça tu pourras pas faire d'erreur de copier/coller ! (Ta liste de warnings indiquait que les fonctions Pack1, Pack2, Pack3, Pack4, Pack5, skinwe, et Heal n'existe pas au moment du addEventHandler, ne les auraient tu pas supprimés en copiant collant mon code ? ...)
  20. Récapitulons: 1 - Je te t'ai passé une version corrigée (et expliquée) de ton code client que tu n'avais plus qu'à copier coller 2 - Tu en copies une partie seulement en cassant le code corrigé 3 - Tu viens me demander de corriger à nouveau le code. Je vois pas comment on va pouvoir s'en sortir si tu fonctionne comme ça A part te recoller la même correction, je ne peux rien faire d'autre. Reprends le code de mon post précédent.
  21. Bonsoir RoRo76, Ton problème est que tu n'as pas séparer l'action de créer le panel vip (les guiCreate...) de l'action d'afficher le panel. Il faut les séparer pour avoir un meilleur contrôle: Créer le panel - Fonction à part Afficher le panel - Fonction panelVIP() Cacher le panel - Fonction exit() Tu noteras l'utilisation du verbe cacher plutôt que détruire (le panel) car c'est plus rapide de le créer une seule fois à la connexion puis de le montrer et le cacher plutôt que de le créer puis le détruire à chaque fois (On peut en effet détruire le panel afin qu'il ne prenne plus de place en mémoire via un destroyElement sur ta window). Voilà donc la solution à ton problème en séparant la création et l'affichage: client (je n'ai remit que les fonctions que j'ai modifiées, garde bien le reste): function createPanelVIP() Ventana = guiCreateWindow(389, 179, 507, 366, "Premium of bW' Clan Tactics Training Server.", false) guiWindowSetSizable(Ventana, false) guiSetAlpha(Ventana, 1.00) Info = guiCreateMemo(11, 27, 486, 92, "♦Premium Account♦\n ¤ Price: 3$/Lifetime", false, Ventana) guiMemoSetReadOnly(Info, true) Boton1 = guiCreateButton(17, 137, 101, 46, "Crossbow", false, Ventana) guiSetProperty(Boton1, "NormalTextColour", "FF05FC00") Boton2 = guiCreateButton(201, 137, 101, 46, "Desert Eagle Gold", false, Ventana) guiSetProperty(Boton2, "NormalTextColour", "FF05FC00") Boton3 = guiCreateButton(386, 137, 101, 46, "PKM(25HP/Bullet)", false, Ventana) guiSetProperty(Boton3, "NormalTextColour", "FF05FC00") Boton4 = guiCreateButton(201, 259, 101, 46, "+200 HP", false, Ventana) guiSetProperty(Boton1, "NormalTextColour", "FF05FC00") Boton5 = guiCreateButton(17, 259, 101, 46, "Shotgun Power(25HP/Bullet)", false, Ventana) guiSetProperty(Boton1, "NormalTextColour", "FF05FC00") Skin = guiCreateButton(386, 259, 101, 46, "Skin Premium", false, Ventana) guiSetProperty(Skin, "NormalTextColour", "FFFEE900") Boton6 = guiCreateButton(17, 198, 101, 46, "USAS-12 Gold", false, Ventana) guiSetProperty(Skin, "NormalTextColour", "FFFEE900") cerrar = guiCreateButton(10, 341, 487, 15, "X", false, Ventana) guiSetFont(cerrar, "default-bold-small") guiSetProperty(cerrar, "NormalTextColour", "FFFF0000") addEventHandler ("onClientGUIClick", Boton1, Pack1, false) addEventHandler ("onClientGUIClick", Boton2, Pack2, false) addEventHandler ("onClientGUIClick", Boton3, Pack3, false) addEventHandler ("onClientGUIClick", Boton4, Heal, false) addEventHandler ("onClientGUIClick", Boton5, Pack4, false) addEventHandler ("onClientGUIClick", Skin, skinwe, false) addEventHandler ("onClientGUIClick", Boton6, Pack5, false) addEventHandler ("onClientGUIClick", cerrar, exit, false) guiSetVisible(Ventana, false) -- on le cache, prêt à être affiché quand on voudra end addEventHandler("onClientResourceStart", resourceRoot, createPanelVIP) -- on crée au démarrage function PanelVIP() showCursor (true) guiSetVisible (Ventana, false) -- On affiche le panel end addEvent( "GUIVIP", true ) addEventHandler("GUIVIP", root, PanelVIP) function exit() showCursor (false) guiSetVisible (Ventana, false) -- On veut réellement cacher le panel end Ton problème sera résolu avec ça. Cordialement, Citizen
  22. You should also send the sound variable with the triggers so they (the clients) will all play the exact same sound.
  23. Ce que le wiki précise: Vérifie donc que tu ne sois pas dans l'un de ces deux cas.D'après ton code, tu souhaites faire jouer une animation spécifique à un joueur qui se prends une balle dans la tête. Le problème c'est que dès l'instant où ce joueur est indiqué comme mort (avec toutes les exécutions de onPlayerWasted terminées), il n'est plus possible (sauf erreur de ma part) de faire jouer des animations à ce joueur (réduit à l'état de cadavre quoi). A mon avis, il est préférable que tu te places du côté client afin d'annuler le onClientPedWasted via un cancelEvent() si bodypart == 9 tu lui fais ensuite jouer ton animation via ton setPedAnimation et tu termines par le tuer avec les informations d'origine via un killPed(source, attacker, weapon, bodypart, sthealth) en server-side (ce qui nécessite donc un triggerServerEvent). Note à part: quand tu demandes de l'aide pour corriger un script qui ne fonctionne pas, il faudrait donner un minimum de détail comme par exemple ta méthode de test (comment tu t'y prends pour tester ton script), les différentes erreurs dans les logs /debugscript 3 (s'il n'y en a pas, le préciser quand même) et enfin ce qu'il se passe sur ton écran (ex: "après lui avoir mit un headshot, il ne bronche pas" ou "après lui avoir mit un headshot, il meurt comme une merde par terre" ). Plus tu donnes d'informations, plus ça sera facile pour nous pour essayer de deviner le problème et donc la ou les solutions possibles. Essaye-donc la solution que je te propose et reviens vers nous avec le résultat de ton test, la manière pour tester et s'il y a des erreurs ou non (et ta nouvelle version du script aussi ). A oui et savoir aussi si j'ai bien compris ce que tu voulais faire et sinon me l'expliquer précisément. Cordialement, Citizen
  24. Ok impeccable Wumbaloo, Une fois qu'on comprends comment utiliser la bible le wiki, on devient beaucoup plus autonome et on apprends plus rapidement le reste. Le wiki c'est vraiment le site de référence que tu vas utiliser quasiment tout le temps quand tu vas coder tes scripts/gamemodes. Tu ne pourras plus t'en passer. Personnellement j'ai également une version offline toujours sous la main, comme ça si je suis en panne d'internet, ou que je suis en week-end/vacance dans un lieu sans internet, je peux toujours coder mes scripts Version offline (Dernière version par un membre): https://forum.multitheftauto.com/viewtopic.php?p=827764#p827764 Sinon tu peux utiliser HTTrack qui permet de copier intégralement un site (les parties publiques évidemment) et tu lui donnes l'url du wiki (https://wiki.multitheftauto.com/wiki/Main_Page). Le processus est long, surtout si tu as un mauvais débit internet. Celui que je t'ai filé plus haut devrait être suffisamment récent pour l'utiliser.
×
×
  • Create New...