Author Topic: Use %appdata% for storing any runtime-generated files  (Read 4491 times)

0 Members and 1 Guest are viewing this topic.

Offline Mr

  • Inactive Soldat Developer
  • Soldier
  • ******
  • Posts: 166
Use %appdata% for storing any runtime-generated files
« on: May 21, 2011, 06:52:53 am »
Hello everyone,

I think that most of you who use Windows Vista or Windows 7, or those who run Soldat on Windows XP with limited permissions, have expirienced this issue already: Soldat can not write to its own directory where soldat.ini, the profiles, and any downloaded files are stored.
This issue has been "fixed" in 1.5.1 by making the Soldat directory writable by any user by default, however I do not think that this is a solution. In fact it makes things even worse, gives a false sense of security. A user with limited permissions could replace Soldat.exe with a malicious application which is launched as administrator once an admin starts the game.

Another even bigger issue is the usuability when multiple users are using the same computer. If one user makes changes to Soldat, they are reflected on the other user's account. Having profiles does not really help much here as also the default profile which is being used is stored and reflected on other Windows accounts. Using %appdata% would solve all these issues.

When Windows 2000 has been intoduced, Microsoft set it as standard that all applications must use the %appdata% directory for storing runtime-generated files. Games and other programs which do not need to access the whole computer with all your files should not necessarily be given administrator permissions either.

I therefore suggest the following changes:

1) The SoldatDirectory/soldat.ini file should be copied to %appdata%/Soldat/soldat.ini if it does not exist yet. This also enables having soldat.ini as template for all new accounts, which automatically means that you can keep your settings when upgrading to a version which implements this changes. Soldat should then only load and update settings from the new file.

2) Move the Profiles directory to %appdata%/Soldat/Profiles/, create it on first run.

3) Instead of downloading files to SoldatDirectory/<name>/<filename>.<ext> directly, it should download them to %localappdata%/Soldat/Downloads/<name>/<filename>.<ext>
When the game now loads a map, it should first look for the file in %localappdata%/Downloads/. This way the user can override things like scenery using full modifications without having to replace files in the installation directory. Next, it should look for them in the installation directory for loading default maps and objects.
This change makes it very easy to reset a Soldat installation to default or delete any broken or incompatible maps without having to reinstall the whole game because default maps have been deleted.

4) Install Soldat in C:\Program Files (x86)\ (or the XP/2kSP4 equivalent) by default and keep the directory read-only for normal users for making the installation secure again.

EDIT: minus suggested that %localappdata% should be used for storing the downloaded files instead. In case that anyone should ever get the idea to run Soldat on a terminal server or a system which is in a domain and set to sync the appdata directory this is indeed the better solution. I have updated 3), thank you minus!
« Last Edit: May 23, 2011, 04:35:39 am by Mr »

Offline Shoozza

  • Retired Soldat Developer
  • Veteran
  • ******
  • Posts: 1632
  • Soldat's Babysitter
    • Website
Re: Use %appdata% for storing any runtime-generated files
« Reply #1 on: May 22, 2011, 04:51:27 pm »
Sounds good will be added.

I'm not sure if it will make it in the 1.5.1 release.
Unless everyone thinks it's worth to delay the release to add this feature ;P
Rules
Tools: ARSSE - SARS - SRB - chatMod

Offline FliesLikeABrick

  • Administrator
  • Flamebow Warrior
  • *****
  • Posts: 6144
    • Ultimate 13 Soldat
Re: Use %appdata% for storing any runtime-generated files
« Reply #2 on: May 22, 2011, 07:37:13 pm »
YES please do this.  I've been wanting this to be fixed for years since it's the source of most or all of the "must be run as administrator" problems!

Offline Shoozza

  • Retired Soldat Developer
  • Veteran
  • ******
  • Posts: 1632
  • Soldat's Babysitter
    • Website
Re: Use %appdata% for storing any runtime-generated files
« Reply #3 on: May 23, 2011, 05:48:43 am »
All right.

