News:

Use the "Forum Search"
It may help you to find anything in the forum ;).

App sandboxing for OSX

Started by Ashley, March 25, 2012, 06:55:20 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Ashley

According to guidelines for app store submission it's recommended to switch to using the new sandboxing features on the Mac to specify what an app can and can't do. There's lots of information about this here

I'd like to implement this for the native mac port of the game. I'll need to make some changes to the way the game loads files and the locations they are loaded from and wanted to consult with the rest of the developers on this.


Paksets

I plan on offering an in-app download facility for users to obtain paksets, to simplify the process as much as possible. I can provide a nice Mac-native panel with a listing, and easy installation by simply clicking a button. I'll always bundle pak64 along with the game inside the app bundle (so people have something to play by default) but any additional paksets would be placed within the data portion of the app's sandbox folder, e.g. under:

${Home}/Library/Containers/<app_bundle_id>/Data/paksets/

Finally users should be able to install paksets the old-fashioned way as well. This won't work if they modify the app bundle themselves (which must be strictly read-only to avoid code signing issues). Thus I'll implement a third location to search for paksets:

~/simutrans/paksets/

(After installing a pakset users will still have to restart the game, however due to the native mac version running Simutrans itself in a thread within the main app this should be easy to do without needing to restart the app itself).


Configuration

My understanding is that currently Simutrans reads its configuration from three possible places (and the -singleuser command line flag also affects this). These are the user's home directory ~/simutrans/simuconf.tab, the program's directory and per-pakset.

The program directory location will be read-only, the per-pakset ones will also be treated as read-only (along with all the pakset data). The user one will be modifyable by the user as required.


Addons

Addons can be installed manually by users into:

~/simutrans/addons/<pakset name>

This is the current functionality afaics and won't change.


Logs

Log files will go in mac-native locations, under /Library/Logs/ (and will be accessible using the Console utility).


Network save games

These currently get downloaded to a temporary save game file in the program directory. This location will be moved into the sandbox:

${Home}/Library/Containers/<app_bundle_id>/Data/netsaves/


Save games

Autosaves will be stored under:

${Home}/Library/Containers/<app_bundle_id>/Data/autosave/

Users will be able to load saves either in-game (from ~/simutrans/saves/) or by dragging a savegame file onto the app icon/windows (in the Mac-native way). The game will also search the autosave folder to provide a list of autosaved games to load as needed.


Launcher (possible)

One possibility is to change the app so it has an initial launch screen where users can select basic options before loading the game itself, this will roughly equate to a subset of the command line options (and maybe other things specific to the app). I'm undecided on whether this will be needed however. For the iOS version certainly a lot more of the interface will need to be provided in a system-native way.


Save/Load dialogs (Mac native)

Another possibility, to provide system-native dialogs for these functions (e.g. outside of the game).


Screenshots

These will need to be stored somewhere obvious to the user, maybe ~/simutrans/screenshots/



Implementation

My idea on implementing this is to move some of the functionality which is currently in simmain.cc into the platform-specific simsys_XX.cc files. E.g. having a function to determine locations on a platform-specific basis, or hooks to permit opening platform-specific dialogs. Of course the simsys_XX files aren't actually OS-specific, but rather backend specific (e.g. the SDL one is used on multiple platforms) so this may not be the best way to go about it.

Moving this kind of functionality into a separate file per-platform makes it much more maintainable, since maintainers of ports can simply modify their own files rather than having to maintain patches against simmain etc. That's what I like about the simsys_XX interface so far.

So should I implement this using a #define (keeping just simmain.cc), or by using functions defined in simsys_q.mm (and then giving the other simsys_XX.cc files similar methods)?

I'm thinking methods along the lines of:

dr_get_simuconf_location()
dr_get_addons_locations()
dr_get_save_location()

etc.

Which can be overridden as needed.

Does anyone have any suggestions around this kind of refactoring? Or any files which Simutrans needs to write to which I've missed?


Edit:

I've decided for now to go with the approach of creating a simsys_osx.mm file, which can contain OSX-specific stuff (including sandboxing) and replace simsys.cc for this project. simsys_q.mm will contain the things specific to Quartz. Eventually there may be a simsys_ios.mm of course, and the Quartz stuff will be common to the two.
Use Firefox? Interested in IPv6? Try SixOrNot the IPv6 status indicator for Firefox.
Why not try playing Simutrans online? See the Game Servers board for details.

prissi

Anyway, the mac default folder for data is not ~/simutrans but "$HOME/Library/Simutrans"

Ashley

True, I realised that from poking around in the code some more. I'm probably going to keep that as a location for users to add their own paksets.
Use Firefox? Interested in IPv6? Try SixOrNot the IPv6 status indicator for Firefox.
Why not try playing Simutrans online? See the Game Servers board for details.

transporter

You said the app is only available for Lion?

Ashley

#4
Yes, OSX 10.7 and above. I am not too interested in spending time on obsolete platforms (and there's the SDL version anyway...) This effort is to get a version which can be put on the Mac App Store.

Progress so far, I think so far the only methods I've needed to add are:


/* Query log directory */
char const* dr_query_logdir();

/* Query pakset directory location */
char const* dr_query_objdir();


Which return the log directory, and objects directory. I've also modified the pakset selection screen's constructor to take a path, which prevents having umgebung_t::program_dir all over the place.

If we use the dr_query_* methods to ask for specific directories and then always use that output it's really easy to change the entire behaviour around file loading by simply replacing simsys.cc with your own version.

(I still need to implement these methods for the original simsys.cc, then I'll post a patch against Standard).
Use Firefox? Interested in IPv6? Try SixOrNot the IPv6 status indicator for Firefox.
Why not try playing Simutrans online? See the Game Servers board for details.

Ashley

Here's a patch, with stub methods for dr_query_logdir() and dr_query_objdir().

This doesn't actually change anything, but permits me to modify the behaviour for the mac version through a replacement for simsys.cc.

I've also tidied up simmain.cc a bit, improving commenting and the logging messages the game prints on startup.
Use Firefox? Interested in IPv6? Try SixOrNot the IPv6 status indicator for Firefox.
Why not try playing Simutrans online? See the Game Servers board for details.