ID:265529
 
I heard from someone that client-side .sav files are easier to crack and need to be incrypted, is that true? I thought they were very similar to server-side .sav files.
Client-side sav files are on the client's computer. Easy for the client player to mess with them.

Server-side sav files are on the server computer. Easy for the server host to mess with them. Build security into both. Kunark, I think, wrote some articles for either digitalBYOND or secureBYOND on the subject. :)
In response to Jon88
Yes, but how easy is it to mess with them? You can't just open them up in Word Pad and change a couple numbers and go "Woohoo i'm a level 1000 god!" Well I was right then, because I said that if .sav files are so easy to mess with then anyone can host and mess with them, but .sav files only load what it's coded to load, right?
In response to Justin Knight
I believe someone made a savefile editor at one point. I'd do a search for it, but it loads savefiles in plaintext saves them, then allows you to edit that and save it as a savefile again, IIRC.
In response to Justin Knight
Justin Knight wrote:
Yes, but how easy is it to mess with them?

Very easy.

You can't just open them up in Word Pad and change a couple numbers and go "Woohoo i'm a level 1000 god!"

No, but you can make a program that makes a text version of the savefile, open that in notepad and make yourself level 1000, then convert it back into a savefile.

Well I was right then, because I said that if .sav files are so easy to mess with then anyone can host and mess with them, but .sav files only load what it's coded to load, right?

No, savefiles load whatever is in them. Even if what's in them isn't anywhere in the programming. That's why they are so fun to mess with.

Sometimes I'll make a private server for a game I like (assuming the game creator put the files up for everyone to host); and I have given myself a custom, multi-tiled icon, custom equipment (It is of the same type as something already defined, but its icon and stats are changed), and other things that certain games leave themselves open to.

It is not even complicated. If you know how, you can whip up a savefile editor in a couple minutes. Plenty of us have done so.
In response to Audeuro
I was doing it the hard way, then - I wrote a BYOND program that displays all the savefile directories and lets me pick some to edit. It even worked with references and other such things.
In response to Loduwijk
Loduwijk wrote:
It is not even complicated. If you know how, you can whip up a savefile editor in a couple minutes. Plenty of us have done so.

Well, I searched for savefile editors and used one. It's really not as easy as you say it is; it's actually quite tedious even with an easy-to-use program. If you are really intent on doing it, it's not too hard, but most people won't be. You make it sound like all players are developers that play your game just to crack it.

Anyway, what encryption do you guys reccommend for .sav files?
In response to Justin Knight
Justin Knight wrote:
You make it sound like all players are developers that play your game just to crack it.

Well, not developers, but definitely the enemy. :P The client is in the hands of the enemy, and nothing it tells you is to be trusted, savefiles included. :)
In response to Jon88
The best strategy is similar to the modern world: totalitarian bureaucracy doesn't work, because then you're spending so much time authenticating and authorising that you don't have any time to actually get any work done. At the same time, no security at all equals anarchy, and many people are incapable of living in anarchy productively (e.g., riots).

As Hegel would say, it's best to achieve a compromise through the dialectic process. Decide what's critical and what isn't critical, perform periodic verifications of data, and range check things such that certain things are wholly impossible.

I should note that more advanced DM developers will never write:

savefile << object

...where object is something to write directly to the savefile. This is because:

A) It's insecure. People with access to the savefile can change any of the variables they like, and add additional variables for the BYOND game to load, assuming they know the appropriate variable names.

B) It's wasteful. Most people aren't careful to declare their variables as tmp or const as needed, so variables that don't need to be saved are saved even though they won't be used once loaded.

C) It saves more than you might think. If you write an object to a savefile, then if any variables of that object point to another object, BYOND will save both objects to the file!

D) It's dangerous. If you save a mob, it also saves the key variable automatically. If you load a mob which contains a mob variable, then the savefile will also load the saved mob, and if the saved mob contains a key, then if the player is actually connected to the game at the time, he or she will be spontaneously connected to this older copy of his or her mob. It's a complicated explanation, but it's what's responsible for a "rollback" bug which plagued My Life as a Spy until Skysaw finally figured it out.