I think we should also add the version number to allow multiple installations of different soldat versions:
1) copy %RootDirectory%\soldat.ini to %appdata%/Soldat/1.5.1/soldat.ini (if missing)
2) move %RootDirectory%\Profiles\ to %appdata%/Soldat/1.5.1/Profiles/ (create if missing)
3) instead of downloading into %RootDirectory%\<name>\<filename>.<ext> download into %localappdata%/Soldat/1.5.1/Downloads/<name>/<filename>.<ext>
4) change install folder from C:\Soldat\ to %programfiles%/Soldat/1.5.1/
5) keep support for the "old way" on pre windows 2000 versions
6) add a link to the %appdata%/Soldat/1.5.1/ in the %programfiles%/Soldat/1.5.1/ folder
7) add a link to the %localappdata%/Soldat/1.5.1/Downloads/ in the %programfiles%/Soldat/1.5.1/ folder (%localappdata% env variable is undefined on 2000 and XP)

Workarounds for missing %localappdata% environment variable on Windows 2000 and XP:
* create a link to the folder by reading the registry (not sure but maybe different users can have different %localappdata% folder settings)
* create a link to the folder assuming the default folder (falis when the folder has been changed - e.g. windows installed on D:\)
* add the current local appdata folder to the environment (same as above)
* add the default local appdata folder to the environment (samve as above)
* create a batch file which reads the registry and opens the folder (the necessary REG command is missing on Windows 2000)
* create a link which reads the registry and opens the folder (the necessary REG command is missing on Windows 2000):
   %windir%\system32\cmd.exe /C @FOR /F "tokens=3*" %a in ('REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" /v "Local AppData" 2^>NUL ^| FINDSTR /C:"REG_SZ"') do @%windir%\explorer.exe /n,"%b\Soldat\1.5.1"
* create an exe file which opens the folder
* create batch file which runs shell command and opens the folder:
   %windir%\explorer.exe /n,shell:local appdata
* create link which runs shell command and opens the folder: %windir%\explorer.exe /n,shell:local appdata (looks like the best solution if it works under win2000 this can't browse inside subfolders of local appdata)

Other things to remember:
Soldat has some cheat program detection stuff (E.g. it writes files on C:\, reads window titles, etc) which needs to be disabled/removed in order to run it as non admin.

Related questions:
How does GNU/Linux and Mac OS X handle the user folder stuff?
How could Soldats folder structure look on these Operating Systems?
Any changes to the soldatserver stuff necessary? If yes, which?
« Last Edit: August 03, 2011, 09:34:34 pm by Shoozza »
Rules
Tools: ARSSE - SARS - SRB - chatMod

Offline FliesLikeABrick

  • Administrator
  • Flamebow Warrior
  • *****
  • Posts: 6144
    • Ultimate 13 Soldat
Re: Use %appdata% for storing any runtime-generated files
« Reply #4 on: May 23, 2011, 08:12:43 am »
Everything non-windows handles the user directory the same since home directories are much much more strictly used in them.  the $HOME environment variable points to a user's home directory, and application configs are created in directories (or single files if it's a single config file) like .soldat.  In non-Windows, a . at the beginning of a filename means that the file/directory is generally treated as a "hidden" file, even though there's no special file attributes on it. 

Now note that on a mac, almost all native mac applications save their appdata in ~/Library somewhere, you'll have to read more about that if you're writing something that will run natively on mac instead of in a terminal or under X.  Terminal/CLI and X apps are the main ones that write to .config files on mac.

Example:


nova-dhcp-host111:~ ryan$ echo $HOME
/Users/ryan
nova-dhcp-host111:~ ryan$ cd $HOME
nova-dhcp-host111:~ ryan$ ls -a | egrep '^\.'
.
..
.CFUserTextEncoding
.DS_Store
.Trash
.Xauthority
.bash_history
.cc
.config
.cups
.dvdcss
.f
.fontconfig
.gem
.htoprc
.irssi
.lab
.lesshst
.macports
.mplayer
.profile
.profile.macports-saved_2011-01-31_at_11:19:56
.recently-used.xbel
.serverauth.326
.serverauth.350
.serverauth.568
.serverauth.63460
.serverauth.7224
.serverauth.8722
.serverauth.930
.ssh
.subversion
.todo
.todo.save
.viminfo
.wireshark
.wireshark-etc
nova-dhcp-host111:~ ryan$



