15

I'm writing a game server in C# and would like to reload or refresh settings from a config file while the server is running.

Ideally I would like to save the settings in an XML file, have the ability to edit the file while the game server is running and then send the server the command to reload the settings from the file.

I know I can use a database to do this as well, but the game server is fairly small and I think it would be more practical to just save settings in a flat-file. I will have file-level access to the machine the server will run on.

What should I use?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
CarelZA
  • 1,217
  • 1
  • 10
  • 12
  • This question feels rather subjective. –  Feb 08 '11 at 15:27
  • 3
    You can set it up so the server auto-loads the file settings with `System.IO.FileSystemWatcher`. If you use a custom `Settings` class, you can simply lock the class, reload it from a file, unlock it (if you are using multiple threads). Reading/writing from/to file or serialization is so trivial in .NET that that is probably not what you need help with. – Jaroslav Jandek Feb 08 '11 at 15:32
  • I have also used FileSystemWatcher in the past. It is quick, easy, and gets the job done. – Joseph Yaduvanshi Feb 08 '11 at 15:35
  • @Jaroslav: Your comment probably should have been posted as an answer. He can't accept it as the answer when it's a comment. – Mike Hofer Feb 08 '11 at 15:58
  • yodaj007 I agree, sorry for that. But check rene's answer, I think it could help many people. – CarelZA Feb 10 '11 at 14:58

4 Answers4

14

Use http://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.aspx

Use a Custom Configuration Section, hookup the sections from the app.config to external config file(s) by setting the location attrib of the section. All xml loading and serialization is done by those custom classes

Code provided by CarelZA:

First of all, ConfigurationManager caches the application's configuration by config section, and you can call ConfigurationManager.RefreshSection() to invalidate the cache for a specific section.

In app.config I added:

<configSections>
  <section name="gameSettings" 
           type="System.Configuration.NameValueSectionHandler,system , Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, Custom=null"/>
</configSections>
<gameSettings configSource="game.config"/>

I created a file called "game.config" and set "Copy to Output Directory" to "Copy always".

In game.config:

<gameSettings>
  <add key="SettingName" value="SettingValue" />
</gameSettings>

Then in code, in order to access any setting:

settings = (NameValueCollection) ConfigurationManager.GetSection("gameSettings");
return settings["SettingName"];

And to reload the game config at any time when the reload command is sent to the server:

ConfigurationManager.RefreshSection("gameSettings");
Community
  • 1
  • 1
rene
  • 41,474
  • 78
  • 114
  • 152
4

As per request posting my comment as an answer:

You can set it up so the server auto-loads the file settings with FileSystemWatcher. If you use a custom Settings class, you can simply lock the class, reload it from a file and unlock it (if you are using multiple threads).

Reading/writing from/to file or serialization is so trivial in .NET that that is probably not what you need help with and there are many options how to do it.

Jaroslav Jandek
  • 9,463
  • 1
  • 28
  • 30
  • Your answer tells me how to check for a changing config file but not what I should use to manage the config file. Also, I specified that I will use a command to reload the config file, it doesn't have to happen automatically. But it is informative, thank you anyway. – CarelZA Feb 10 '11 at 14:35
0

Sounds like a job for XML Serialization! Instead of manually parsing and editing XML, you can easily achieve this same effect by creating a settings object, serializing it to XML, and de/serializing it when you need to make modifications. This way, you could hot swap configuration files.

using System.Xml.Serialization;

For instance, you could have the object

public class Settings
{
  public string SomeProperty {get; set;}
  public string SomeProperty2 {get; set;}
}

Save it to your disk as,

var settings = new Settings {SomeProperty="Hello", SomeProperty2="Joe"};
var fs = new FileStream("settings.xml");
var xs = new XmlSerializer(settings.GetType());
xs.Serialize(fs,settings);

Read it back in as,

var fs = new FileStream("settings.xml");
var settings = (Settings)fs.Deserialize(fs);
George Johnston
  • 31,652
  • 27
  • 127
  • 172
  • Check out the answer by rene. ConfigurationManager already exists for this purpose and I figured out how to use it to do what I need. No need to read and parse XML files myself. – CarelZA Feb 10 '11 at 14:51
0

Check out the MemoryCache in System.Runtime.Caching (.NET 4.0). You could write yourself a simple class which performs the following steps:

  • Load the XML file
  • Parse its contents into whatever representation you want them in
  • Store the output in the cache with a HostFileChangeMonitor watching it - this will cause it to be removed from the cache automatically when the file is changed

Before performing any of the above, you'd check the cache to see if a previously-cached copy of the settings exists and only proceed if it doesn't.

The advantage of rolling your own approach like this is that you do not trigger restarts of the application as is the case with AppSettings stored in your web.config or app.config files. (It should be said that this is not the only way of achieving this)

Luke Bennett
  • 32,786
  • 3
  • 30
  • 57
  • you know that HostFileChangeMonitor is new with .NET 4, right? – John Saunders Feb 08 '11 at 16:08
  • Check out the answer by rene. ConfigurationManager already exists for this purpose and I figured out how to use it to do what I need. No need to read and parse XML files myself. Also, ConfigurationManager caches configuration by section, so it does everything for me. – CarelZA Feb 10 '11 at 14:52