• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Help with save file duplication

66
Posts
6
Years
    • Seen May 2, 2020
    Alright so is there any type of script that can stop players from copying their save file and then restoring it later. I need this because I have an online trading thing in my game and people can duplicate Pokémon like that. Or make it so that the save file is in a hidden directory so that no one knows where to find it. Thanks.
     

    Sparkin

    Guest
    0
    Posts
    Can you elaborate more on how they would duplicate?
     
    66
    Posts
    6
    Years
    • Seen May 2, 2020
    Like this:
    Step .1
    Copy and paste their save file from C:/Users/Username/Saved games to their desktop
    Step. 2
    Trade away a shiny or some OP Pokémon to some other computer or something.
    Step. 3
    Overwrite current save file with the one that you copied to your desktop
    Step. 4
    Send Pokémon back to original computer.

    And then you have 2 of the exact same Pokémon.
     

    Ego13

    hollow_ego
    311
    Posts
    6
    Years
  • I mean you could change the file path for the save file so ppl wont be able to find it in the first place
    Then again if someone really wants do it, they will find a way
     
    66
    Posts
    6
    Years
    • Seen May 2, 2020
    I mean you could change the file path for the save file so ppl wont be able to find it in the first place
    Then again if someone really wants do it, they will find a way
    Yea that's something I'm trying to figure out. I have no clue how to change where the save file goes.
     
    25
    Posts
    6
    Years
  • Well, the one option is to put some sort of a unique variable in the save file and to check whether it is equal to the representitive server variable. Like, any action regarding the pokemon change changes this unique variable (commonly, it is called a "seed") and when some player connects to your online system, your server system checks the seed it has stored for this player.
    But it is more math than a programming - I mean, finding such function, that is. Then, you still have to implement it in your project and so on.

    Hash functions they are called, if I am not mistaken.

    And really... Think small?
     
    66
    Posts
    6
    Years
    • Seen May 2, 2020
    and when some player connects to your online system, your server system checks the seed it has stored for this player.

    Ah should've mentioned this earlier I guess, I'm not the one who's hosting the server. I'm using this online panel meaning I have no control over what the server checks for and all that kind of stuff. I think the best way to stop save file duplicating is to just change the save location to a place where no one knows.
     

    Ego13

    hollow_ego
    311
    Posts
    6
    Years
  • This function gets the save file path
    Code:
    def self.getSaveFolder
    Just don't know how to modify it
    You might just wann write an absolute file path instead of letting the programm check for it

    I'm still wondering if there isn't an easier way to check if a file was copied
     
    25
    Posts
    6
    Years
  • Ah should've mentioned this earlier I guess, I'm not the one who's hosting the server. I'm using this online panel meaning I have no control over what the server checks for and all that kind of stuff. I think the best way to stop save file duplicating is to just change the save location to a place where no one knows.

    Trust me, it is the easiest thing possible to find out where the game saves the data. Even if you cypher your game data, one can simply just start playing your game on a fresh copy of Windows/whatever they are using, and simply see what was added.
     

    Luka S.J.

    Jealous Croatian
    1,270
    Posts
    15
    Years
  • Essentials gets the saved games folder path by invoking SHGetKnownFolderPath through Win32API. This uses GUID of the folder paths which you can find documented here. The only annoying bit is that you have to split the GUID into correct hex chunks for def getKnownFolder. I've made a small module for myself to automate this process, and make it a bit easier.

    Code:
    module Env
    
    	COMMON_PATHS = {
    		"CAMERA_ROLL" => "AB5FB87B-7CE2-4F83-915D-550846C9537B",
    		"START_MENU" => "A4115719-D62E-491D-AA7C-E74B8BE3B067",
    		"DESKTOP" => "B4BFCC3A-DB2C-424C-B029-7FE99A87C641",
    		"DOCUMENTS" => "FDD39AD0-238F-46AF-ADB4-6C85480369C7",
    		"DOWNLOADS" => "374DE290-123F-4565-9164-39C4925E467B",
    		"HOME" => "5E6C858F-0E22-4760-9AFE-EA3317B67173",
    		"MUSIC" => "4BD8D571-6D19-48D3-BE97-422220080E43",
    		"PICTURES" => "33E28130-4E1E-4676-835A-98395C3BC3BB",
    		"SAVED_GAMES" => "4C5C32FF-BB9D-43b0-B5B4-2D72E54EAAA4",
    		"SCREENSHOTS" => "b7bede81-df94-4682-a7d8-57a52620b86f",
    		"VIDEOS" => "18989B1D-99B5-455B-841C-AB7C74E4DDFC",
    		"LOCAL" => "F1B32785-6FBA-4FCF-9D55-7B8E7F157091",
    		"LOCALLOW" => "A520A1A4-1780-4FF6-BD18-167343C5AF16",
    		"ROAMING" => "3EB685DB-65F9-4CF6-A03A-E3EF65729F3D",
    		"PROGRAM_DATA" => "62AB5D82-FDC1-4DC3-A9DD-070D1D495D97",
    		"PROGRAM_FILES_X64" => "6D809377-6AF0-444b-8957-A3773F02200E",
    		"PROGRAM_FILES_X86" => "7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E",
    		"COMMON_FILES" => "F7F1ED05-9F6D-47A2-AAAE-29D317C6F066",
    		"PUBLIC" => "DFDF76A2-C82A-4D63-906A-5644AC457385",
    	}
    	
    	def self.path(type)
    		hex = self.guidToHex(COMMON_PATHS[type])
    		return getKnownFolder(hex)
    	end
    	
    	def self.guidToHex(string)
    		chunks = string.split("-")
    		hex = []
    		for i in 0...chunks.length
    			chunk = chunks[i]
    			if i < 3
    				hex.push(chunk.hex)
    			else
    				split = chunk.scan(/../)
    				for s in split
    					hex.push(s.hex)
    				end
    			end
    		end
    		return hex
    	end
    			
    end

    I've recorded most of the common paths and their GUIDs in the module, and you can very easily get the folder path with a simple command such as
    Code:
    Env.path("DOCUMENTS")
    You can edit the save folder by changing the value the def self.getSaveFolder returns; so your function could basically look like this
    Code:
    def self.getSaveFolder
        return Env.path("ROAMING")
    end
    This isn't anywhere "safe" enough to fully prevent cheating. The most optimal way for that would be what @FireBurn256 suggested and you'd want access to your online files in an ideal situation.
     
    Last edited:
    66
    Posts
    6
    Years
    • Seen May 2, 2020
    Essentials gets the saved games folder path by invoking SHGetKnownFolderPath through Win32API. This uses GUID of the folder paths which you can find documented here. The only annoying bit is that you have to split the GUID into correct hex chunks for def getKnownFolder. I've made a small module for myself to automate this process, and make it a bit easier.

    Code:
    module Env
    
    	COMMON_PATHS = {
    		"CAMERA_ROLL" => "AB5FB87B-7CE2-4F83-915D-550846C9537B",
    		"START_MENU" => "A4115719-D62E-491D-AA7C-E74B8BE3B067",
    		"DESKTOP" => "B4BFCC3A-DB2C-424C-B029-7FE99A87C641",
    		"DOCUMENTS" => "FDD39AD0-238F-46AF-ADB4-6C85480369C7",
    		"DOWNLOADS" => "374DE290-123F-4565-9164-39C4925E467B",
    		"HOME" => "5E6C858F-0E22-4760-9AFE-EA3317B67173",
    		"MUSIC" => "4BD8D571-6D19-48D3-BE97-422220080E43",
    		"PICTURES" => "33E28130-4E1E-4676-835A-98395C3BC3BB",
    		"SAVED_GAMES" => "4C5C32FF-BB9D-43b0-B5B4-2D72E54EAAA4",
    		"SCREENSHOTS" => "b7bede81-df94-4682-a7d8-57a52620b86f",
    		"VIDEOS" => "18989B1D-99B5-455B-841C-AB7C74E4DDFC",
    		"LOCAL" => "F1B32785-6FBA-4FCF-9D55-7B8E7F157091",
    		"LOCALLOW" => "A520A1A4-1780-4FF6-BD18-167343C5AF16",
    		"ROAMING" => "3EB685DB-65F9-4CF6-A03A-E3EF65729F3D",
    		"PROGRAM_DATA" => "62AB5D82-FDC1-4DC3-A9DD-070D1D495D97",
    		"PROGRAM_FILES_X64" => "6D809377-6AF0-444b-8957-A3773F02200E",
    		"PROGRAM_FILES_X86" => "7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E",
    		"COMMON_FILES" => "F7F1ED05-9F6D-47A2-AAAE-29D317C6F066",
    		"PUBLIC" => "DFDF76A2-C82A-4D63-906A-5644AC457385",
    	}
    	
    	def self.path(type)
    		hex = self.guidToHex(COMMON_PATHS[type])
    		return getKnownFolder(hex)
    	end
    	
    	def self.guidToHex(string)
    		chunks = string.split("-")
    		hex = []
    		for i in 0...chunks.length
    			chunk = chunks[i]
    			if i < 3
    				hex.push(chunk.hex)
    			else
    				split = chunk.scan(/../)
    				for s in split
    					hex.push(s.hex)
    				end
    			end
    		end
    		return hex
    	end
    			
    end

    I've recorded most of the common paths and their GUIDs in the module, and you can very easily get the folder path with a simple command such as
    Code:
    Env.path("DOCUMENTS")
    You can edit the save folder by changing the value the def self.getSaveFolder returns; so your function could basically look like this
    Code:
    def self.getSaveFolder
        return Env.path("ROAMING")
    end
    This isn't anywhere "safe" enough to fully prevent cheating. The most optimal way for that would be what @FireBurn256 suggested and you'd want access to your online files in an ideal situation.

    Thanks a lot! I really don't think people would go as far as to install a fresh copy of windows just to duplicate Pokémon anyway.
     

    Luka S.J.

    Jealous Croatian
    1,270
    Posts
    15
    Years
  • You wouldn't even need to go that far. If you're planning on encrypting the game with what's built into RMXP, extracting the scripts from the .rgssad is extremely simple. And after that, anyone can look through the code to properly locate the save file and mess with it as much as they want.
     

    Ego13

    hollow_ego
    311
    Posts
    6
    Years
  • You wouldn't even need to go that far. If you're planning on encrypting the game with what's built into RMXP, extracting the scripts from the .rgssad is extremely simple. And after that, anyone can look through the code to properly locate the save file and mess with it as much as they want.

    Can confirm that. That is really so easy that I was kinda surprised that it worked. And there's pretty much no risc to do so...
     
    66
    Posts
    6
    Years
    • Seen May 2, 2020
    Yea I'm not encrypting it with RPG Maker's encryption thing because it's super easy to decrypt.
     
    Last edited:
    Back
    Top