But on BSD/Linux, it's exactly how I originally described above.
« Last Edit: May 23, 2011, 08:30:09 am by FliesLikeABrick »

Offline Mr

  • Inactive Soldat Developer
  • Soldier
  • ******
  • Posts: 166
Re: Use %appdata% for storing any runtime-generated files
« Reply #5 on: May 24, 2011, 12:27:54 am »
The SHGetSpecialFolderPath function can be used for receiving paths to the %appdata% and %localappdata% directories. The function works on Windows 2000 and up.

Following parameters can be used for the csidl parameter:
http://msdn.microsoft.com/en-us/library/bb762494%28v=vs.85%29.aspx

CSIDL_APPDATA
CSIDL_LOCAL_APPDATA

If the function returns TRUE, the folder is guranteed to be usable by an application. This should always be the case for the AppData directory.
If the function fails for the Local_AppData query, the game should use the path returned by the AppData query.

I generally agree to having version numbers for supporting multiple installations, the installer however has to make sure that the changes from old versions do not get lost if the application is upgraded. It also should ask the user if a specific game data directory should be removed on deinstallation.
In 6) and 7) you mentioned creating links to the %appdata% directory in %programfiles%. This is not good practice as the links then point to directories that are not readable for other users of the computer and again require administrator rights to be created.

Offline Shoozza

  • Retired Soldat Developer
  • Veteran
  • ******
  • Posts: 1632
  • Soldat's Babysitter
    • Website
Re: Use %appdata% for storing any runtime-generated files
« Reply #6 on: May 24, 2011, 11:29:55 am »
Thanks for the information.
I ready did some research on getting appdata and localappdata folders in soldat (new functions for getting appdata and localappdata were added yesterday).
However it will probably take a while to find every single file access and change it if necessary.

About the link to %appdata% in %programfiles%: It will ofc be created when soldat gets installed and it will use the placeholders which should allow all users to get into the correct appdata and localappdata folders when hey click on the link files.


The mac stuff has time. Will read about when I really need to know how it works. Just though maybe someone knows the exact details :P
Rules
Tools: ARSSE - SARS - SRB - chatMod

Offline FliesLikeABrick

  • Administrator
  • Flamebow Warrior
  • *****
  • Posts: 6144
    • Ultimate 13 Soldat
Re: Use %appdata% for storing any runtime-generated files
« Reply #7 on: May 24, 2011, 09:47:42 pm »
yeah sorry, I'm more help with the non-mac unix systems than mac right now.  I'll take a look into it if I have time to try and get you more mac-specific info

Offline DorkeyDear

  • Veteran
  • *****
  • Posts: 1507
  • I also go by Curt or menturi
Re: Use %appdata% for storing any runtime-generated files
« Reply #8 on: May 28, 2011, 12:36:56 pm »
I did run into a couple of problems when installing MSAC in Soldat 1.5.1. I installed MSAC, and when I tried to open Soldat, it ran in fullscreen with a different resolution. I was a bit confused at the time about why this happened, but after a bit of chatting, I resolved the issue. Before, when I modified my configuration files via config.exe, it actually had the files in the VirtualStore directory, which I have not even heard of prior to today. The 'fix' was simply moving all those files back into the Soldat directory, deleting the VirualStore's Soldat directory, and having the Soldat direcory and all its files set as full privledges.

The suggestion that Mr proposed (among others who posted here) sound like an awesome idea that will resolve this complication that others may have as well. I was not very familiar with privledges, VirtualStore, administrator rights, etc., but I ended up figuring it out with some help. There may be others who would have a more difficult time figuring it out than I, and even possibly not play Soldat because of it (e.g. new players who have never played Soldat before may not feel as though it is worth the effort).

My point is that I support this. Whether it is implemented in the next version of Soldat, or the one after that, that is up to you guys to decide. It should hopefully resolve the issue I had earlier today.

