bzt {l Wrote}:Well, I don't know about fossil, but I've used CVS, SVN and Hg for a long time, and technically speaking git is far more superior to all of them.
I cannot judge CVS, SVN, Hg, since I have not read the documentation of them, but probably you are correct. (Fossil isn't perfect either, but their object formats and protocols are less confusing than git, and the command-line interface is also less confusing than git. I had made up (but not implemented, yet) "Generalized Fossil" which is slightly a variant of fossil, to improve what I consider are the problems; it is compatible enough anyways that an implementation of Generalized Fossil could reconstruct a deconstructed Fossil repository and all of the same structures will be present.)
I do have an account on GitHub (I needed to create the account on another computer but then I could access it on this computer), which I did that I might be able to write issues on other projects. Although some features of GitHub require JavaScripts, some don't; reading the file lists and files, and reading the API documentation, does not require JavaScripts. I do not use it for my own projects (although mirrors on GitHub and other services would still be possible, which I might do in future; currently the only mirror is on Chisel).
Considering SQL injection is important, but that's not what I meant here. For example, you've said keyboard assignments are also stored in SQL. What if someone sets the key to left movement "Left" and right movement "Funky"+"Left"? Obviously there's no such key as "Funky", but with a trivial verification and invalid key removal now you'll end up having both left and right keys set to "Left". I meant things like that when I said you have to do a lot of sanity checks if you allow modifications outside of your game.
If the user wants to assign them strangely, the program should not stop it. The software should not try to believe that what the user deliberately entered is wrong and that you really want something else; too many modern designs do that and I do not like that. A better design is that you have enough ropes to hang yourself and also a few more just in case; that is the UNIX philosophy, and it is better than Microsoft, Google, etc.
(This is especially the problem in web browsers that do not let end users do what you want to do, and tries to override your decisions and hides things from you. This is why I still use a very old version (and I still need to heavily customize it to make it being reasonable, and still many things aren't working reasonably); the new ones are bad in many ways. They keep removing good features and adding bad ones instead.)
(I have game "amoebax" (also FOSS) and the configuration menu does not allow to set the same keys for both players. Nevertheless that is what I wanted to do, but fortunately, I found the configuration file and edited that and that did what I wanted it to do.)
zzo38 {l Wrote}:Actually it does help, as long as the system administrator does not tamper with the scores.
You see, that's exactly the problem. For a typical end user they are the system administrator too. There's no difference between a user tampering with the files and the system administrator tempering with the files because the machine owner, who is the player user, also has root privileges (or sudo).
Yes, although I meant the situation in which case a local server is used; for a single user system, probably no server will be used. The user is only cheating themself, and as I explained, verification of scores is possible anyways. Even if you are on a multiuser system, it could use a server which is configured to expose move lists and puzzle sets, in which case the system administrator cannot effectively cheat because any user can verify the scores.
Yes it would, because then you would need to have a software that can modify encrypted sqlite databases. To have such a software, you'd have to patch and compile the sqlite REPL, which is not something an average user can (or willing) to do. (There's no protection from experts, anything can be hacked. In the security industry we say a data is considered to be protected and safe not if the encryption is unbreakable (which could never be), rather when the price of hacking is higher than the value of the encrypted data.)
The data belongs to the end user so they can do what they want to do with it. Being able to access and modify the database is useful, even if it is not normally needed; a user can do so at their own risk.
zzo38 {l Wrote}:There is actually two files; the database file and the puzzle set file. Both file formats are documented.
Right, and that is a wise separation. What I'm trying to say is with the necessity of checks is, while the puzzle set file has a custom format, so it can only be modified through
your program, where you can enforce the logic and consistency, but with a database file you allow modification through 3rd party software (the sqlite3 REPL), which will
not enforce your logic at all.
It is not quite true. A non-composite puzzle set is four files, three of which are Hamster archive files, and one of which is a plain text file (which is expected to be read and altered using a text editor). A composite puzzle set is a Hamster archive file containing the other four (and is considered to be read-only; you must split them into separate files if you want to be able to edit them). Hamster archive format is not a common format, but this repository does contain a program (misc/har.c) for dealing with them; the UNLUMP and RELUMP programs included with OHRRPGCE can also deal with them (although they have less capabilities than har). (I had been trying to see if 7z, libarchive, etc could also implement Hamster archive format, but they have not done so at this time.)
You must be prepared that you'll read inconsistent garbage from the database (hopefully you won't) You see, the difference is, using a custom format makes tempering with the puzzle files not part of normal operation, however by your own admission tempering with the database through 3rd party software is normal and allowed. And your program must not segfault during normal operation, no matter what (that's always a bug if it does).
SQLite has integrity checks in case the database is inconsistent. Regardless of the file formats, and regardless of whether or not any external programs support editing these formats, what is important is that untrusted files (in this case, the puzzle set files) do not cause security problems or other undesired operations. Trusted files (the database) is private and it is assumed that whatever the user puts in there is desired.
(There are also many virtual tables and temporary tables which are exposed to the end user (this is documented). It is intended that the user can use them if they are believed to be useful to you. I have found them useful a few times, although non-advanced users might not have any use for them, which is also OK.)
I agree that the program must not segfault during normal operation and that it is a bug if it does.
zzo38 {l Wrote}:Avoiding encrypting the files also makes the program simpler,
Actually in your case it won't, using encryption would be simpler (sqlite3aes is totally transparent to your application. You have to make one additional call after opening the database, but that's it). But I don't want to pressure you to use encryption, all I want to do is, make you aware what you must check everything you read from the database if you allow db access outside the game.
I believe it is best to allow you to have enough ropes to hang yourself and also a few more just in case; it should not try to hide things from the user or try to outguess you.
I've checked your code. Not bad at all, but it definitely lacks some more compile time and runtime checks. Have you tried to run it through valgrind for example? I suggest that you do, it has very very useful reports.
I have used valgrind for testing; it is very good. Sometimes this helped me to find some bugs.
Which other compile time and runtime checks do you suggest? (Please be specific. "Check the file" is not specific enough.)
And also if I were you, I'd consider rewriting it for SDL2 (the render interface instead of the surface interface). Looking at your code I think it shouldn't be too hard, with surfaces you lock the surface to get the pixel buffer pointer and then you modify the buffer directly (mostly). This is pretty much the same with render, you lock the texture to get the pixel buffer's address, and then you can modify the buffer directly. This means the main logic and most parts of your game can be left untouched, you'll only have to replace the locking/unlocking part to make it SDL2 compatible.
I have looked at SDL2, and I think there are some advantages and disadvantages compared with SDL1. If you want to run it on a computer with SDL2 but is not compatible with SDL1 (maybe Wayland, but I don't actually know), you may consider using the SDL compatibility layer (I have seen at least two such compatibility layers). If some feature does not work with the compatibility layer, you can report this, and I can consider whether to either fix it in my program or to forward the report to the authors of the compatibility layer for them to fix it instead.
I also wrote a PORTING file, with notes in case anyone wishes to port it to anything or include it in any kind of distributions, and some of the considerations about doing so. Probably exec.c will be used as is or nearly as is, and other files might need more modifications or being replaced entirely (possibly copying some code from them).
Anyway, well done, your project looks good! I like puzzles, I like the idea that you can create puzzles, and also it is written in C, one of the most bullet-proof and powerful languages in the world! Nice job!
Good.
Another comment: The database is not related to the game logic. This means that an alternative implementation which uses the same game logic can use an entirely different database (or none at all), different user interfaces, etc, and still be compatible with the same puzzle set files and same games.
Note that any puzzle set that includes solutions are also test cases for the game logic; you can run "heromesh -a" to automatically test them (and report any errors that occur). This means that in case of porting or changes (either to the puzzle set's class definitions or to the game engine implementation) can be tested that they do not break the existing game logic.