rubygame-maker

text file protection for Game Maker's GML and RPG Maker XP RGSS


i've been working on 2 projects, a program made in Game Maker 8 and a RPG made in RPG Maker XP, one of the thing i am trying to do is get RPG Maker XP to read a "Score File" made from Game Maker, the score file itself is just a basic text file which both the Game Maker Program and the RPG Maker XP Game will read to gather data.

the problem i face is that if someone was to open this score file in a text editor like notepad, they could change the data and "cheat", so what i have been trying to do is encrypt the file so that at first glance, it's unreadable, have Game Maker and RPG Maker XP decrypt the file, pull all the data out of it and then encrypt it

however i have hitched a snag, the .dll i was working with in Game Maker seems to encrypt/decrypt the score file differently, i tested the .dll by creating 2 identical .txt file with the same text in them and have then encrypted in the 2 programs, the contents was completely different which means that if i try decrypting a file in RPG Maker XP which was encrypted in Game Maker, it will fail

i have tried other .dlls but they don't seem to work in RPG Maker XP, from what i understand, RGSS is a class of Ruby which means any code which would work in Ruby shoudl work in RPG Maker XP and between Ruby and Game Maker's GML, C is the common language the 2 can use .dlls for

so here is what i am asking, is there any .dll, script, code ect. which i can use to protect the data in my text file from being edited outside Game Maker and RPG Maker XP

Troy "Memor-X" Memor

PS: if there is a method that can also work in a .php program that would be great also, but i can work around that if it can't


Solution

  • XOR is a very simple, but quite effective, solution to this problem.

    In GML:

    /// script load_xor_file
    // arguments: filename
    // Prerequisite: Change the "key=" line to your chosen key
    var key, kl, file, len, str, i;
    key = "YOUR SECRET KEY HERE";
    kl = string_length(key);
    file = file_bin_open(argument0,0);
    len = file_bin_size(file);
    str = "";
    for( i=0; i<l; i+=1) {
        str += chr(file_bin_read_byte(file) ^ ord(string_char_at(key,i mod kl + 1)));
    }
    file_bin_close(file);
    return str;
    
    /// script save_xor_file
    // arguments: filename, data
    // Prerequisite: Change the "key=" line to the SAME KEY as in load_xor_file
    var key, kl, file, len, i;
    key = "YOUR SECRET KEY HERE";
    file = file_bin_open(argument0,1);
    file_bin_rewrite(file);
    len = string_length(argument1);
    for( i=0; i<len; i+=1) {
        file_bin_write_byte(file, chr(string_char_at(argument1,i+1)) ^ chr(string_char_at(key,i mod kl + 1)));
    }
    file_bin_close(file);
    

    I have never used RPG Maker myself, but I imagine it wouldn't be too hard to write similar code for it.

    A couple of notes, it doesn't guarantee security. One could decompile the Game Maker EXE and reveal the key, or the key can just straight-up be broken if it is insecure.

    A good, secure key is long, because breaking the encryption relies on the key repeating itself. If the key is the over half the length of the data being encrypted, it is virtually impossible to break the encryption, except by a known-plaintext attack if the file's contents are predictable (for example, I could assume the file contains the player's name and score, so those could be used in a known-plaintext attack).

    Overall, this won't guarantee security of the file, but for your purposes should be more than suitable.

    Also, since you were asking for a possible PHP solution:

    <?php
    function load_xor_file($filename) {
        $key = "YOUR SECRET KEY HERE";
        $in = file_get_contents($filename);
        $keyrep = str_repeat($key,ceil(strlen($in)/strlen($key)));
        return $in ^ $keyrep;
    }
    function save_xor_file($filename,$data) {
        $key = "YOUR SECRET KEY HERE";
        $keyrep = str_repeat($key,ceil(strlen($data)/strlen($key)));
        file_put_contents($filename,$data ^ $keyrep);
    }
    ?>
    

    PS. I know this question is fairly old, but I was just randomly browsing Game Maker tags :p