Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 05/05/20 in all areas

  1. CnC War Enterprises MTA: CnC Enterprises (Or CnC War Enterprises) is a server dedicated to bringing a proper first person shooter to Multi Theft Auto, replacing many of the core functionality in MTA with my own stupidly complex systems to better perform these tasks. In short, I've pretty much brought an entirely new game to MTA unlike any server seen before. Our main features : - Brand new weapon system with much more accurate sync - More realistic weapon handling - Brand new HUD and GUI for everything - More realistic sound system - Fully sync first person shooting system - Fully custom everything - Updated graphical systems Battle Creek - Blood Gulch - Discord Link mtasa://82.165.112.197:22003
    2 points
  2. After a worrying discussion on Discord last night regarding password storage and remember me functionality I've decided to write a tutorial on how it should be done. This guide assumes you are not using MTA's built in account system, but a custom one. Any code shown in this tutorial is purely for illustrative purposes, and is not finished code, you should use it as a guideline, not a solution. The following topics will be discussed in this tutorial: How to hash and salt passwords (register) How to validate a hashed password (login) How to add "remember-me" functionality How to offer password recovery How to migrate from an older hashing algorithm, to a newer one Using a password policy (Extra) How to handle database leaks (Extra) What even is hashing and salting? For the purpose of this tutorial we expect a database structure which is somewhat similar to this: How to hash and salt passwords When you have a user register on your service, that user expects of you to keep their password safe. Whilst it is generally bad practice to use the same password for multiple services there are many users that still do so. Because of this it's crucial that you save the user's passwords in a way that an attacker will be unable to find out the original password the user typed. This includes if they have full access to your database. In order to do this we do what is called "Password hashing" When a user registers, your server receives the user's intended username, (email) and password. Before you save that password to the database you have to hash and salt this, luckily MTA has a function that takes care of this. If you wish to know more about what exactly it does, there's more information at the end of this tutorial. In order to hash this password you use the passwordHash function. This function is relatively slow (by design), so it is highly recommended you pass a callback to this function, so your entire script doesn't wait for it to complete. https://wiki.multitheftauto.com/wiki/PasswordHash local mysqlHandle -- we're assuming this value is set somewhere else in code function register(username, email, password) local player = client passwordHash(password, "bcrypt", {}, function(hashedPassword) -- callback function for hashing the password local handle = dbExec(function(handle) -- callback function for storing the user in the database if (handle) then triggerClientEvent(player, "registrationSuccess") -- inform the user that registration was successful else triggerClientEvent(player, "registrationFailed") end end,mysqlHandle, "INSERT INTO users (email, username, password) VALUES (?, ?, ?)", email, username, hashedPassword) end) end addEvent("passwordTutorial:register", true) addEventHandler("passwordTutorial:register", getRootElement(), register) How to validate a hashed password Once you've saved the hashed pasword to your database you need to do a little bit of additional work when authenticating the user. Luckily MTA offers a passwordVerify() function, which is the counterpart of the previously discussed passwordHash(). What this function does it basically hashes the password in the same way, resulting in the same output hash. https://wiki.multitheftauto.com/wiki/passwordVerify In order to get the account the user is trying to log in to you have to do a query for an account which has the user submitted username, and of which the password matches through passwordVerify. PasswordVerify is also a relatively slow function, thus you should use a callback. function login(username, password) local player = client dbQuery(function (handle) -- callback for the query selecting the user by username local results = dbPoll(handle, -1) if (#results == 0) then triggerClientEvent(player, "loginFailed") return end passwordVerify(password, results[1].password, {}, function(matches) -- callback function for the password verify if (matches) then -- Do anything you wish with the database result to log the player in with the rest of your scripts triggerClientEvent(player, "loginSuccess") else triggerClientEvent(player, "loginFailed") end end) end, mysqlHandle, "SELECT * FROM users WHERE username = ?", username) end addEvent("passwordTutorial:login", true) addEventHandler("passwordTutorial:login", getRootElement(), login) How to add "remember me" functionality When users on your server log in, they often do not want to have to enter their username and password every time they want to log in. In order to satisfy this need you can implement a "remember me" function. What I've seen happen in the past, is people would store the user's password (encrypted) on the client. This is NOT safe, and should never be done! In order to properly use remember me functionality what you would do is upon login in, generate a random string. The longer the better. This random string is what we call an access token. You would then allow the user to log in with such an access token, preferably only once generating a new access token each time one is used. To implement this you would generate that token every time the user logs in, whilst they have "remember me" enabled. You will have to save this token in your database alongside your user. For extra security you could also store the user's serial alongside the access token, you can then validate that the access token is being used from the same device. https://wiki.multitheftauto.com/wiki/Filepath function login(username, password) -- This code should be put in the callback to the dbQuery function, but to keep the example clean that's not shown here if (rememberMe) then local token = generateRandomToken() dbExec(function() triggerClientEvent(player, "loginSuccess", token) end,mysqlHandle, "INSERT INTO access_tokens (user_id, token) VALUES (?, ?)", results[1].id, token) end end function rememberMeLogin(username, accessToken) -- this function handles a user's login attempt dbQuery(function(handle) local result = dbPoll(handle, -1) if (#result == 0) then triggerClientEvent(player, "loginFailed") else -- Do anything you wish with the database result to log the player in with the rest of your scripts triggerClientEvent(player, "loginSuccess") end end,mysqlHandle, "SELECT users.* FROM access_tokens JOIN users ON users.id = access_tokens.user_id WHERE users.username = ?", username) end addEvent("passwordTutorial:loginRememberMe", true) addEventHandler("passwordTutorial:loginRememberMe", getRootElement(), login) How to offer password recovery Offering password recovery requires a little bit more than just your MTA server. Generally password recovery is done with emails. So you would need access to an email server / service which you can use to send an email from an HTTP request. (Like you can do with fetchRemote()). When a user requests a password reset, have them enter the email you registered with. You then fetch a user from the database with this email address. You would then store a password recovery token for this user. This token, just like the remember me token, is a random string. Ideally, you would send the user a link with a password reset form that goes to a webpage where the user can reset their password. You could do this with an external service, like a webserver. Or you could use MTA's Resource web access for it, but if you do make sure you handle permissions properly for anything else that uses this. However another option would be to have the user copy paste the generated token from the email into you server's login window. Which of the two solutions you pick is up to you, my personal preference goes to the one with the link in the email. But in either case the server side logic is the same. When the user attempts to perform password recovery, verify that the token they give you belongs to a user, and then change the password to the newly requested password. Make sure you hash this password the same way you do in your login. function requestPasswordRecovery(email) dbQuery(function (handle)) local result = dbPoll(handle, -1) if (#result == 0) then triggerClientEvent(player, "passwordTutorial:passwordRecoveryRequestFailed") else local token = generateRandomToken() dbExec(mysqlHandle, "UPDATE user_data SET recovery_token = ?", token) -- mail the token to the user, mail implementation depends on the mail server/service you use triggerClientEvent(player, "passwordTutorial:passwordRecoveryRequestSuccess") end end, mysqlHandle, "SELECT * FROM users WHERE email = ?", email) end function recoverPassword(recoveryToken, password) dbQuery(function (handle) local result = dbPoll(handle, -1) if (#result == 0) then -- this is only valid if you have the user request password recovery from ingame triggerClientEvent(player, "passwordTutorial:passwordRecoveryFailed") else passwordHash(password, "bcrypt", {}, function(hashedPassword) -- callback function for hashing the password local handle = dbExec(function(handle) -- callback function for storing the new password in the database if (handle) then -- this is only valid if you have the user request password recovery from ingame triggerClientEvent(player, "passwordTutorial:passwordRecoverySuccess") -- inform the user that registration was successful else -- this is only valid if you have the user request password recovery from ingame triggerClientEvent(player, "passwordTutorial:passwordRecoveryFailed") end end,mysqlHandle, "UPDATE user_data SET password = ? WHERE recovery_token = ?", username, recoveryToken) end) end end, "SELECT * FROM users WHERE recovery_token = ?", recoveryToken) end Besides changing the password, it's important you also delete any access tokens that user might have if you're using remember me functionality. It is also good practice to make recovery tokens expiry after a certain amount of times, and not allow a recovery token to be created whilst one is already in prgoress. This prevents a user from sending a large number of emails from your service. How to migrate from an older hashing algorithm, to a newer one Maybe after reading this topic you realise that your password security is not what it should be. So you want to change your old password hashing / validation logic to the ones explained in this topic. And due to the nature that hashes can not be "unhashed", you can't simply migrate your passwords over. So in order to migrate the passwords what you have to do is when a user logs in, first validate their password with the old hashing algorithm. If this matches, then hash (and salt) it with your new hashing algorithm and save it in your database. Make sure to delete the old password otherwise your password security is not any better than before. Using a password policy Passwords policies are important to prevent your users from picking a password that is too easily cracked / brute forced. Many password policies come in the form of "Must have at least one capital letter, one digit and one number". But that discards that fact that the best way to make your password more difficult to crack, is making your password longer. So in the code snippet below is a function that measures the 'search space' of a password. The search space of a password is the amount of possible passwords there are with a certain combination of characters. In order to use this, you would have to set a minimum password search space when a user registers for an account. This minimum is up for you to set, but be reasonable, you shouldn't expect a user's password to be impossible to remember / create. I recomend playing with the function a bit to see what values you get out of it, and pick something you believe is sensible. function getPasswordSearchSpace(password) local lowerCase = password:find("%l") and 26 or 0 local upperCase = password:find("%u") and 26 or 0 local digits = password:find("%d") and 10 or 0 local symbols = password:find("%W") and 32 or 0 local length = password:len() return (lowerCase + upperCase + digits + symbols) ^ length end -- The below function calls are to indicate the difference in search space for a set of passwords print(getPasswordSearchSpace("a")) print(getPasswordSearchSpace("abc")) print(getPasswordSearchSpace("Abc")) print(getPasswordSearchSpace("Ab!")) print(getPasswordSearchSpace("Ab!0")) print(getPasswordSearchSpace("Mu#9A0h.")) print(getPasswordSearchSpace("This is a demonstration of how easy an incredibly strong password is to remember")) How to handle database leaks If you have reason to believe that your database has been leaked or otherwise compromised, it is important that your first course of action is removing any access tokens stored in your database. Once you have done that you have to inform your users. Whilst when properly hashed and salted it's extremely difficult / time consuming to find out a user's password it is still a possibilty. So you should inform your users of the breach, tell them that their passwords were properly hashed, and they do not need to fear for their passwords immediately. However you should suggest to your users that they change their password either way, just in case. What even is hashing and salting? Hashing has been brought up several times in this tutorial, whilst you do not need to know what it is / does, you might be interested in knowing regardless. I won't be going too far in depth as I simply do not have the knowledge, but the basic idea of hashing is this: When you hash anything, you turn it into a string of characters (or other value) that has no relation to the original input, other than when you hash the original input again, it will always generate the same hash. For example, when you hash the stirng 'banana' using the sha512 hashing algorithm, it will always yield the output: "F8E3183D38E6C51889582CB260AB825252F395B4AC8FB0E6B13E9A71F7C10A80D5301E4A949F2783CB0C20205F1D850F87045F4420AD2271C8FD5F0CD8944BE3" Now hashing can not be reverted, you can not "unhash" a hash, so in order to verify someone's password you hash it again, and see if the two hashes are the exact same. Now this is great, passwords are safely stored. However there is still more to do, salting. Salting is adding some random data to your password prior to hashing it. This prevents when two users (on the same service, or on others) have the same password, that their hashes are also the same. Meaning if one password is compromised, the other password is not. It is important that a salt is random for every user in your application, not one salt for your entire application. Now you might think we didn't do any salting in the code / tutorial above. This is not true, we just didn't do it ourselves. MTA's passwordHash function actually hashes the passwords and salts it, this salt is then stored in the output hash it self, just before the actual password hash. In the case of bcrypt it actually stores a little bit more info in the resulting hash, but you need not worry about that.
    1 point
  3. If you're having issues with models or are looking for help on how to achieve certain results, feel free to ask in here. Note: Please check the Guide section before asking questions in here. Frequently Asked Questions on GTA modding the FAQ is on 3DS Max, though can be applied for various app's Lighting and Shading #1 Why can't I change the smoothing of my model? Your model contains duplicate vertices - this is a typical issue within GTA importers. They tend to break the vertices/split the edges on import, requiring to be welded. View the spoiler for a potential fix. #2 My map model is overexposed in day and night time. Your model lacks vertex color and illumination respectively. The GTA engine uses vertex color information to define lighting which is baked into the model. View spoiler for a potential fix. #3 Why is my Infernus model so bright? GTA engine calculates brightness of vehicles based on map objects collision brightness (that it's standing on) and the vehicle surface properties. View the spoiler for a potential fix. #4 My striped Bullet has different brightness for primary and secondary colors. GTA engine uses different lighting techniques for vehicles than map objects. Some of which are specular lighting, which in short brings a fake highlight onto the vehicle surface, illuminating it. View spoiler for a potential fix. Modeling #5 Certain polygons are not visible ingame, but looks fine on 3D editor. GTA engine among most other game engines uses backface culling, which kills the faces that are not facing/are blocked by ones facing the camera. This procedure is done to save memory. View the spoiler for a potential fix. #6 Can I make scissor doors for my vehicle without requiring scripts? It is possible to modify how vehicle doors appear in their open phase. It involves changing the rotations of dummies and their children objects, the doors. View the spoiler for a potential method. #7 How does vehicle reflections and chrome work? GTA vehicles uses 2 UV channels; first for diffuse, second for env and chrome mapping. If the secondary UV channel is not unwrapped properly, the env/chrome will either not work or flashes too often. View the spoiler for a potential method. #8 I can see through my vehicle chassis when looking at the police decals, why is that? Materials that are responsible for alpha needs to be last in the multimaterial list. If this is not done, textures like police decals will not render parts of the vehicle behind the alpha. View the spoiler for a potential fix. #9 How do I make a vehicle paintable? GTA SA requires models to have a certain colorcoded material applied to the surface of vehicles that needs to be paintable. It also needs (optionally if using textures) a texture that is not black. As anything that isn't black will be. If parts of the texture is grey, the color ingame will look sort of dirty or old. View the spoiler for a method. Miscellaneous #10 I have imported des_sherrifsgn1.dff into 3ds and extracted the textures into a folder, but they aren't displayed. It is not enough to extract the images, you'll have to tell the program where your textures are stored for it to apply them on the model. View the spoiler for a potential solution. #11 I want to remove Wuzimu's glasses and export it to my game. How do I do this? You're going to need a GTA formats importer. I prefer Kam's vanilla tools for skins due to its decent support for bones and skinned models. View the spoiler for a potential method. #12 What file types are worth to know about? GTA has many, many file types, and a lot of them are not natively available in MTA unless you modify your server's anti-cheat system to allow locally custom data files etcetera. So if we're going with MTA friendly files, there are a few. View the spoiler. #13 Where do I find shared vehicle textures, and what's each their use? You can locate the .txd for shared textures in GTA SA dir\models\generic\vehicle.txd. It stores textures which are used for SA vehicle lights, lighting and many more textures, which are used across hundreds of vehicles. As these textures are found in your local files, none of them are required to be added to custom vehicle .txd files, making for potentially very low file sizes. View the spoiler for a full list. #14 I have downscaled my model, but in-game it remains the same size as before. If your model's scale values says something like 76,144, 76,144, 76,144, it will reset to 100, 100, 100 on export. To correct this, go to Utilities panel, click Reset xForm, Reset selected, then right click the modifier and collapse to. Now your model will have its new scale applied. #15 I have converted a Counterstrike map and turned the main mesh into a collision which is 250kb. I am getting invisible walls, why is that? GTA has a very low polycount limit in regards to collision models. Not to be confused with collision primitive models, which are spheres or boxes, but the CM itself. If it is above or around 5000 (needs additional sources...) polygons, issues will occur, such as invisible walls or as if there's a large box blocking the entire model off. Another culprit for collision issues is the pivot point and position that the collision is exported at. You need to set the collisions to 0, 0, 0 and pivot point needs to resemble that of the main model, otherwise they will not line up properly. #16 My character movement is bugging on custom modeled stairs. GTA III, VC and SA do not have support for advanced staircase collisions, and so they require a different approach, which is a planar ramp or slope if you will. This may not look very good when the character steps on the stairs, however it is the most performance and bug-less method around. **Please feel free to contribute to the FAQ by leaving a comment here or through PM. It will be greatly appreciated.** little note for colors #B8E0B6 #4A4A4A
    1 point
  4. بسم الله الرحمن الرحيم , function نكمل هسا بالجزء 2 عن الـ الجزء بسيط هذا بيكون . function setPedArmor ( theplayer , armor ) معلومات بسيطة : كلمة function , أو او تنقص حرف او تزيد حرف Function ما يصير تكتب أول حرف كبير إسم الفنكشن إلعب فيه زي ما بدك , أول حرف كبير , أول حرف صغير ما يأثر , حط الإسم اللي يناسبك - تنبيه : إسم الفنكشن لازم ما يكون فيه فراغ ( سبيس ) , مثال : function set Ped Armor ( plr , a ) - مسموح انك تضع _ في الإسم : function setPlayer_Armor ( p , a ) arguments ال : كلمة theplayer , ما يصير تسوي سبيس ( فراغ ) بين الكلمتين , لانه يسوي غلط مثلا تسوي هيك : the player خطأ × - arguments مسموح انك تضع _ في الـ function setPedArmor ( plr_ , _ar_mor ) argument الـ : - لا يجوز ان يكون رقم , لازم يكون كلمة . - لا يجوز ان يكون رمز , مثل : @ , % .. وكل الرموز الاخرى ما عدا (_) الشحطة إختبار : Q: صحح الخطأ في كل فرع من الأفرع التالية : [1]- fnction theFunCTIOn ( s , & ) [2] - function_ thefunction ( s , z ) [3] function nR_ ( x , _a _ ) نراكم في الجزء 3
    1 point
  5. use onPlayerWasted on the serverside wiht spawnPlayer
    1 point
  6. That's pretty simple as you may just add a if oldlvl + 1 > 30 then return end within addPlayerXp function. And for rewards using the event onPlayerLevelUp you add statement like if newlvl >= 1 then give him something. And for items at spawn you sould check his lvl on spawn and give the item depending on his level Sorry I'm on the phone so I can't do better
    1 point
  7. You misspelled the 'kilLDayZPlayer' event as you can see it's kilL and not kill (don't know why) local xpNeed = 100; -- E.g. 100 * lvl = XP you need to rank up! addEvent("onPlayerLevelUp", true); function addPlayerXp(player, xp) local acc = getPlayerAccount(player); local oldexp = getAccountData(acc, "exp") or 0; local oldlvl = getAccountData(acc, "lvl") or 1; local newlevel = oldlvl + 1; local newexp = oldexp + xp; setAccountData(acc, "exp", newexp); setElementData(player, "exp", newexp); if (newexp >= (oldlvl * xpNeed)) then local expleft = newexp - (oldlvl * xpNeed); -- added calculation for the exp that may remains after level up. outputChatBox("[Level-Up] Congratulations! New level "..newlevel.."!", player, 66, 134, 244); setAccountData(acc, "lvl", newlevel); setAccountData(acc, "exp", expleft); setElementData(player, "exp", expleft); setElementData(player, "lvl", newlevel); triggerEvent("onPlayerLevelUp", player, newlevel, oldlvl, oldexp, newexp); end end addEventHandler("onPlayerLogin", root, function() local acc = getPlayerAccount(source); if acc then setElementData(source, "lvl", getAccountData(acc, "lvl") or 0); setElementData(source, "exp", getAccountData(acc, "exp") or 0); end end); addEventHandler("onZombieGetsKilled", root, function(killer) if killer and getElementType(killer) == "player" then addPlayerXp(killer, 50); end end); addEventHandler("kilLDayZPlayer", root, function(killer) if (killer and killer ~= source and getElementType(killer) == "player") then addPlayerXp(killer, 50); end end); You're welcome
    1 point
  8. تمت اضافة مود كل معلومات السيرفر فوق شاشه و يمكنك نسخ رابط ديسكورد بحرف L طبعا نص يكبر و يصغر و بعدها يجي كلام ثاني و هكذا ----------- لوحة ارسل دم الاعبين معاك بالتيم
    1 point
  9. Try this one: local xpNeed = 100; -- E.g. 100 * lvl = XP you need to rank up! addEvent("onPlayerLevelUp", true); function addPlayerXp(player, xp) outputChatBox("3")-- test do not delete local acc = getPlayerAccount(player); local oldexp = getAccountData(acc, "exp") or 0; local oldlvl = getAccountData(acc, "lvl") or 1; local newlevel = oldlvl + 1; local newexp = oldexp + xp; setAccountData(acc, "exp", newexp); setElementData(player, "exp", newexp); if (newexp >= (oldlvl * xpNeed)) then local expleft = newexp - (oldlvl * xpNeed); -- added calculation for the exp that may remains after level up. outputChatBox("[Level-Up] Congratulations! New level "..newlevel.."!", player, 66, 134, 244); setAccountData(acc, "lvl", newlevel); setAccountData(acc, "exp", expleft); setElementData(player, "exp", expleft); setElementData(player, "lvl", newlevel); triggerEvent("onPlayerLevelUp", player, newlevel, oldlvl, oldexp, newexp); end end addEventHandler("onPlayerLogin", root, function() local acc = getPlayerAccount(source); if acc then setElementData(source, "lvl", getAccountData(acc, "lvl") or 0); setElementData(source, "exp", getAccountData(acc, "exp") or 0); end end); addEventHandler("onZombieGetsKilled", root, function(killer) if killer and getElementType(killer) == "player" then addPlayerXp(killer, 50); end end); addEventHandler("killDayZPlayer", root, function(killer) outputChatBox("1") -- test do not delete if (killer and killer ~= source and getElementType(killer) == "player") then outputChatBox("2")-- test do not delete addPlayerXp(killer, 50); end end); and make another video
    1 point
  10. Favor não exagere no uso de Caps Lock, e utilize o botão <> do fórum para postar o código. Você pode ver as regras do fórum em: [VÍDEO] Tudo sobre este fórum - Portuguese / Português - Multi Theft Auto: Forums
    1 point
  11. 1 point
  12. You tried my way and it didn't work? Also may I see the errors in /debugscript 3 ?
    1 point
  13. @SoManyTears Because the local declaration ensures that the value is deleted at the end of the function. if cities[city] then if not isElement(sound) then sound = playSound("ambiance.mp3",true) end elseif isElement(sound) then stopSound (sound) sound = nil end setTimer(change_weather, 1000, 0) -- 1 too 0
    1 point
  14. سيرفر جميل وعجبتني فكرة الديسكورد واسكنات الاسلحة وبالتوفيق
    1 point
  15. function executeCommandWithKey() executeCommandHandler("yourcommand", yourfunction) end bindKey("x", "down", executeCommandWithKey()
    1 point
  16. myZone = createColSphere (2490, -1668, 12.5, 25) function dimensionCheckerEnter(theElement, matchingDimension) if matchingDimension then bindKey("H", "down", dxGuiTeleport) end end addEventHandler ("onClientColShapeHit", myZone, dimensionCheckerEnter) function dimensionCheckerLeave(theElement, matchingDimension) if matchingDimension then unbindKey("H", "down", dxGuiTeleport) end end addEventHandler ("onClientColShapeLeave", myZone, dimensionCheckerLeave)
    1 point
  17. What if user will delete cache? Or will manipulate it on other way? Do not be afraid to use SQLite/MySQL. If you have lot of data, you can store it in one column as a JSON string aswell.
    1 point
  18. السلام عليكم ورحمة الله وبركاته اليوم بحمد الله تم افتتاح سيرفر شطاره الرسمي نوع السيرفر: هجولة - حياة واقعية بعض الصور من السيرفر مهمات السيرفر مهمة الجري مهمة الديربي مهمة الشوتر مهمة النجمة وجاري زيادة المهمات وظائف السيرفر مكافحة المخدرات مركز الشرطة سرقة اللاعبين مسعف السيرفر التنقيب عن النفط وجاري زيادة الوظائف باقي اشياء كثيره صراحه ماقدر اغطيها . ادخلو واكتشفوها بانفسكم واتمنى ان اعجبكم السيرفر ونتشرف في زيارتكم لنا . معلومات عن السيرفر ip: mtasa://51.255.215.208:22450 عدد الاعبين : 50 Q2 : اختصار السيرفر الادارة 1- OxeJEn / 2- # D7ooM / 3-YouSeF والسلام اخر الختام
    1 point
  19. You may try using colshapes https://wiki.multitheftauto.com/wiki/Element/Collision_shape
    1 point
  20. Temporary bans cannot be appealed. Your ban is longer than usual because you tried to develop cheats / mess with MTA by looking for something to make a custom cheat, and because it's not the first time. @whatarai061
    1 point
  21. السلام عليكم ورحمة الله وبركاته كثير أشوف ناس نفسها تتعلم برمجة و إلخ , ف ببدأ بدورة تعليم إن شاء الله .. إسم الدورة : عبادي كورس .. على بركة الله : لازم تعرف أشياء أساسية باللغة بشكل عام : [1] - function [2] - if [3] - then [4] - end - function : تستخدم لإنشاء وظيفة , شو هي الوظيفة أصلاً ؟ , كثير ما نلاحظ وظائف موجودة أساسيا باللعبة مثل : setElementData , setPlayerArmor , isPedDead مثلا الأولى تُستخدم لإعطاء لاعب داتا , والثانية لإعطاء لاعب درع , و الثانية لمعرفة اللاعب ميت أو لا .. هذي كلها تسمى وظائف ( فنكشن ) ء تم إنشاء هذه الوظائف ( function ) من خلال ال توضيح أكثر ؟ function setPlayerArmor هكذا تم إنشاء الوظيفة الي نشوفها فوق ^ , طيب هسا نجي نفكر بالمنطق , وظيفة تعطي درع للاعب ؟ طب مين اللاعب الي بدي اعطيه , هل رح اعطي نفسي , ولا اعطي لاعب عشوائي ! تسويها من الفنكشن نفسه , طب كيف ؟ arguments نحط بين قوسين كلمة تدل على اللاعب الي بدي اعطيه , ونسميها هذي الكلمة . - اهم شيء تكون بين قوسين , زيادة قوس او تنقيص قوس = خطا function setPlayerArmor ( player ) -? player طب عندي سؤال هسا , شرط احط كلمة - لا مو شرط , أي كلمة تدلك ع اللاعب الي رح تعطيه مستقبلاً , مثال : function setPlayerArmor ( p ) function setPlayerArmor ( x ) function setPlayerArmor ( z ) - ! arguments طب انا ما فهمت كلمة هسا بقولك كيف تفهمها , انا بدي اعطي لاعب محدد درع , رحت اخترت لاعب من القائمة عشان اعطيه درع , يدلني على اللاعب argument يدلني على اللاعب الي بدي اعطيه , اذا لازم الوظيفة يكون فيها argument رحت ع الوظيفة , ما فيها نجي نفكر هسا , طب انا حددت اللاعب الي بدي اعطيه الدرع , بس كم كمية الدرع الي بدي اعطيه اياها !!! - مثلا انا بدي اعطيه نص درع ( 50 ) بالمئة .. جديد خاص بكمية الدرع argument إذا لازم نسوي function setPlayerArmor ( x , armor ) جديد argument وهيك سوينا argument لازم نحط فاصلة بين كل . - argument ملاحظات بسيطة : لازم فاصلة بين كل - إسم خاص فيه , ممنوع تكرر الإسم argument لكل طبعاً هذي أساسيات , نراكم ب الجزء 2 ,, راجعو الجزء 1 مرتين وافهموه و احفظوهـ , اي اسئلة على الخاص ~ - المحترفين بالبرمجةة : عارف انه لسا مو مكمله , بس اهم شيء التاسيس ~~ * ملاحظة : لمعرفة قراءة الموضوع ، اذا كنت من التلفون حط وضعية سطح مكتب ، الافضل تقراها من اللابتوب او الكمبيوتر .. إختبار : [1] - أي الآتي خاطئ : A- function newfunction ( n ) B- function NewFunction ( z , c , s ) C- function Newfunction ( n ; F ) [2] - صحح الخطأ : A- function nEwFunction ( sop ,, o ) B- function newfunction n , b C- function news ( n , n ) D- function ( newFunction , n )
    1 point
  22. You misunderstand the using of the event system Try this, if this is not working reply me with the name of the gamemode you're using. local xpNeed = 100; -- E.g. 100 * lvl = XP you need to rank up! addEvent("onPlayerLevelUp", true); -- addEvent("onZombieGetsKilled", true) you do't need to add the event here as this event is already added in the dayz gamemode function addPlayerXp(player, xp) local acc = getPlayerAccount(player); local oldexp = getAccountData(acc, "exp") or 0; local oldlvl = getAccountData(acc, "lvl") or 1; local newlevel = oldlvl + 1; local newexp = oldexp + xp; setAccountData(acc, "exp", newexp); setElementData(player, "exp", newexp); if (newexp >= (oldlvl * xpNeed)) then outputChatBox("[Level-Up] Congratulations! New level "..newlevel.."!", player, 66, 134, 244); setAccountData(acc, "lvl", newlevel); setAccountData(acc, "exp", 0); setElementData(player, "exp", 0); setElementData(player, "lvl", newlevel); triggerEvent("onPlayerLevelUp", player, newlevel); end end addEventHandler("onPlayerLogin", root, function() local acc = getPlayerAccount(source); setElementData(source, "lvl", getAccountData(acc, "lvl") or 0); setElementData(source, "exp", getAccountData(acc, "exp") or 0); end); function rewardOnWasted ( killer ) -- local exp = getElementData(killer,"exp") -- local thelvl = getElementData(killer, "lvl") or 0; -- local theexp = getElementData(killer, "exp") or 0; -- if exp then --setElementData(killer,"exp",tonumber(getElementData(killer,"exp"))+50) if killer then addPlayerXp(killer, 50) --outputChatBox("Experience gained +50! total ".. tostring(((thelvl + 1) * xpNeed) - theexp -50).."!", killer ) --you normally don't need this as you have the client syde to show that end -- else -- setElementData(killer,"exp",50) -- end end --addEvent("onZombieGetsKilled", true) addEventHandler("onZombieGetsKilled", getRootElement(), rewardOnWasted) function rewardOnWasted1 ( killer1) --if there is a killer, and that killer is not the same person as whoever died if ( killer1 ) and ( killer1 ~= source ) and getElementType(killer1) == "player" then -- setElementData(killer1,"exp",tonumber(getElementData(killer1,"exp"))+50) addPlayerXp(killer1, 50) -- outputChatBox("Experience gained +50! total ".. tostring(((thelvl + 1) * xpNeed) - theexp -50)) else setElementData(killer1,"exp",50) end end -- addEvent("killDayZPlayer", true) same for this one! addEventHandler ( "killDayZPlayer", getRootElement(), rewardOnWasted1 ) --attach the rewardOnWasted function to the relevant event You may delete the comments as I let them there just so you know the mistakes you done. Greetings.
    0 points
×
×
  • Create New...