# Ini Notecard Reader
This script reads notecards written in INI format.
Internally, it uses llMessageLinked to save the link set data in the prim, and then reads it with the function below.
## Payload Script
Put the following script in the script you want to use:
```lsl
string INI_NOTECARD_NAME = ".Config.ini";
//////////////// CONSTANTS //////////////////////
// INI script initialization completed
integer INI_LOADER_INIT = -203000;
// Register INI notecard
integer INI_REGISTER = -203001;
// INI notecard loading completed
integer INI_READY = -203002;
// Initialize loaded INI notecard
integer INI_RESET = -203003;
// No notecard found
integer INI_NOT_FOUND = -203004;
////////////////////////////////////////////////////////////////////////////////////////////////////
// Get list of keys from a section
list getIniKeysBySection(string ini, string section) {
string temp = llLinksetDataRead("ini" + "" + ini + "" + section);
list keypair = llParseString2List(temp, [""], []);
integer i = 0;
list ret = [];
do {
ret += llList2String(keypair, i);
} while(++i < llGetListLength(keypair));
return ret;
}
// Get value from section and key
string getIniValue(string ini, string section, string theKey) {
integer i = 0;
list entries = getIniKeysBySection(ini, section);
do {
list keypair = llParseString2List(llList2String(entries, i), ["="], []);
integer j = 0;
do {
if (llList2String(keypair, 0) == theKey) {
return llList2String(keypair, 1);
}
} while(++j < llGetListLength(keypair));
} while(++i < llGetListLength(entries));
return "";
}
// Get value by number
string getIniValueByCount(string ini, string section, integer count) {
string keypair = llList2String(getIniKeysBySection(ini, section), count);
integer equalCharLocation = llSubStringIndex(keypair, "=");
return llDeleteSubString(keypair, 0, equalCharLocation);
}
// Check if the key exists in the section
integer existsIniKeyBySection(string ini, string section, string theKey) {
integer i = 0;
list entries = getIniKeysBySection(ini, section);
do {
string entry = llList2String(entries, 0);
integer separator = llSubStringIndex(entry, "=");
if (~separator && llDeleteSubString(entry, separator, -1) == theKey) {
return TRUE;
} else if (entry == theKey) {
return TRUE;
}
} while (i++ < llGetListLength(entries));
return FALSE;
}
default {
state_entry() {
llMessageLinked(LINK_THIS, INI_REGISTER, INI_NOTECARD_NAME, NULL_KEY);
}
on_rez(integer param) {
llResetScript();
}
link_message(integer sender, integer channel, string data, key id) {
if (id == NULL_KEY) {
id = "0";
}
if (channel == INI_READY && data == INI_NOTECARD_NAME) {
// Insert the processing to be performed when the notecard is read here.
}
}
}
```
## Reference
Assume that the following ini notecard (.Config.ini) is loaded.
```ini
[General]
# Key-Value Store
key1=value1
key2=value2
key3=value3
[Enum]
// Enum Store
AAA
BBB
CCC
```
Comment lines are either # or //.
*Comments cannot be placed on the same line as a key.
### list getIniKeysBySection(string ini, string section)
Gets a list of keys from a section. This function outputs only the keys in the section and removes the values.
```lsl
list general = getIniKeyBySection(".Config.ini", "General");
list enum = getIniKeyBySection(".Config.ini", "Enum");
```
In general, ["key1", "key2", "key3"] are stored.
In enum, ["AAA", "BBB", "CCC"] are stored.
### string getIniValue(string ini, string section, string theKey)
Gets a value from a section and key name.
```lsl
string key1 = getIniValue(".Config.ini", "General", "key1");
string enum_str = getIniValue(".Config.ini", "Enum", "AAA");
```
key1 stores "value1".
enum_str will be blank.
### string getIniValueByCount(string ini, string section, integer count)
This is a special function. It gets the countth value of a section with values. Use it in conjunction with getIniKeysBySection.
```lsl
string key3 = getIniValueByCount(".Config.ini", "General", 2);
```
key1 stores "value3".
This can be used to match the button number clicked in the dialog.
### integer existsIniKeyBySection(string ini, string section, string theKey)
Checks if a key exists in a section.
```lsl
integer key2_exists = existsIniKeyBySection(".Config.ini", "General", "key2");
integer key4_exists = existsIniKeyBySection(".Config.ini", "General", "key4");
```
key2_exists will be 1, but key4_exists will be 0.
## Sample Program: Picopico Walking Sound
This is a sample script that overwrites the walking, crouching walking, and running sounds with a beeping sound.
See the ini notecard and script inside for more details.