ID:140358
 
Code:
client/New()
..()
Load()

client/proc
Load()

if(!src || !mob || copytext(mob.key,1,6)=="Guest") return

winset(mob, "_sload.savmsg", {"text="Looking for Save File...""})

var/loop = 0
var/savefile/temp = new("[key].dmgs")

while(length(temp)<1000)
if(loop>=3) break
loop++
sleep(5)

if(!length(temp))

winset(mob, "_sload.savmsg", {"text="No save file found.""})
winset(mob, "_sload.save", "image=ico_warn.png")
ResetMob(mob)

else if(length(temp)>102400)

winset(mob, "_sload.savmsg", {"text="Save file is too large!""})
winset(mob, "_sload.save", "image=ico_ok.png")
ResetMob(mob)

else

var/client_file = s_load(temp)

if(client_file)

if(client_file["name"]) client_file["name"] >> mob.name
if(client_file["items"]) client_file["items"] >> mob.items
if(client_file["trunk"]) client_file["trunk"] >> mob.trunk
if(client_file["guild"]) client_file["guild"] >> mob.guild
if(client_file["active"]) client_file["active"] >> mob.active
if(client_file["icon_state"]) client_file["icon_state"] >> mob.icon_state
if(client_file["pixel_c"]) client_file["pixel_c"] >> mob.pixel_c

if(mob.icon_state!="Custom") mob.icon='players.dmi'
else if(client_file["icon"]) client_file["icon"] >> mob.icon

if(client_file["config"]) client_file["config"] >> mob.config
if(client_file["ddisk"]) client_file["ddisk"] >> mob.ddisk
if(client_file["blocklist"]) client_file["blocklist"] >> mob.blocklist

winset(mob, "_sload.savmsg", {"text="Save file found ([round(length(client_file)/1024,1)]kb).""})
winset(mob, "_sload.save", "image=ico_ok.png")

else
winset(mob, "_sload.savmsg", {"text="Save file is invalid.""})
winset(mob, "_sload.save", "image=ico_error.png")
ResetMob(mob)

return


proc
make_hash(text)
return md5("[ahash][text]")

s_save(mob/M)

if(!M.client) return

var/savefile/F2 = new("[usr.key].dmgs")

var/savefile/F3 = new()

F3["guild"] << M.guild

if(M.icon_state=="Custom") F3["icon"] << M.icon

F3["icon_state"] << M.icon_state
F3["items"] << M.items
F3["trunk"] << M.trunk
F3["pixel_c"] << M.pixel_c
F3["name"] << M.name
F3["blocklist"] << M.blocklist
//F3["ace"] << M.ace
F3["ddisk"] << M.ddisk
F3["config"] << M.config
F3["active"] << M.active


F2["file"] << F3

var/hash = make_hash(F2.ExportText("file"))
F2["hash"] << hash

M << {"<img src="save_icon.png" width="16" height="16"><b>Game state saved.</b>"}

return F2

s_load(var/savefile/F)

var/text = F.ExportText("file")
if(copytext(text,1,14) != ". = filedata(")
return null

var/savefile/F2 = new(F["file"])

var/check = F.ExportText("hash")
var/hash = make_hash(text)
if(check != {". = "[hash]"\n"})
return null

return F2


Problem description:

I took part of the save system from Garthor's "Safe Save" in order to protect from the more obvious exploits.

It seems to work fine *however* im having trouble, it saves the file in the hosts game folder (at least it is when im hosting it locally to test!) and not in the players KeyInfo folder. I have tried doing Client.Export(F2) and then new(Import()), that seemed to work. It at least put the save file where i wanted it. But it wouldnt load! I did some debuging and found when it got to the if(copytext(text,1,14) != ". = filedata(") part it was failing, i did a quick print out (world << "[copytext(text,1,14)]" to see what was there and it was empty...

Not sure what im doing wrong, feels like im banging my head against a wall because ive not really done much with regards to SaveFiles, always used the basic save method (Export/Import) and added an MD5 but nothing that much more complicated & im kinda trying to do tons of other stuff at the same time. Need to get this sorted though!

Any help would be great, or pointers etc.

The issue is that you've taken what I had and butchered it, and what you have no longer works. I suppose you could say that my library successfully prevented you from tampering with it.

The library contains a readme with an explanation of how to use it, as well as two examples (one in the readme, one in the demo). But, to paraphrase: what you should be doing is including my library properly, and then building your savefile however you want. Once you've done so, do var/savefile/F_safe = safe_save(F), and F_safe will now be secure. Send that out with client.Export().

Similarly, to load, first do var/savefile/F_safe = client.Import(), then var/savefile/F = safe_load(F). If F is null, then the savefile was invalid. Otherwise, you can load as you wish.
In response to Garthor
Garthor wrote:
The issue is that you've taken what I had and butchered it, and what you have no longer works. I suppose you could say that my library successfully prevented you from tampering with it.

It does work though. It's just not putting the file where i wanted it to put it, it does the same thing in your original library. Saves it in the directory with the host files.

The library contains a readme with an explanation of how to use it, as well as two examples (one in the readme, one in the demo). But, to paraphrase: what you should be doing is including my library properly, and then building your savefile however you want. Once you've done so, do var/savefile/F_safe = safe_save(F), and F_safe will now be secure. Send that out with client.Export().

Similarly, to load, first do var/savefile/F_safe = client.Import(), then var/savefile/F = safe_load(F). If F is null, then the savefile was invalid. Otherwise, you can load as you wish.

Ok then, ill try reverting it back & redoing it. However i really didnt think id changed it that detrimentally. I suppose i can always adjust it once its working then when it breaks i know where i went wrong :)

Thanks
In response to EternalDuelistSoul
You should not touch the source of my library. Period. It is designed in a manner such that there should never be any need for you to do so.