I often times do have multiple versions of Soldat installed at a single time, so I support this as well. I'm not exactly sure what the behavior should be upon installation of a new version, but a few possibility could be:

(a) Only install a fresh configuation file. Configuration would not be directly transfered from other older versions of Soldat into the newly installed on. Everything is default values. This is pretty much the easiest way out.

(b) Have the user choose installing fresh new configuration file, or copying old file from a chosen configuration. Any newly added 'variables' (for lack of a better word) to the config would be added as default values. A possible frustration is the necessity to change configurations in multiple versions of Soldat in order to get the config the same for all the versions. Soldat profiles can transfer over as well, with the newly added variables added to the config; this could be optional.

(c) Having an 'inheritance' scheme for config files would be nice. There would be a base default config file located somewhere. Upon installing a new version of Soldat, it would have the newly created configuration inherit values from this base config file (not just copy them). It could be possible to have the config be able to inherit from not only this base file, but I don't feel as though that is very necessary. Allowing such thing would make it easier to have separate configurations setup ready to be used (e.g. full-screen, high-resolution compared to windowed, low-resolution). Upon installing a new version of Soldat, it could be a user choice where to put the newly added variables, whether in the base file, or the newly created config file. I'm not quite sure what is the better choice. The advantage of this would be you can change a single variable in one single config file, and have it change for multiple profiles in multiple versions of Soldat. Note: it could be possible to inherit multiple files, but I'm not quite sure how that would work.

The third option is probably too much wishing, but it really wouldn't be that hard to implement in my opinion. Psudeocode:
Code: [Select]
LoadConfig(filename: string): IniFile;
IniFile file = Ini.LoadFile(filename);
if (file.HasKey('General', 'InheritConfig')) // and file exists etc.
IniFile inherited_file = LoadConfig(file.get('General', 'InheritConfig'))
file = inherited_file.Merge(file); // anything in inherited_file is replaced by whatever file contains
return file;
I'm not quite sure why I wrote that; I guess I'm just having fun. :P

Offline Shoozza

  • Retired Soldat Developer
  • Veteran
  • ******
  • Posts: 1632
  • Soldat's Babysitter
    • Website
Re: Use %appdata% for storing any runtime-generated files
« Reply #9 on: May 28, 2011, 06:46:02 pm »
Imho we should go with (a) for the full installer.
The updater could copy the previous versions soldat.ini, server.ini and profiles to the new versions folder (for soldat 1.5.1 it would just look at 1.5.0 config files any older files will be ignored).
The config files should be independent from each other so no base ini and derivate stuff (could confuse people when stuff changes in other soldat installations).
Rules
Tools: ARSSE - SARS - SRB - chatMod

Offline DorkeyDear

  • Veteran
  • *****
  • Posts: 1507
  • I also go by Curt or menturi
Re: Use %appdata% for storing any runtime-generated files
« Reply #10 on: May 28, 2011, 10:18:35 pm »
Yeah (a) is the simplest, nothing more complicated is really necessary. Inheritance would be confusing. Just a thought: default inheriting nothing, but still a cool feature that could be available. Hehe jk`ing (kind of); I don't really expect that :P. In any case, here were my concerns when I mentioned my ideas:

-Keeping old configs from old versions of Soldat -- to avoid needing to reconfigure your Soldat every time a new installation is done in a new separate location
-When playing multiple versions of Soldat often, if you need to change a config, you need to change it in many locations (not a big deal with 1 or 2 installations, but after more it could get annoying; but i guess its not often where a person switches between many versions of Soldat)
-When switching between similar but slightly different configs (with various combinations; e.g. 'developers configuration' (e.g. windowed mode, taunts set to common script controls, etc.), 'serious gaming time' (e.g. fullscreen, taunts set to 'EFC up' etc.), & 'for fun' (funny colors, fun interface, etc.) setups, each inheriting common characteristics (e.g. controls, ))

The last two I can't see being very important, as they are specific case issues. I was more of dreaming when coming up with the idea of configuration inheritance (hehe).