-
Posts
866 -
Joined
-
Last visited
-
Days Won
1
Everything posted by Mr_Moose
-
"isObjectInACLGroup" requires many steps if used in a function called by a command handler, first argument is a player element which must be converted into an account object and then converted into a string. Try this: local accName = getAccountName ( getPlayerAccount ( client )) if isObjectInACLGroup ("user."..accName, aclGetGroup ( "Admin" )) then -- Executed only for ACL group "Admin" end And make sure you replace "client" with the variable name of your player element and that the player is in the ACL group "Admin".
-
As you're using a grid list, it's kind of pointless to use 5 different event's to trigger server side, vehicle names are already in the grid list and can be passed to the server side part and then converted into an object id using: int getVehicleModelFromName ( string name ) Except for that the code is clean and the documentation well made.
-
You should use the "onPlayerChat" event and call the local chat function from there and then cancel the main chat. Alternatively cancel and unbind "onPlayerChat" and bind the local chat to 'T'.
-
Maybe you should start by reading the code line by line to see what it does, and if you don't understand post it here to get help.
-
Every time I buy a new PC I still have the old one hanging around, I also need constant access to the internet so both hardware and internet connection are things I still have to pay for no matter if I host by myself or rent a VPS from vortex, with full control of my servers I don't have to worry about what other people do, which may cause bad performance for my VPS, I got all performance for myself which is a huge advantage, electricity and it's rest products (heat) can be reused in many ways and are costs I still have to pay, at the end I get a fully acceptable uptime of 99.8% (stats from this year), for a cost of just $1 which was due to a broken capacitor in one of the servers. It's not a perfect solution in all cases as said earlier, but there are definitely cases where this is the best solution, all Grand Theft Walrus servers runs on a solution like this for instance, take a look there if you wish to see it live. With the right software as mentioned in the tutorial I also have lot's of performance being unused which I sell for a cheap price to responsible developers in need of a host. So the final hosting cost ended up in -$200 in pure profit, something you can't get if you use vortex. My conclusion is simple, this self hosting project is definitely better
-
I think you need a predefined table with the coordinates of each area you want to make, getZoneName uses a table as well. What I suggested above was a set of heavy calculations which is pretty useless to do multiple times, it's better to do it once and save the output as an xml file or similar which can be used to convert names to coordinates in a more serious resource, the script to generate that table doesn't need to be more than just an ugly hack, here's a skeleton that may be used for that. local x,y = 0,0 local curr_zone for x, 600 do for y, 600 do curr_zone = getZoneName((x-300)*10, (y-300)*10, 0) -- Save the output in a proper format. end end
-
Those who made custom dx outputs for zone names are probably checking a name string to see if it's changing, getting the coordinates for each zone may be hard thought, I tried that long ago by making a simple script looping from -3000 to 3000 in x and y, getting the zone name and assign a color to it and then created 10x10 colored squares that represented these areas, it wasn't optimized at all but it worked, I'm sure there are better ways but you probably have to do most of the work by yourself by indexing these areas.
-
If you really fixed it the problem would have been gone, the missing end was near line 29, try this. It's not tested but should work. --lineas iniciales: marker = createMarker( 2043, 855, 5, "cylinder", 2, 151, 146, 0, 255 ) CONTROL_MARGIN_RIGHT = 5 LINE_MARGIN = 5 LINE_HEIGHT = 16 g_Root = getRootElement() g_ResRoot = getResourceRootElement(getThisResource()) g_Me = getLocalPlayer() server = createServerCallInterface() guiSetInputMode("no_binds_when_editing") --lineas finales: function getPlayers() g_PlayerData = {} table.each(getElementsByType('player'), joinHandler) end function showgui (hitElement) if getElementType(hitElement) == "player" and (hitElement == localPlayer) then createWindow(wndMain) hideAllWindows() guiCheckBoxSetSelected(getControl(wndMain, 'jetpack'), doesPedHaveJetPack(g_Me)) guiCheckBoxSetSelected(getControl(wndMain, 'falloff'), canPedBeKnockedOffBike(g_Me)) setJetpackMaxHeight ( 9001 ) triggerServerEvent('onLoadedAtClient', g_ResRoot, g_Me) end --[[ HERE'S THE MISSING END ]]-- end addEventHandler("onClientMarkerHit", marker, showgui) function joinHandler(player) if (not g_PlayerData) then return end g_PlayerData[player or source] = { name = getPlayerName(player or source), gui = {} } end addEventHandler('onClientPlayerJoin', g_Root, joinHandler)
-
function giveTeamMembersMoney(theTeam, money) for id, plr in ipairs(getElementsByType("player")) do if getPlayerTeam(plr) == getTeamFromName(theTeam) then givePlayerMoney ( plr, money ) outputChatBox ( "[TEAM] Money received.", plr, 255, 255, 255, true ) end end end You're trying to get a team name from a nil object on line 3, then you compare the same thing with a constant string named "TEK" which applies to all players, "player" is also a class name, it may work for now but in the future when lua get's more object orientated it won't work using class names as variables. The chat output was also seen to all online players unless it crashed before it got there, the above code does what you want, don't forget to pass the arguments. An example call would look like this: giveTeamMembersMoney("Police", 20000) -- give members of the police team $20´000 giveTeamMembersMoney("Criminals", 4000) -- give members of the criminals team $4´000
-
More updates means more restarts which means less uptime, Windows has lower security by default, Windows consumes up to 10x more RAM, In short, Windows has nothing to do on a server. Go for Linux, especially Debian is a stable distribution which also can be run without GUI, giving you more performance for your money, Cent OS is also common on game server hosting machines. And Ubuntu are good for beginners since it's easy to work with. I have long experience from both Windows and Linux server systems.
-
I've been talking about the server all the time, all I'm saying is that in the end it's all about the resource performance, if the resources are well written and optimized, you wont need a top of the line server to run them.
-
I'm pretty sure they affect each others in some cases, only the fact that you can set the FPS limit server side which will be applied to all clients, means that the server CPU directly can affect the clients. That example with the BMW was actually pretty good, and just to make it clear, no not all data goes thought the server CPU, only the data processed by server side scripts. For example render a DX GUI will only affect the clients currently using that GUI while for example a saving function that saves all account data for all players in a timer each 50ms (example of badly optimized script), will use pretty much all CPU performance, that the server has, and thereby also slow down the clients. Let's also assume you have some calls between server and client, like if you used set and get element data to temporary store the data you're trying to save server side which has to be synced through all clients and the server. There are ways to workaround this but if the resources are badly written the server CPU will reduce clients FPS as well. By default both the MTA server and client software use a pretty low amount of resources and you can easily get 60 FPS on older machines as well.
-
That's exactly what it was and I found a conclusion there in performance browser, when the CPU can't do all calculations the FPS will go down, a server can also run out of resources and that will be noticed on the clients as well. That 36 FPS thing is a notice in the server configuration file where maximum FPS can be specified, this has probably more to do with the tick count rather than client's graphics but a limit of 36 will prevent clients from running with higher amount of FPS, that's why I recommend 60 in server configuration.
-
RAM and CPU are the most important components I would say, but still, it all depends on what kind of resources you plan to use and how optimized they are, how much is running on the server vs the client etc.. Let's check each component individually and what they are used for. RAM, store objects and data for quick access when the CPU needs it, this is a pretty cheap component today which most servers has a large amount of, there's also a swap on your hard drive to store objects that isn't accessed very often that help's the RAM. With more players you may need more of this obviously, let's take cit2 as an example, a server that could had 1400 players online at the same time as most and they have 64GB RAM I read somewhere, that's a maximum of ~46MB/player, with a more optimized game mode you can reduce that even more but as recommendation it's a fair number to work with. HDD, usually not an issue 10GB is just fine, most server has way more space than that anyway, what's important here is the backup which should be stored on at least two different physical drives, not in the same chase to avoid loosing all data if your server is on fire one day for example CPU The component you can optimize most of all, start the built in resource 'webadmin' and 'performancebrowser', open your web browser and connect to your server to view the performance browser, that shows you how many % CPU is used by each running resource and thanks to that you can find which one is badly optimized, a resource that use much CPU will reduce the server's FPS (Frames per second) and your players may experience lag. A recommendation for the FPS is 36 but I would suggest 60 as that's what most monitors today have, you may notice a few GTA bugs with that but it shouldn't be any problem thought. Multicore may be useful if you plan to run other applications on your VPS such as a webserver maybe, except for that the server itself won't use more than 1 core as far as I know. A faster CPU may handle badly optimized scripts better but I recommend optimizing the scripts instead, you usually save more money that way since most hosting companies usually charge you more if you want a faster CPU. Bandwidth, usually it's easy to think that you need lot's of this but as for the other part's it's all about optimization here as well, mods could for example be downloaded later by script from an external server to prevent long download times, it's measured in mbt/s where 8bit = 1byte, you do the math and find out how much data you need to transfer, I haven't noticed any issues yet serving 50 clients on a 10mbt/s line, what you may check here is also the ping, a high ping could ruin the synchronization between players and objects so the server must have as low ping as possible.
-
Good point, especially after working in a terminal for a while, I surely miss that feature.
-
I would also recommend DX functions, have a look at this maybe which already does most of the job for you: https://github.com/GTWCode/GTW-RPG/tree/master/resources/GTWtopbar, by including that a simple announce command based on your code would look like this: function Announce( sourcePlayer, commandname, ...) local message = table.concat({...}, " ") if(message ~= nil and message ~= "") then if(tonumber(getElementData(sourcePlayer,"Admin")) < 2) then outputChatBox("ERROR: you Can't use This CMD.",sourcePlayer) outputDebugString("WARNING: Player " .. getPlayerName(sourcePlayer) .. " has attempt to use An ADMIN command. [/"..commandname.."]") return end export.GTWtopbar("Note: "..message, root, 255, 255, 255) else outputChatBox("Error Right Syntax: /announce [text] ",sourcePlayer) end end addCommandHandler("announce", Announce)
-
Could you elaborate on that? I was actually thinking of that as well, but then I found out that I had lot's of GUI's, if each resource would contain a png image the download size would increase a lot. Now that's not the end of the story, a global resource which applies png images to improve the look of standard CE GUI's might be the solution, the download size remains low and everything would be built using standard CE GUI functions, Here's an example of that: https://github.com/GTWCode/GTW-RPG/tree/master/resources/GTWgui
-
It's kind of wasted tho, the onPlayerChat event already has all this functionality built in and the main reason for making custom chats are usually the look and feel and maybe a different key, instead of just doing cancelEvent() in there you could also add the code from "globalchat" into it, that would cancel regular chat outputs and show your custom outputs and still allow commands to be sent through, remember, you're making a custom chat system, not a custom command handler.
-
Make it a script file first: nano compiler Paste the code and edit the search paths to match the directory layout on your VPS, make it executable and finally, run. sudo chmod +x compiler ./compiler the 'luac_mta' application must be downloaded and extracted in the same directory as this script in order to make this work, it's not tested yet so make a backup of your files before using it.
-
Upgraded from 2.0 to 2.1, not many news in here thought but the security is a little bit better, code is more optimized to prevent lag on servers with many players online, and ability for staff to chat in any team chat has been added: use "/cteam " as staff to write a message to a specific team.
-
It's always problematic when people rename original resources, there's a few original dx text message resources available, the good news in this case is that they all use the same syntax and does pretty much the same. Download this: https://github.com/GTWCode/GTW-RPG/tree/master/GTWtopbar And change these: exports.UIPtexts:output( to exports.GTWtopbar:dm( Or follow Chronos advice and use "outputChatBox"
-
It is possible but don't talk about general game modes like if they where a good way to measure performance usage, if there's just one little mistake in a single script you could have a memory leak making any server lag. The best thing you could do is to try it out and launch the scripts one by one while you check how much RAM is used, set a low limit for max players to prevent memory leaks caused by many players. Sounds like some kind of virtual VPS setup and the swap file might be located on a fast SSD, if so it's not to slow compared to the RAM and you may be able to use a large amount of it as well before you notice any lag. I would also suggest that you only run the MTA server in a screen session and nothing else on that VPS and it could be a fully acceptable server after all.
-
Pretty urls are defined in the .htaccess file which probably has a line like this so far: RewriteRule ^/?wiki(/.*)?$ %{DOCUMENT_ROOT}/index.php [L] However, it's easy to change to whatever you want, this for example: RewriteRule ^/?wiki(/.*)?$ %{DOCUMENT_ROOT}/index.php [L] RewriteRule ^/?w(/.*)?$ %{DOCUMENT_ROOT}/index.php [L] Will allow "w" and convert it to "wiki", but if I change it to this: RewriteRule ^/?docs(/.*)?$ %{DOCUMENT_ROOT}/index.php [L] RewriteRule ^/?wiki(/.*)?$ %{DOCUMENT_ROOT}/index.php [L] It will just ignore one of them. Now, your idea was to use the root right? Well that's a bad idea, it causes conflicts with real existing folders. You can read more about that here: http://www.mediawiki.org/wiki/Manual:Short_URL "wiki" is very common even on pages with subdomains so if anything really needs to be changed at all that "w" and "wiki" thing might work, except for that it's a worthless idea.
-
Well I guess you just got scammed by this guy, however indexes are easy to check, just check if a certain index returns nil like this: theTable = { } if theTable[theIndex] then -- theTable has a value at theIndex else -- theTable is empty at theIndex end Multi dimensional arrays is a bit tricky thought but here 's one way you could solve it: theTable = {{ }} if theTable[theIndex] then -- theTable has a value at theIndex else theTable[theIndex] = { } -- Make a new array if empty end We're here to help, not to do your job.
-
Updated as it looks like there are many views on this topic, hope it's helpful for all of you, and don't be afraid to ask if anything's unclear.