-
Posts
822 -
Joined
-
Last visited
-
Days Won
86
Everything posted by The_GTA
-
You might be using a faulty MD5 hasher that treats line-endings differently (the COPY & PASTE process adds or removes CRLF and turns it into LF only, etc). For that reason it is important that you use the MTA provided md5 function instead of random online MD5 hashing services. You can easily modify the above code like the following to obtain the MTA generated MD5 string: ... local fcontent_md5 = md5(fcontent); if not (fcontent_md5 == md5_of_license) then error("FATAL ERROR: LICENSE file has changed! (MD5 found " .. tostring(fcontent_md5) .. ")"); end end ... This way the error message will contain the expected MD5 value. How about you try adjusting the code and setting the constant to the one from the new error message? HINT: the expected MD5 is EE519C0C252F9064053A7354A595D416
-
You have used the following MD5 checksum: but MTAs md5 function does return an upper-case md5 string, thus you should turn it into... Does that fix your problem? HINT: you can use the string.upper Lua function to turn a lower-case string to upper-case.
-
I think you are talking about plausible self protection logic in resources. I recommend you to compile the scripts which come with such protective steps. You can prevent the loading of a script under a certain condition by putting the check at the very top of the script, above everything else. For example, let's check for the existence of a file called "LICENSE". do local doesLicenseFileExist = fileExists("LICENSE"); if not (doesLicenseFileExist) then error("FATAL ERROR: LICENSE file missing!"); end -- TODO: calculate the MD5 of the LICENSE file and put it here as constant. local md5_of_license = string.toupper(""); local fh = fileOpen("LICENSE"); if not (fh) then error("FATAL ERROR: failed to open LICENSE file for checksum verification!"); end local fcontent = fileRead(fh, fileGetSize(fh)); fileClose(fh); local fcontent_md5 = md5(fcontent); if not (fcontent_md5 == md5_of_license) then error("FATAL ERROR: LICENSE file has changed! (MD5 found " .. fcontent_md5 .. ", expected " .. md5_of_license .. ")"); end end ... By using checksum verification you leave open a small window of chance that the attacker does modify your license in such a way that he created a different LICENSE file with the same hash as your original. But doing so should create a LICENSE file which does not feasibly originate from you so it is easy to argument your way out of it in a trial. The attacker could hijack the fileOpen, fileRead, fileExists, fileGetSize, fileClose and md5 functions by providing own implementations. This hijack would not be detectible and would circumvent your protection. That is why there is no perfect protection but putting these steps does present the argument that you want your code protected which is enough in a trial.
-
Hello amirmahdi, this is done in two simple steps. (serverside) First we calculate the nearest vehicle of the player. This can be done by getting all vehicles on the server and using the distance metric to find the vehicle with the smallest distance and return it. local function findClosestVehicle(elem) local vehicles = getElementsByType("vehicle"); local elem_x, elem_y, elem_z = getElementPosition(elem); local closest_veh = false; local closest_dist = false; for m,veh in ipairs(vehicles) do local veh_x, veh_y, veh_z = getElementPosition(veh); local dist = getDistanceBetweenPoints3D(elem_x, elem_y, elem_z, veh_x, veh_y, veh_z); if not (closest_dist) or (closest_dist > dist) then closest_dist = dist; closest_veh = veh; end end return closest_veh; end Next we create a command handler "rscar" which uses our new function to respawn the closest vehicle. addCommandHandler("rscar", function(player) local veh = findClosestVehicle(player); if not (veh) then outputChatBox("could not find close vehicle", player); return; end -- TODO: use respawnVehicle to place the vehicle on the map again. end ); Good luck!
-
Try setting the clip and wordBreak parameters of dxDrawText to true. They are false by default.
-
Really cool find!
-
I know that it is a bad move to voice-out about bugs without evidence, but a similar-sounding spurious issue has occured to me on a LAN server with low ping where we played with three people but one person had the race gamemode fail to load. The result was that the person spawned outside of the car but still had GTA SA vehicle radio play on-foot. I wonder if this is due to the fact that UDP is a terrible networking protocol for a reliable game experience or that there are hidden game-up-to-date issues.
-
I personally appreciate your passion for the GTA franchise related to multiplayer gaming. People like you are big examples of engineering your ideas into reality. Without testing your promoted game installation, just by judging the download size I see that you are packing a lot of content! We as a community surely love people who put their time and passion into creating new content. I am not sure how your content lays out and how much of it is of sensitive nature. But I sure hope that you have taken the necessary protections and in turn act as a good example for the russian GTA modding communities. Sometimes you guys surely have a funny way of treating other people's contents! ?
-
You're welcome! Working with the GPU is very complicated because it is a piece of hardware that has been incrementally created. A lot of things that seem intuitive will lead you to annoying & strong drawbacks, most likely due to aging & limited API design (Direct3D9). That is why it is important to get support on our forums whenever your drawing code does not work how you imagine it.
-
I have received your resource files for full evaluation and have detected an alpha-based image configuration combined with append-layer based shader attachment. Based on the provided files, here is my defect report: By creating and attaching multiple shaders onto the same "head_diff_000_a_whi" texture of the player model you are inducing depth-fighting between the bart and the face textures. It looks like a coding error in your script due to COPY & PASTE. In order to focus your eyes for critical reading, take a look at line 348 of example.lua: engineApplyShaderToWorldTexture(shader,clothes_ID[7]["face"][1],thePlayer, true) In this line you are using the "face" texture. Are you meaning to use the "beard" texture instead? If you are, then you can fix easily fix this issue by chaging the string and making sure that each shader points to only one texture. In case you are not, there is a fundamental flaw in your design that is caused by misunderstanding how the GPU works and how MTA is utilizing it. By using append-layers and enabling depth-testing, the GPU is attempting to redraw the beard onto the original model BUT this is not stable because of mathematical inprecision. Your textures will start to flicker or one will hide another. So how to fix this defect? Instead of creating two shaders that draw onto one texture, I recommend you to off-screen combine the textures and then apply them to a shader. You can use the dxCreateRenderTarget, dxSetRenderTarget, dxCreateTexture and dxDrawImage functions to create a drawing surface (render target), layer the face + beard onto each other and then use the resulting render-target as texture in your shader. Do not forget to enable alpha for the render-target! Here is how a combine-stage of two textures might look like: local function renderCombinedTexture(tex1, tex2) local tex1w, tex1h = dxGetMaterialSize(tex1) local tex2w, tex2h = dxGetMaterialSize(tex2) local cw, ch = math.max(tex1w, tex2w), math.max(tex1h, tex2h) local rt = dxCreateRenderTarget(cw, ch, true) dxSetRenderTarget(rt) dxDrawImage(0, 0, tex1w, tex1h, tex1) dxDrawImage(0, 0, tex2w, tex2h, tex2) dxSetRenderTarget() return rt end You should use renderCombinedTexture in the onClientRender event handler to adhere to MTA's recommendations. If you have combined the textures and the combined texture does replace a predefined texture fully of the GTA SA DFF file, then I recommend you to set appendLayers to false instead. I was unsure how your system worked in my previous reply so I spearheaded a guess. But now with my actual analysis I recommend you to NOT use the appendLayers functionality. IMO it is a feature of MTA with very limited applicability. You seem to use weird global variables across your script. Take a look at the following line which repeats itself but seems to imply a contradiction: hat[thePlayer] = shader The global table is called "hat" but the function it is used in is called addFace or addBart. Could this be a variable misuse? I am looking forward to hearing back from you! ?
-
Hello ju4nnnnnnn, have you modified your acl.xml file? This error message sounds like you are using a non-standard access permission configuration. Inside of the acl.xml file you should find the following relevant entries: <group name="Admin"> <acl name="Moderator"></acl> <acl name="SuperModerator"></acl> <acl name="Admin"></acl> <acl name="RPC"></acl> <object name="resource.admin"></object> <object name="resource.webadmin"></object> <object name="resource.acpanel"></object> </group> ... <acl name="Moderator"> ... <right name="function.startResource" access="true"></right> ... </acl> By default, the resources of the admin ACL group do have the Moderator ACL rights list assigned to them and it gives them access to the startResource function. Please check if your ACL.xml file has changed and try to revert the configuration to the last known good state.
-
Hello SkyDow, welcome to our forums! In this Scripting section we like to help you solve your Lua programming related questions so that you get to spawn your vehicles by either writing the Lua code yourself or making use of existing resources. It sounds like you have made a map using the MTA map editor and are trying to use it inside of your own server. I think that by starting the map on your server then you can at least make the vehicles be placed on your server. If you want to add respawning rules then I recommend you to script it yourself using the toggleVehicleRespawn, setVehicleRespawnPosition and setVehicleRespawnDelay functions. You could loop through the map elements using the getElementsByType function in combination with the "vehicle" element type.
-
Cool job! I think your work shows how creative you are.
-
Sorry but I do not work on the next version of scene2res at the moment.
-
Este é um texto traduzido. Recomendo que você use scene2res para conversão de mapa GTA para MTA. Ele otimiza automaticamente os arquivos TXD para você. Converter e carregar mapas GTA sem aprovação dos criadores de conteúdo está errado. scene2res Project Top Page - OSDN
-
Parts of it, like drawing text on elements, have to be done clientside. You might have to tell clients the text string using an event and when it should stop displaying (I recommend a timer).
-
Is one of the files missing that is inside the meta.xml? It is because of unexpected data loss? (hard drive starting to fail, unexpected delete operation inside server folder, etc) You can solve load failures by fixing the meta.xml problems and then executing a "refresh" command inside of your MTA server executable.
-
Hello Mario222, since you have asked in your title about "how to create" such a system, I want to give you basic hints about useful functions of MTA and Lua in general. You can use the table.sort Lua table library function to put table entries into a point-based order. This function can receive a table of tables as input and then sort based on an item key, for example the points of a player. The wiki documentation for the MTA:SA race resource is the go-to location for details about the events and functions when creating add-ons for it. I think that the "onPlayerFinish" event is of interest to you. By using its rank parameter you can design a mathmatical point-distribution function based on finish-positions. I recommend you to use a fixed table of points for a each player finish-position. When you are more advanced in mathematics you wouldn't be asking this question, right? But you could give it an exponential decrease based on a higher first-position score depending on the player count. This detail is up to you, in other words I won't be providing you with the advanced solution for nothing.
-
Thank you very much. I am trying my hardest to help you and everyone else who is genuinely in the need of it. You're welcome!
-
Sure. Here is my example. -- We assume that there is only one warehouse on the map/server. -- We assume that being inside the warehouse means being inside the colshape. local warehouse_timer = false; local warehouse_col = false; -- TODO. local function warehouseEnter(shape, matching_dimm) if (shape == warehouse_col) and (matching_dimm) then -- If we previously had a warehouse_timer, then we should clean it up here regardless. if (warehouse_timer) then killTimer(warehouse_timer); warehouse_timer = false; end warehouse_timer = setTimer( function() -- TODO -- If the timer has finished, then we should clean it up. warehouse_timer = false; end, 1000, 1 -- TODO ); end end addEventHandler("onClientElementColShapeHit", root, warehouseEnter); local function warehouseLeave(shape, matching_dimm) if (shape == warehouse_col) and (matching_dimm) then -- If we have previously entered the warehouse clientside, then we should -- have the warehouse_timer variable set to not false. We assume that -- the warehouseEnter function has been properly implemented. if (warehouse_timer) then killTimer(warehouse_timer); warehouse_timer = false; end end end addEventHandler("onClientElementColShapeLeave", root, warehouseLeave); Good luck with your project. I like that you phrased your idea in a serious way. ?
-
You're not even giving a full description what your script is supposed to do! Besides that, your script has flaws. But the flaws of your kind of scripts do not allow general support. Instead of doing too much, I want to give you hints: function warehoueEnter() if (getElementType(source) == "ped") or (getElementType(source) == "marker") then return end --thought maybe this would work if isElementWithinColShape(localPlayer, WarehouseCol1) == true then setElementData(localPlayer, "timer", 60) :O = setTimer(warehoueTimer, 1000, 61) else killTimer(:O) end end addEventHandler("onClientElementColShapeLeave", localPlayer, warehoueEnter) addEventHandler("onClientElementColShapeHit", localPlayer, warehoueEnter) you fire this event for all colshapes; is this really what you want to do? for what colshapes do you want warehoueEnter to really trigger? if you asked this question in a straightforward way, maybe people could help you much easier. If you want to limit triggering events to certain elements such as WarehouseCol1, use the addEventHandler function with propagate set to false and comparing the first argument of the event handler callback to WarehouseCol1. Look at the wiki page of onClientElementColShapeHit for an example! you triggering this event handler for both leaving and entering the col shapes makes no sense. could you please decide on what is important here: entering the warehoue if you enter the col shape (onClientElementColShapeHit) or when you leave it (onClientElementColShapeLeave)? There seldom exist MTA scripters that seek support on our forums and I like to see you here. If you want to listen to my advice, then please learn from the code structures and examples from the wiki. Format your code exactly like on the wiki pages. Get used to best-practice coding rules.
-
Which functions do you mean in particular? I don't understand.
-
Yes. I do not like to start support requests through private messaging but continuing there is fine.
-
Do your textures have alpha enabled? This looks like a hack-job to me and I am not convinced that you truly know how HLSL shaders work. If the beard is an alpha texture then you might have to set relevant alpha-enabling render-states. What you have to set depends on the asset structure themselves and unless you share the textures I cannot give you a recommendation.
-
There is a fundamental logic issue in your script. The element type of the root element is "root". Thus the following check will always fail: if (getElementType(getRootElement()) == "ped") then return end --thought maybe this would work Do you know about predefined event handler global variables? They are set based on the situation of each issued event. Look them up here. I suggest you to use the source event handler global variable like this: if (getElementType(source) == "ped") then return end The following is kind of weird, so please split up the event handler code: --Leaving the warehouse function warehouseLeave() if (getElementType(getRootElement()) == "ped") then return end --thought maybe this would work if isElementWithinColShape(localPlayer, WarehouseCol1) == true then timertxt = getElementData(localPlayer, "timer") Wtimer = dxDrawTextOnElement(localPlayer, "Defend Warehouse: "..timertxt, 1, 20, 255, 0, 255, 255, 5, "arial") elseif Wtimer == nil then return else destroyElement(Wtimer) end end addEventHandler("onClientRender", getRootElement(), warehouseLeave) -- OK. because of dxDrawTextOnElement addEventHandler("onClientElementColShapeLeave", getRootElement(), warehouseLeave) -- Why??? Good luck with your scripting! ?