E) It's lazy. You might as well just write the variables you care about, then read the variables that you care about, instead of just relying upon BYOND to do all the work for you. BYOND's good like that, but unless you're just hacking something in as a temporary test or fix, it's better to spend the extra effort to have more control.
In response to Jtgibson
I'm using savefile[buffer] << object to save mobs in a roguelike I'm writing. It is, in several ways, much easier in this case. I don't want to have to go through the objects list and decide what needs saving - Dantom have included a procedure that does it for me. I should use it. That's why it's there. People don't tell you not to use the 'printf()' proc in C because you can do exactly what it does by messing with memory directly - printf() is there so that you don't have to mess with memory.

Anyway, it's singleplayer. If you want to cheat, go ahead. You're only screwing yourself. :p.

If I do set up a scoreboard of some sort for it, though, then I'll have to encrypt the savefile. Easy enough to do. Encrypt several variables for the mob, and add a 'check' value that is a combination of several other variables. Then the players need to figure out the checking algorithm to cheat without getting caught and branded as a cheater.

I'm not actually using any tmp or const variables that shouldn't be saved, at least for mobs.

The only datums a player ever references are as follows:

Their inventory.
Equipped weapon/armour.
Spell datums.
Skill datums.
Condition datums. (Status effects).

None of those datums reference other datums or objects (Except the player, of course.)

Singleplayer, so the key problem is irrelevant. I'm not going to be loading anything but one savefile.

I may get more control doing it some other way, but I don't need it. May as well do it the easy way - It works.
In response to Jp
Jp wrote:
I'm using savefile[buffer] << object to save mobs in a roguelike I'm writing. It is, in several ways, much easier in this case. I don't want to have to go through the objects list and decide what needs saving - Dantom have included a procedure that does it for me. I should use it. That's why it's there. People don't tell you not to use the 'printf()' proc in C because you can do exactly what it does by messing with memory directly - printf() is there so that you don't have to mess with memory.

Not quite the same. printf() has predictable, reliable results each and every time -- either it produces a string, or the stack is full and no string can be produced. Writing an object directly to the disc, on the other hand, has a wide variety of potential results depending on the complexity of the object being saved and the amount of changed data that the object contains.

Writing an object to the disc is a bad idea in any programming language, though admittedly less bad in DM than in most CPU-based languages, since DM at least doesn't point to invalid memory addresses afterwards.
In response to Justin Knight
Justin Knight wrote:
Loduwijk wrote:
It is not even complicated. If you know how, you can whip up a savefile editor in a couple minutes. Plenty of us have done so.

Well, I searched for savefile editors and used one. It's really not as easy as you say it is; it's actually quite tedious even with an easy-to-use program. If you are really intent on doing it, it's not too hard, but most people won't be. You make it sound like all players are developers that play your game just to crack it.

Quite tedious? You're joking, right? I'm not sure which savefile editor you used, but I know Foomer's is VERY easy to use. You don't even have to use a seperate program to edit the savefile.

Believe me, if the players have their savefile, they're going to try and get into it.
In response to Airjoe
I recommend hub://AZ0123.az_EditSave for all your savefile editing needs. Very easy to use.

~X
In response to Airjoe
Airjoe wrote:
Quite tedious? You're joking, right? I'm not sure which savefile editor you used, but I know Foomer's is VERY easy to use. You don't even have to use a seperate program to edit the savefile.

Believe me, if the players have their savefile, they're going to try and get into it.

