diff --git a/dep/ini-parser/INIFileParser.License b/dep/ini-parser/INIFileParser.License
new file mode 100644
index 00000000..67901943
--- /dev/null
+++ b/dep/ini-parser/INIFileParser.License
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2008 Ricardo Amores Hernández
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/dep/ini-parser/INIFileParser.dll b/dep/ini-parser/INIFileParser.dll
new file mode 100644
index 00000000..d19e920f
Binary files /dev/null and b/dep/ini-parser/INIFileParser.dll differ
diff --git a/dep/ini-parser/INIFileParser.xml b/dep/ini-parser/INIFileParser.xml
new file mode 100644
index 00000000..7d5e96bc
--- /dev/null
+++ b/dep/ini-parser/INIFileParser.xml
@@ -0,0 +1,1181 @@
+
+
+
+ INIFileParser
+
+
+
+
+ Asserts that a strings has no blank spaces.
+
+ The string to be checked.
+
+
+
+
+ Represents an INI data parser for files.
+
+
+
+
+ Ctor
+
+
+
+
+ Ctor
+
+
+
+
+
+ Implements reading ini data from a file.
+
+
+ Uses codification for the file.
+
+
+ Path to the file
+
+
+
+
+ Implements reading ini data from a file.
+
+
+ Path to the file
+
+
+ File's encoding.
+
+
+
+
+ Saves INI data to a file.
+
+
+ Creats an ASCII encoded file by default.
+
+
+ Path to the file.
+
+
+ IniData to be saved as an INI file.
+
+
+
+
+ Writes INI data to a text file.
+
+
+ Path to the file.
+
+
+ IniData to be saved as an INI file.
+
+
+ Specifies the encoding used to create the file.
+
+
+
+
+ Represents all data from an INI file
+
+
+
+
+ Represents all sections from an INI file
+
+
+
+
+ Initializes an empty IniData instance.
+
+
+
+
+ Initializes a new IniData instance using a previous
+ .
+
+
+ object containing the
+ data with the sections of the file
+
+
+
+
+ Configuration used to write an ini file with the proper
+ delimiter characters and data.
+
+
+ If the instance was created by a parser,
+ this instance is a copy of the used
+ by the parser (i.e. different objects instances)
+ If this instance is created programatically without using a parser, this
+ property returns an instance of
+
+
+
+
+ Global sections. Contains key/value pairs which are not
+ enclosed in any section (i.e. they are defined at the beginning
+ of the file, before any section.
+
+
+
+
+ Gets the instance
+ with the specified section name.
+
+
+
+
+ Gets or sets all the
+ for this IniData instance.
+
+
+
+
+ Used to mark the separation between the section name and the key name
+ when using .
+
+
+ Defaults to '.'.
+
+
+
+
+ Creates a new object that is a copy of the current instance.
+
+
+ A new object that is a copy of this instance.
+
+
+
+
+ See property for more information.
+
+
+
+
+ Deletes all comments in all sections and key values
+
+
+
+
+ Merges the other iniData into this one by overwriting existing values.
+ Comments get appended.
+
+
+ IniData instance to merge into this.
+ If it is null this operation does nothing.
+
+
+
+
+ Attempts to retrieve a key, using a single string combining section and
+ key name.
+
+
+ The section and key name to retrieve, separated by .
+
+ If key contains no separator, it is treated as a key in the section.
+
+ Key may contain no more than one separator character.
+
+
+ If true is returned, is set to the value retrieved. Otherwise, is set
+ to an empty string.
+
+
+ True if key was found, otherwise false.
+
+
+ key contained multiple separators.
+
+
+
+
+ Retrieves a key using a single input string combining section and key name.
+
+
+ The section and key name to retrieve, separated by .
+
+ If key contains no separator, it is treated as a key in the section.
+
+ Key may contain no more than one separator character.
+
+
+ The key's value if it was found, otherwise null.
+
+
+ key contained multiple separators.
+
+
+
+
+ Merge the sections into this by overwriting this sections.
+
+
+
+
+ Merges the given global values into this globals by overwriting existing values.
+
+
+
+
+ Information associated to a key from an INI file.
+ Includes both the value and the comments associated to the key.
+
+
+
+
+ Initializes a new instance of the class.
+
+
+
+
+ Initializes a new instance of the class
+ from a previous instance of .
+
+
+ Data is deeply copied
+
+
+ The instance of the class
+ used to create the new instance.
+
+
+
+
+ Gets or sets the comment list associated to this key.
+
+
+
+
+ Gets or sets the value associated to this key.
+
+
+
+
+ Gets or sets the name of the key.
+
+
+
+
+ Creates a new object that is a copy of the current instance.
+
+
+ A new object that is a copy of this instance.
+
+
+
+
+ Represents a collection of Keydata.
+
+
+
+
+ Initializes a new instance of the class.
+
+
+
+
+ Initializes a new instance of the class with a given
+ search comparer
+
+
+ Search comparer used to find the key by name in the collection
+
+
+
+
+ Initializes a new instance of the class
+ from a previous instance of .
+
+
+ Data from the original KeyDataCollection instance is deeply copied
+
+
+ The instance of the class
+ used to create the new instance.
+
+
+
+
+ Gets or sets the value of a concrete key.
+
+
+ If we try to assign the value of a key which doesn't exists,
+ a new key is added with the name and the value is assigned to it.
+
+
+ Name of the key
+
+
+ The string with key's value or null if the key was not found.
+
+
+
+
+ Return the number of keys in the collection
+
+
+
+
+
+ Adds a new key to the collection
+
+
+ KeyData instance.
+
+
+ true if the key was added false if a key with the same name already exist
+ in the collection
+
+
+
+
+ Adds a new key with the specified name and value to the collection
+
+
+ Name of the new key to be added.
+
+
+ Value associated to the key.
+
+
+ true if the key was added false if a key with the same name already exist
+ in the collection.
+
+
+
+
+ Clears all comments of this section
+
+
+
+
+ Gets if a specifyed key name exists in the collection.
+
+ Key name to search
+ true if a key with the specified name exists in the collectoin
+ false otherwise
+
+
+
+ Retrieves the data for a specified key given its name
+
+ Name of the key to retrieve.
+
+ A instance holding
+ the key information or null if the key wasn't found.
+
+
+
+
+ Deletes all keys in this collection.
+
+
+
+
+ Deletes a previously existing key, including its associated data.
+
+ The key to be removed.
+
+ true if a key with the specified name was removed
+ false otherwise.
+
+
+
+
+ Sets the key data associated to a specified key.
+
+ The new for the key.
+
+
+
+ Allows iteration througt the collection.
+
+ A strong-typed IEnumerator
+
+
+
+ Implementation needed
+
+ A weak-typed IEnumerator.
+
+
+
+ Creates a new object that is a copy of the current instance.
+
+
+ A new object that is a copy of this instance.
+
+
+
+
+ Collection of KeyData for a given section
+
+
+
+
+ Information associated to a section in a INI File
+ Includes both the value and the comments associated to the key.
+
+
+
+
+ Initializes a new instance of the class.
+
+
+
+
+ Initializes a new instance of the class
+ from a previous instance of .
+
+
+ Data is deeply copied
+
+
+ The instance of the class
+ used to create the new instance.
+
+
+ Search comparer.
+
+
+
+
+ Deletes all comments in this section and key/value pairs
+
+
+
+
+ Deletes all the key-value pairs in this section.
+
+
+
+
+ Merges otherSection into this, adding new keys if they don't exists
+ or overwriting values if the key already exists.
+ Comments get appended.
+
+
+ Comments are also merged but they are always added, not overwritten.
+
+
+
+
+
+ Gets or sets the name of the section.
+
+
+ The name of the section
+
+
+
+
+ Gets or sets the comment list associated to this section.
+
+
+ A list of strings.
+
+
+
+
+ Gets or sets the keys associated to this section.
+
+
+ A collection of KeyData objects.
+
+
+
+
+ Creates a new object that is a copy of the current instance.
+
+
+ A new object that is a copy of this instance.
+
+
+
+
+ Represents a collection of SectionData.
+
+
+
+
+ Initializes a new instance of the class.
+
+
+
+
+ Initializes a new instance of the class.
+
+
+ StringComparer used when accessing section names
+
+
+
+
+ Initializes a new instance of the class
+ from a previous instance of .
+
+
+ Data is deeply copied
+
+
+ The instance of the class
+ used to create the new instance.
+
+
+
+ Returns the number of SectionData elements in the collection
+
+
+
+
+ Gets the key data associated to a specified section name.
+
+ An instance of as class
+ holding the key data from the current parsed INI data, or a null
+ value if the section doesn't exist.
+
+
+
+ Creates a new section with empty data.
+
+
+ If a section with the same name exists, this operation has no effect.
+
+ Name of the section to be created
+ true if the a new section with the specified name was added,
+ false otherwise
+ If the section name is not valid.
+
+
+
+ Adds a new SectionData instance to the collection
+
+ Data.
+
+
+
+ Removes all entries from this collection
+
+
+
+
+ Gets if a section with a specified name exists in the collection.
+
+ Name of the section to search
+
+ true if a section with the specified name exists in the
+ collection false otherwise
+
+
+
+
+ Returns the section data from a specify section given its name.
+
+ Name of the section.
+
+ An instance of a class
+ holding the section data for the currently INI data
+
+
+
+
+ Sets the section data for given a section name.
+
+
+ The new instance.
+
+
+
+
+
+
+ true if the section with the specified name was removed,
+ false otherwise
+
+
+
+ Returns an enumerator that iterates through the collection.
+
+
+ A that can be used to iterate through the collection.
+
+
+
+
+ Returns an enumerator that iterates through a collection.
+
+
+ An object that can be used to iterate through the collection.
+
+
+
+
+ Creates a new object that is a copy of the current instance.
+
+
+ A new object that is a copy of this instance.
+
+
+
+
+ Data associated to this section
+
+
+
+
+ Configuration used to write an ini file with the proper
+ delimiter characters and data.
+
+
+ If the instance was created by a parser,
+ this instance is a copy of the used
+ by the parser (i.e. different objects instances)
+ If this instance is created programatically without using a parser, this
+ property returns an instance of
+
+
+
+
+ Formats a IniData structure to an string
+
+
+
+
+ Produces an string given
+
+ The data to string.
+ Ini data.
+
+
+
+ Configuration used by this formatter when converting IniData
+ to an string
+
+
+
+
+ Represents all data from an INI file exactly as the
+ class, but searching for sections and keys names is done with
+ a case insensitive search.
+
+
+
+
+ Initializes an empty IniData instance.
+
+
+
+
+ Initializes a new IniData instance using a previous
+ .
+
+
+ object containing the
+ data with the sections of the file
+
+
+
+
+ Copies an instance of the class
+
+ Original
+
+
+
+ Defines data for a Parser configuration object.
+
+ With a configuration object you can redefine how the parser
+ will detect special items in the ini file by defining new regex
+ (e.g. you can redefine the comment regex so it just treat text as
+ a comment iff the comment caracter is the first in the line)
+ or changing the set of characters used to define elements in
+ the ini file (e.g. change the 'comment' caracter from ';' to '#')
+ You can also define how the parser should treat errors, or how liberal
+ or conservative should it be when parsing files with "strange" formats.
+
+
+
+ Default values used if an instance of
+ is created without specifying a configuration.
+
+
+ By default the various delimiters for the data are setted:
+ ';' for one-line comments
+ '[' ']' for delimiting a section
+ '=' for linking key / value pairs
+
+ An example of well formed data with the default values:
+
+ ;section comment
+ [section] ; section comment
+
+ ; key comment
+ key = value ;key comment
+
+ ;key2 comment
+ key2 = value
+
+
+
+
+
+
+ Copy ctor.
+
+
+ Original instance to be copied.
+
+
+
+
+ Sets the char that defines the start of a section name.
+
+
+ Defaults to character '['
+
+
+
+
+ Sets the char that defines the end of a section name.
+
+
+ Defaults to character ']'
+
+
+
+
+ Retrieving section / keys by name is done with a case-insensitive
+ search.
+
+
+ Defaults to false (case sensitive search)
+
+
+
+
+ Sets the char that defines the start of a comment.
+ A comment spans from the comment character to the end of the line.
+
+
+ Defaults to character ';'
+
+
+
+
+ Sets the string that defines the start of a comment.
+ A comment spans from the mirst matching comment string
+ to the end of the line.
+
+
+ Defaults to string ";"
+
+
+
+
+ Gets or sets the string to use as new line string when formating an IniData structure using a
+ IIniDataFormatter. Parsing an ini-file accepts any new line character (Unix/windows)
+
+
+ This allows to write a file with unix new line characters on windows (and vice versa)
+
+ Defaults to value Environment.NewLine
+
+
+
+ Sets the char that defines a value assigned to a key
+
+
+ Defaults to character '='
+
+
+
+
+ Sets the string around KeyValuesAssignmentChar
+
+
+ Defaults to string ' '
+
+
+
+
+ Allows having keys in the file that don't belong to any section.
+ i.e. allows defining keys before defining a section.
+ If set to false and keys without a section are defined,
+ the will stop with an error.
+
+
+ Defaults to true.
+
+
+
+
+ If set to false and the finds duplicate keys in a
+ section the parser will stop with an error.
+ If set to true, duplicated keys are allowed in the file. The value
+ of the duplicate key will be the last value asigned to the key in the file.
+
+
+ Defaults to false.
+
+
+
+
+ Only used if is also true
+ If set to true when the parser finds a duplicate key, it overrites
+ the previous value, so the key will always contain the value of the
+ last key readed in the file
+ If set to false the first readed value is preserved, so the key will
+ always contain the value of the first key readed in the file
+
+
+ Defaults to false.
+
+
+
+
+ Gets or sets a value indicating whether duplicate keys are concatenate
+ together by .
+
+
+ Defaults to false.
+
+
+
+
+ If true the instance will thrown an exception
+ if an error is found.
+ If false the parser will just stop execution and return a null value.
+
+
+ Defaults to true.
+
+
+
+
+ If set to false and the finds a duplicate section
+ the parser will stop with an error.
+ If set to true, duplicated sections are allowed in the file, but only a
+ element will be created in the
+ collection.
+
+
+ Defaults to false.
+
+
+
+
+ If set to false, the stop with a error if you try
+ to access a section that was not created previously and the parser will stop with an error.
+ If set to true, inexistents sections are created, always returning a valid
+ element.
+
+
+ Defaults to false.
+
+
+
+
+ Creates a new object that is a copy of the current instance.
+
+
+ A new object that is a copy of this instance.
+
+ 2
+
+
+
+
+ Responsible for parsing an string from an ini file, and creating
+ an structure.
+
+
+
+
+ Ctor
+
+
+ The parser uses a by default
+
+
+
+
+ Ctor
+
+
+ Parser's instance.
+
+
+
+
+ Configuration that defines the behaviour and constraints
+ that the parser must follow.
+
+
+
+
+ True is the parsing operation encounter any problem
+
+
+
+
+ Returns the list of errors found while parsing the ini file.
+
+
+ If the configuration option ThrowExceptionOnError is false it can contain one element
+ for each problem found while parsing; otherwise it will only contain the very same
+ exception that was raised.
+
+
+
+
+ Parses a string containing valid ini data
+
+
+ String with data
+
+
+ An instance with the data contained in
+ the correctly parsed an structured.
+
+
+ Thrown if the data could not be parsed
+
+
+
+
+ Checks if a given string contains a comment.
+
+
+ String with a line to be checked.
+
+
+ true if any substring from s is a comment, false otherwise.
+
+
+
+
+ Checks if a given string represents a section delimiter.
+
+
+ The string to be checked.
+
+
+ true if the string represents a section, false otherwise.
+
+
+
+
+ Checks if a given string represents a key / value pair.
+
+
+ The string to be checked.
+
+
+ true if the string represents a key / value pair, false otherwise.
+
+
+
+
+ Removes a comment from a string if exist, and returns the string without
+ the comment substring.
+
+
+ The string we want to remove the comments from.
+
+
+ The string s without comments.
+
+
+
+
+ Processes one line and parses the data found in that line
+ (section or key/value pair who may or may not have comments)
+
+ The string with the line to process
+
+
+
+ Proccess a string which contains an ini section.
+
+
+ The string to be processed
+
+
+
+
+ Processes a string containing an ini key/value pair.
+
+
+ The string to be processed
+
+
+
+
+ Extracts the key portion of a string containing a key/value pair..
+
+
+ The string to be processed, which contains a key/value pair
+
+
+ The name of the extracted key.
+
+
+
+
+ Extracts the value portion of a string containing a key/value pair..
+
+
+ The string to be processed, which contains a key/value pair
+
+
+ The name of the extracted value.
+
+
+
+
+ Abstract Method that decides what to do in case we are trying to add a duplicated key to a section
+
+
+
+
+ Adds a key to a concrete instance, checking
+ if duplicate keys are allowed in the configuration
+
+
+ Key name
+
+
+ Key's value
+
+
+ collection where the key should be inserted
+
+
+ Name of the section where the is contained.
+ Used only for logging purposes.
+
+
+
+
+ Temp list of comments
+
+
+
+
+ Tmp var with the name of the seccion which is being process
+
+
+
+
+ Represents an INI data parser for streams.
+
+
+
+
+ This instance will handle ini data parsing and writing
+
+
+
+
+ Ctor
+
+
+
+
+ Ctor
+
+
+
+
+
+ Reads data in INI format from a stream.
+
+ Reader stream.
+
+ And instance with the readed ini data parsed.
+
+
+ Thrown if is null.
+
+
+
+
+ Writes the ini data to a stream.
+
+ A write stream where the ini data will be stored
+ An instance.
+
+ Thrown if is null.
+
+
+
+
+ Writes the ini data to a stream.
+
+ A write stream where the ini data will be stored
+ An instance.
+ Formaterr instance that controls how the ini data is transformed to a string
+
+ Thrown if is null.
+
+
+
+
+ Represents an INI data parser for strings.
+
+
+
+ This class is deprecated and kept for backwards compatibility.
+ It's just a wrapper around class.
+ Please, replace your code.
+
+
+
+
+ This instance will handle ini data parsing and writing
+
+
+
+
+ Ctor
+
+
+
+
+ Ctor
+
+
+
+
+
+ Parses a string containing data formatted as an INI file.
+
+ The string containing the data.
+
+ A new instance with the data parsed from the string.
+
+
+
+
+ Creates a string from the INI data.
+
+ An instance.
+
+ A formatted string with the contents of the
+ instance object.
+
+
+
+
+ Represents an error ococcurred while parsing data
+
+
+
+
diff --git a/src/MHServerEmu/Common/Config/IniFile.cs b/src/MHServerEmu/Common/Config/IniFile.cs
index 4614d181..039ffec8 100644
--- a/src/MHServerEmu/Common/Config/IniFile.cs
+++ b/src/MHServerEmu/Common/Config/IniFile.cs
@@ -1,35 +1,29 @@
-using System.Runtime.InteropServices;
-using System.Text;
+using IniParser;
+using IniParser.Model;
namespace MHServerEmu.Common.Config
{
public class IniFile
{
- private const int ReadBufferSize = 255;
-
- [DllImport("kernel32")]
- private static extern int GetPrivateProfileString(string section, string key, string defaultValue, StringBuilder returnedString, int size, string path);
- [DllImport("kernel32")]
- private static extern int GetPrivateProfileInt(string section, string key, int defaultValue, string filePath);
- [DllImport("kernel32")]
- private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
-
private string _path;
+ private FileIniDataParser _parser;
+ private IniData _iniData;
public IniFile(string path)
{
_path = path;
+ _parser = new();
+ _iniData = _parser.ReadFile(_path);
}
- public string ReadString(string section, string key)
- {
- StringBuilder stringBuilder = new(ReadBufferSize);
- GetPrivateProfileString(section, key, "", stringBuilder, ReadBufferSize, _path);
- return stringBuilder.ToString();
- }
-
- public int ReadInt(string section, string key) => GetPrivateProfileInt(section, key, 0, _path);
+ public string ReadString(string section, string key) => _iniData[section][key];
+ public int ReadInt(string section, string key) => Convert.ToInt32(_iniData[section][key]);
public bool ReadBool(string section, string key) => Convert.ToBoolean(ReadString(section, key));
- public void WriteValue(string section, string key, string value) => WritePrivateProfileString(section, key, value, _path);
+
+ public void WriteValue(string section, string key, string value)
+ {
+ _iniData[section][key] = value;
+ _parser.WriteFile(_path, _iniData);
+ }
}
}
diff --git a/src/MHServerEmu/MHServerEmu.csproj b/src/MHServerEmu/MHServerEmu.csproj
index 302936c2..b3c17576 100644
--- a/src/MHServerEmu/MHServerEmu.csproj
+++ b/src/MHServerEmu/MHServerEmu.csproj
@@ -15,6 +15,9 @@
..\..\dep\protobuf-csharp\Google.ProtocolBuffers.dll
+
+ ..\..\dep\ini-parser\INIFileParser.dll
+
..\..\dep\K4os.Compression.LZ4\K4os.Compression.LZ4.dll