I want to basically create a roleplay gamemode(it wont be a darkrp ripoff and it wont probably see the daylight, just a project i’m trying to learn some lua with). I’ve come across a small snag. I’ve read about persistant data, usermessages, networked ints/strings and the new Net library introduced in gmod 13. So what i am trying to achieve as of right now is a simple money system and a roleplay name system. Any ideas on how to approach this? Best way to do this is probably use the net library and persistant data, but with the net library the stream works both ways right? Isn’t that something bad considering i don’t want the player altering his amount of money clientside? Is such a thing even possible? Anyway would be great if someone gave a simple money system example with the net library and feel free to rate me dumb cause i didn’t understand the documented net library fully. Also on a sidenote, i know some people can xray darkrp like get the amount of money a player has, how is that possible (any chance such a thing is preventable without some high-end anti-cheat or scriptenforcer)? Hopefully this wont become a rant of me being a idiot and trying to make my own rp or a rant about darkrp.
Just whipped this up on paint to explain a basic approach:
The step two, performance wise, is it wise to save to disk after every change? I’m thinking that names and money yeah should be saved each time to disk but for example hunger, sleep anything else amongst those lines should just be left in cache and only save when player logs out(might not need to save at all really). Also about saving to disk, you mean essentially the GetPData and SetPData functions? If so, is saving to disk faster than saving to lets say a MySQL database? Under perfect condition where the database is on the server host and disk space is huge.
A player can get other players wallet because DarkRP is using (most likely) NWVars, which don’t care about who receives the data, everybody gets it (and they’re expensive as hell, they’re sent multiple times a second, wastes enormous amounts of bandwidth). The net library is much better, because you send data only when you want, to whoever you want. I’d recommend you use SQLite (to save persistent data). It’s pretty simple and I believe Garry made a library for that (or methods on the Player class, not sure). Use the diagram above. If you save the data when it is changed, forget about server shutdown and player disconnection. It’s not needed anymore and it’s a safeguard against crashes. I’d use the SteamID64 to associate data to players (it’s plain numbers in a string).
EDIT: Remote MySQL databases are slower of course, since you need to send data through a connection while PData is saved on disk.
Ah thanks, so basically stick with net library over usermessages and nwvars. I don’t see any cons to net library compared to umsg and nwvar. Anything else i should be aware of? This stuff you guys posted is great and helps a ton
Usermessages are not bad. But they aren’t sent immediately. They’re added to a buffer and sent in the next frame (which usually is not a problem, but their individual buffer is very small, 255 bytes each).
About the net library and clients, there’s no problem if they try to “hack” you, it doesn’t work like this. If you’re not receiving net messages from clients, they’ll just be ignored. If you need to however, you’ll have to check what data they’ve sent you.
Ah, so there shouldn’t be a way for the client to be able to trick the server into receiving false data? I mean if i would make a shared function that sets money each time the player does KeyPressed, there is no way for the client to come and interrupt the shared function with its own set of data? This is probably a dumb question but just to make sure.
If a client can run their own lua code they can send a net message from themselves with whatever data they like. There are probably also ways for clients to do this without running their own lua (but that’s quite unlikely to happen), so always make sure to validate what you receive and not trust what the client sends.
The client should never have to set data values. Never. If it must, you’re doing something wrong. Data values on the client should only be needed for visual or informative purposes. You can, however, tell the server a change happened (for example, on inventories) and let the server verify and confirm what happened. Only then, the changes are made. Like Willox said, confirm everything the client tells you.
I wouldn’t save to disk on every change if you’re using mysql and especially if you’re using remote mysql databases, it simply wouldn’t be wise even if the performance decreases weren’t noticeable.
If there’s going to be a lot of people using this gamemode at once it’s probably best not to save to disk each time it changes, but only when they leave and the server shuts down.
You could also add an auto-save function that’s called every 30-60 seconds that would save all of the data to disk. This addition combined with saving only on disconnects and server shutdown’s would probably be best for larger servers.