The one I used, it came up first on my search, required a lot of file-pathing that got really tedious after a while. You had to find the save file you want to edit, find the editor's directory which was inconspicuously in a hidden Application Data folder for me (as is with Foomer's demo too), then copy the save file into that directory, type in the file name and convert it into a save file, edit it whichever way you please, then make that back into a save file, and copy that where you got it from in the first place, THEN load it into the game. Are you overlooking the editing part? Say you want to "hack" the save files of some random RPG (They're probably the ones that use save files the most), so you download it and do the steps above, but the game has an exp var, not simply a level var! If you go too high, it might not load correctly, and if you go too low you won't get the high level you want. So you probably will have to try a few times, meaning repeat some of the steps above. I call THAT tedious; you probably won't get the instant gratification you want and will lose interest. This is why I was saying not everyone is a developer that wants to hack your game, because you would have to be patient and probably have to have some developer-type knowledge to edit the save file correctly.

You guys kinda missed the point here, I don't want to know all about savefile editing (READ THE TOPIC). I simply wanted to know how easy it is to edit them, and when I realized that it's pretty easy if you are determined, and asked how to implement encryption/decryption into saving/loading said files. Oh yeah, I think someone might have said how to do it, but some sample coding would be great. I don't want to accidently screw up people's save files.
In response to Justin Knight
Well then how would I go about writing a savefile encyrption system, with client side saving?

I looked at Client Side, and liked it, up untill everyone had level 100 characters. =/
In response to Flame Sage
You can save only the important variables that you need as text strings. I suggest making a certain text encryption process that you can use to encrypt and decrypt text strings, in canonical form if possible, and saving all numbers in their encrypted text form.
Example:
mob/verb/Save()
var/savefile/F=new("Save/[src.ckey]")
F["Desc"]<<Encrypt(src.desc)
F["Age"]<<Encrypt(num2text(src.age))
mob/verb/Load()
var/savefile/F=new("Save/[src.ckey]")
src.desc=Decrypt(F["Desc"])
src.age=text2num(Decrypt(F["Age"]))
In response to Justin Knight
Here is the code I was using in one of my projects to encode and decode savefiles. It may be a bit of over-kill, since it uses md5() encryption as well as AirMapster's RC5 preview, but it works wonders. I can guarantee no one will crack it. Just make sure to decrypt the file before reading from it, and encrypting after you're done. S is the savefile to encrypt/decrypt, Key is that player's key, pass is returned by Get_Pass(), which just jumbles a key in such a way as to give the same pass for a Key Save pair, and Save is the actual name of the saved game. In my case, it was something like RPName.sav, where RPName was the name of their character. Feel free to modify this for your own purposes. Just remember to change the "some random text" and "more random text" to something else.

proc
first_char(T){if(T&&istext(T)&&length(T)).=copytext(T,1,min(length(T),2))}

Get_Pass(var/Key, var/Save)
var/pass = ckey("some [Key] random [Save] text")
var/list/chars = text2list(pass)
var/list/new_chars = new()
var/span = round(chars.len/10)
for(var/i = 1, i <= chars.len, i+=span)
new_chars.Add(chars[i])
pass = list2text(new_chars)
return pass


Encode_Save(var/savefile/S, var/pass, var/Key, var/Save)
if(!S) return
if(pass)
if(!Key || !Save)
world.log << "Encode failed! insuficient arguments"
return
var/cipher = RC5_Encrypt(S.ExportText("/"), pass)
if(cipher)
fdel("./saves/players/[first_char(Key)]/[Key]/[Save]")
del(S)
S = new("./saves/players/[first_char(Key)]/[Key]/[Save]")
S << cipher
else world.log << "Encode failed! no cipher"
else world.log << "Encode failed! no pass"


Decode_Save(var/savefile/S, var/pass, var/Key, var/Save)
if(!S) return
if(pass)
if(!Key || !Save)
world.log << "Decode failed! insuficient arguments"
return
var/cipher
S >> cipher
var/text = RC5_Decrypt(cipher, pass)
if(text)
fdel("./saves/players/[first_char(Key)]/[Key]/[Save]")
del(S)
S = new("./saves/players/[first_char(Key)]/[Key]/[Save]")
S.ImportText("/",text)
else world.log << "Decode failed! no text"
else world.log << "Decode failed! no pass"
return S


~X
In response to Xooxer
Hi, i am just wondering where i would put that in my game or if not where how do i implement it. This is to Xooxer btw

Thanks, Ajmoore