Hello everyone,
I wrote this tutorial to help all you guys get a good start to making your own scripts. I will update this tutorial as needed. If you have any comments or suggestions please feel free to post them here
|
Content |
|
|
1. |
|
|
2. |
|
|
3. |
|
|
4. |
|
|
5. |
|
|
6. |
|
|
7. |
|
|
8. |
|
|
9. |
|
|
10. |
|
|
11. |
|
|
12. |
|
-INTRODUCTION-
Ok first off, please make sure you are using the current version of the FFXI Windower, you can find the current version at www.windower.net
Q. What are scripts?
A. Scripts are a group of commands that can be
bundled together to preform a desired task.
Q. Are scripts the same thing as bots?
A. No, scripts require human interaction to
function properly, scripts are designed to make a specific task easier for the
user.
Q. Can scripts get me banned?
A.
No, scripts alone can not get you banned nor are they detectable. I'm sure if you go around shouting "Tee,
Hee, SCRIPTS are for ME!!!" I'm sure nothing
good will come from it. All in all watch what you say
and you will be fine.
-OVERVIEW-
Scripts are files that contain a group of commands that pre-forms a task. They can be a file with any extension, as of date the windower is not very picky on the file's extension
The location of the script file is a factor though the proper directory (folder) that scripts are to be placed is
<current windower folder> \ scripts \
To run a script in the script folder a example command will look like this
exec test.txt
exec test.script
If you have sub-folders in the script folder to better organize your scripts, a example command would look like this
exec skill\healing.txt
exec assist\targeting.script
Now that you know what scripts are and the proper place to put these files now we can start to learn the makeup of these scripts
First to know is that there will be times you may wish to add comments to your script that will not interfear with your commands. This is done with two forward slashes '//'. Adding these two forward slashes to the begging of a line will cause the windower to ignore that line. This comes in helpful when you like to add filenames comments to notify yourself or others what the proper name of the file should be called
//Scripting_tutorial_v1.3.txt
//
my scripting tutorial
INPUT
This command is used
to send strings of command to the FFXI game. Anything that can be typed
in the Chat Log can be tied to the INPUT command.
Examples:
input /p Hello everyone
will be
as typing (/p Hello Everyone) in the chat box
input /magic "Cure" <me>
will be
as typing (/magic "Cure" <me>) in the chat box
input /target <p1>
will be
as typing (/target <p1>) in the chat box
input Thank You
will be
as typing (Thank You) in the chat box. This will come out in a
/say unless you have the chatmode set to something different.
So as you can see anything that you can type in the chat box whether it be a command or a statement you will use the INPUT command to tell the windower to send that string to the chat box.
ALIAS
This command is used
to set a certain string or strings of commands to a variable. This comes in
handy by instead of typing out the entire command again you can simply call
that command by typing its alias.
Structure
alias [alias name] [command string]
Examples #1:
alias timetocure input /ma "Cure"
<me>
alias ineedacure input /ma "Cure"
<me>
alias cureplz input /ma "Cure"
<me>
By using these alias you can type
in your script
imetocure
ineedacure
cureplz
to perform
a input /ma "Cure" <me>
Example #2:
alias run1 input /p Hello Everyone
alias run2 pause 1
alias run3 input /p ...
By using these alias you can type
in your script
run1
this will
send a /p Hello Everyone to the chat box
run2
this will
tell the windower to pause for 1 second, pause and /wait
is exactly the same thing the advantages with pause over a /wait is pause you
can add decimal to your timing where asas the /wait
command can only do whole numbers. Example: pause 1.7 will wait 1 and .7
seconds where /wait can only be set as /wait 1 or /wait 2 using the pause
command you will greatly be able to fine tune your timing in your scripts.
run3
this will
send a /p ... to the chat box
Now that you know what an ALIAS does you can start making them more advanced. Here you will need to learn that a colon ; is a line separator, this is used to divide the commands you are using.
Lets take
the 3 'run' alias that were used in the previous example.
alias run1 input /p Hello Everyone
alias run2 pause 1
alias run3 input /p ...
Now say you want to combine these 3 to one alias, there are two ways to do this. You can either put all three commands to one alias using the line separator ; or you can make a new alias that will combine the 3 run alias's
Example #1 - Putting all 3 commands
onto one alias
alias runningitall input /p Hello Everyone;pause 1;input /p ...;
As you can see we are using a ; as a line separator to put all 3 commands onto one alias) By doing this
you can simple type 'runningitall' in your script to
perform all 3 commands
Example #2 - Combine the current
alias to a new alias
alias runningitall run1;run2;run3;
As you can see instead of typing
each command out we are using their alias with a line separator ';' to combine
them into one new alias. By doing this you can simple type 'runningitall'
in your script to perform all 3 commands. Using this method though you will
still have run1,run2, and run3, defining each command
You will also need to learn how to turn a alias you made back into nothing (null).This can be done by adding a forward slash '/' after the alias.
Example:- Say
you have this alias
alias runningitall input /p Hello Everyone;pause 1;input /p ...;
To turn this alias back into
nothing and clear the alias of any commands you will have to redefine the alias
with a /
alias runnintitall /
(by doing this you
will clear out any command set to the alias)
BIND
This will bind a certain key to perform a certain action
Structure:
bind [key] [command or alias]
UNBIND
This will unbind a certain key that was previously assigned to a BIND
Structure:
unbind [key]
When binding a key you may use ! which will represent ALT, and ^ for CTRL
Example #1:
bind key ^c input /p Hello everyone
(this
will assign a '/p Hello Everyone' command to the CTRL+C key combination
unbind key ^c
(this will unbind the
previously bound key CTRL+C)
Example #2:
bind key !a input /p Hello All
(this will assign a
'/p Hello All" command to the ALT+A key combination)
unbind key !a
(this will unbind the
previously bound key ALT+A)
You may also use the line separator ';' to add multiple command to a bound key
bind key ^q input /p Hello Everyone;pause 1;input
/p ...;
(this will perform 3
commands when you press CTRL+Q combination)
This will send a '/p Hello
Everyone', then it will wait for 1 second, then it will send a '/p ...'
Now lets use the run1, run2, and run3 alias in the previous example;
alias run1 input /p Hello Everyone
alias run2 pause 1
alias run3 input /p ...
bind key !z run1;run2;run3;
(this will perform 3 commands when you press ALT+Z combination) This will send a '/p Hello Everyone', then it will wait for 1 second, then it will send a '/p ...'
Now that you know the simple makeup of a script you will need to learn how to make a script stop. There is not a single console command that will exit out of a script. You will have to make a way for the script to end within the script you are making. This is done by setting a bind key that will redefine the alias to nothing as shown in the 'ALIAS command (advanced)' section of this tutorial.
Lets use a simple script for our example
//[looping.txt]
alias hahaha input /p IMA RUN FOREVER;
alias runitagain exec looping.txt;
alias runtime hahaha;runitagain;
runtime
By using this example script the script will send a command '/p IMA RUN FOREVER" then it will reload the file looping.txt. This will make the script send /p IMA RUN FOREVER over and over and over again.
Now lets add a bind that will redefine the alias we used to make the script stop. Since you learned that adding a '/' after the alias will clear the alias of any commands that it holds you will be cause the script to stop.
//[looping.txt]
alias hahaha input /p IMA RUN FOREVER;
alias runitagain exec looping.txt;
alias runtime hahaha;runitagain;
bind ^escape alias hahaha /;alias runitagain /;alias runtime /;
runtime
Notice the 'bind ^escape' The script will still send the command '/p IMA RUN FOREVER' and then reload itself, but now users can press CTRL+Escape to redefine the alias we used to nothing which will cause the script to end.
You do not have to use CTRL+Escape to make the script end, what causes the script to end is the bind that is redefining the alias to nothing, If you choose you can use any bind you like, it doesn’t matter. The reason I say use CTRL+Escape is because this is universal for exiting out of a script.
Aikar has notified me that using the #1 method may not work or mess up. In good faith I will add Aikar's method for ending a script.
Ok lets take the sample script that we used in the #1 method.
//[looping.txt]
alias hahaha input /p IMA RUN FOREVER;
alias runitagain exec looping.txt;
alias runtime hahaha;runitagain;
runtime
As Aikar said that adding all the alias to one line can end up messing up. I guess I can see this causing a problem if the Text Wrapping of some text editors end up messes up the bind ^escape line by making it spread over multiple lines. What Aikar purposed is to add new alias's that will cancel out the used alias's. Using the sample script above the new alias's would look something like this.
alias stophahaha alias hahaha
/;
alias stoprunitagain alias runitagain
/;
alias stopruntime alias runtime /;
alias stop stophahaha;stoprunitagain;stopruntime;
Now that you have all the new alias's set to the stop alias instead of using
bind ^escape alias hahaha /;alias runitagain /;alias runtime /;
You will be using
bind ^escape stop;
This will prevent text wrapping messing up the bind ^escape command Here is what the new sample script would look like in whole.
//[looping.txt]
alias hahaha input /p IMA RUN FOREVER;
alias runitagain exec looping.txt;
alias runtime hahaha;runitagain;
alias stophahaha alias hahaha
/;
alias stoprunitagain alias runitagain
/;
alias stopruntime alias runtime /;
alias stop stophahaha;stoprunitagain;stopruntime;
bind ^escape stop;
runtime
Internal & External script looping is used to make a script repeat itself. This is helpful when for instance you are making skill up scripts and you feel it necessary to reduce the interaction needed to preform a script. Another senario would be in creating a Auto-Shooting or Auto-Boosting Script for Ranger or Monk.
External looping-
This is the term used when describing a script that repeats itself with file looping. This means when the script comes to an end there will be a call to reload its own file name in order to repeat itself.
PRO's n' CON's-
PRO's to this method is that the windower itself is more stable on how long the script can loop itself before crashing as descripted in the Internal looping section.
CON's to this method a random error I have
noticed that sometimes the windower will give you the error "cannot load
file 'examplename.txt' file not found" even though the file is correctly placed and the file paths
are correct. I have encountered this error and still do not understand why this
happens at times. I will update tutorial when resolved.
Now lets take our previous example script
//[looping.txt]
alias hahaha input /p IMA RUN FOREVER;
-> alias runitagain exec looping.txt;
alias runtime hahaha;runitagain;
alias stophahaha alias hahaha
/;
alias stoprunitagain alias runitagain
/;
alias stopruntime alias runtime /;
alias stop stophahaha;stoprunitagain;stopruntime;
bind ^escape stop;
runtime
Please notice the '-> alias runitagain' alias, as you have learned in the Overview the command 'exec' is used to load a script file. As you can see in this alias we have 'exec looping.txt'. Since this alias can be found in the 'runtime' (combination alias) and the script is told to run the 'runtime' alias as seen at the bottum of the script when the script gets to the end of the 'runtime' alias it will execute its own filename 'exec looping.txt' hence 'External Looping'.
Internal looping-
This is the term used when describing a script that repeats
itself by loading an alias from
another alias. This means that when you have a group of commands to one alias
and that group comes do an end
during processing there will be another alias at the end that continues the
process by loadings its same group alias or another group alias.
PRO's n' CON's-
PRO's to this method is there will be an increase
on the processing speed of the script. File execution will cause a slight delay
on the reaction time since you are accessing the hard drive and retreaving a file. You will also not experiance
the random error that is described in the External looping section.
CON's to this method is due to the way the windower was designed this method will cause the windower to eventually crash. This is due to alias being
loaded while the previously ones are waiting to end. Since you are continueing onto the previous alias the alias(s) in whole cannot
come to a end and. This will cause the windower to eventually crash.
Lets take the looping.txt script
//[looping.txt]
alias hahaha input /p IMA RUN FOREVER;
1> alias runitagain
exec looping.txt;
2> alias runtime hahaha;runitagain;
alias stophahaha alias hahaha
/;
alias stoprunitagain alias runitagain
/;
alias stopruntime alias runtime /;
alias stop stophahaha;stoprunitagain;stopruntime;
bind ^escape stop;
runtime
Notice the two alias' marked with 1> and 2>. since we do not need the 'runitagain' alias lets remove it. Since the 'runtime' alias needs a method to repeat itself lets add an extra alias to this one in order to continue the alias.
alias runtime hahaha;runtime;
As you can see we have added its own alias in order to make it repeat itself. Please be aware that executing a script like this would send '/p IMA RUN FOREVER' to the log very quickly and will crash rather quickly as well since the build up of alias' grow very quickly.
You can also have two or more alias loopings grouped together. Lets add a few extra lines to this script\
//[looping.txt]
1> alias hahaha
input /p IMA RUN FOREVER;hahaha2;
2> alias hahaha2 input /p IMA RUN 4EVER;hahaha;
3a> alias runtime hahaha;
alias stophahaha alias hahaha
/;
4> alias stoprunitagain
hahaha2 /;
alias stopruntime alias runtime /;
alias stop stophahaha;stoprunitagain;stopruntime;
bind ^escape stop;
3b> runtime
Notice the alias' marked with 1>, you can see at the end of this alias group we added a new alias call 'hahaha2' which you will see the alias defined on the 2>, marker. On the new alias group you can see there is yet another call which will continue the process back to the first 1> alias. Since you know these two alias will repeat themselves you can change the 'alias runtime' marked at 3a>, You can either call a runtime alias as marked at 3b> or you would be able to call the 1> or 2> now since they will be able to combine themselves threw Internal looping.
Remember to update your alias cancelation (nulling) when you call the keybind to stop the script.
|
Before |
|
//[looping.txt] alias hahaha input /p IMA RUN FOREVER;hahaha2; alias hahaha2 input
/p IMA RUN 4EVER;hahaha; alias runtime hahaha; alias stophahaha alias hahaha /; alias stoprunitagain hahaha2 /; alias stopruntime alias runtime /; alias stop stophahaha;stoprunitagain;stopruntime; bind ^escape stop; runtime |
|
After |
|
//[looping.txt] alias hahaha input /p IMA RUN FOREVER;hahaha2; alias hahaha2 input
/p IMA RUN 4EVER;hahaha; alias stophahaha alias hahaha /; alias stophahaha2
alias hahaha2 /; alias stop
stophahaha;stophahaha2; bind ^escape stop; hahaha |
When you start to make more complex scripts there will be times you wish to add more options to one key. You can accomplish this by, Key Rotating (virtual looping). We will be doing this by redefining a previous defined alias to something new with new commands
In the previous script instead of the script running endlessly with the use only having the option to end the script by pressing Ctrl+Escape lets add a bind key to trigger the two party chat commands
First we will need our bind linked to an alias
bind ^z partysay
Now we will need to develop a method to change this alias threw different alias'
alias partysay1 input /p IMA RUN FOREVER;alias partysay partysay2;
alias partysay2 input /p IMA RUN 4EVER;alias partysay
partysay1;
You can see we made two new alias similar to our bind key alias this will help you organize your alias' On the end of each alias instead of directly calling the next alias to continue the process we are changing the bind key alias. You will also need to remember to define the bind key to one of the rotating alias' to start the rotation process.
alias partysay partysay1
You can use this process to make bind key rotations dependant on other bind key rotations, by changing alias' you can add complexity to your scripts to an unlimited proportion. Once again please remember to update your ending sequence
Now our script looks like this in whole
//[looping.txt]
bind ^z partysay
alias partysay1 input /p IMA RUN FOREVER;alias partysay partysay2;
alias partysay2 input /p IMA RUN 4EVER;alias partysay
partysay1;
alias partysay partysay1;
alias endalias1 alias partysay1 /;
alias endalias2 alias partysay2 /;
alias endalias3 alias partysay /;
alias endbind unbind key ^z;
alias stop enalias1;endalias2;endalias3;endbind;
bind ^escape stop;
Running this script you will be able to press CTRL+Z to trigger the party say, and each time you press the key combination the message will alternate between 'IMA RUN FOREVER' and "IMR RUN 4EVER'
These commands can be used in a script or typed directly into the windower console
These commands can be found in the command.txt file that is included with the windower.
GENERAL COMMANDS
showfps # - Shows or hides FPS counter
<0 = hidden, 1 = visible, no parameter to toggle>
screenshot <format> [hide] - Takes a screenshot,
specifying hide hides Windower from the screenshot.
<format can be bmp/jpg/png>
wait # and pause #- Pauses execution of a command/bind/alias/script for
given seconds.
Can be decimal.
CONSOLE COMMANDS
console_toggle - Toggles the visibility of the console
console_clear - Clears the console buffer
console_echo "string" - Echoes string to the console buffer
console_displayactivity # - Sets whether the console displays on
new text
<0 = disable, 1 = enable>
console_fadedelay int - Time in
milliseconds before the console fades
console_position X Y - Sets the console position
console_color A R G B - Sets the console color
<Alpha (Optional) Red Green Blue>
console_exec "file" - Executes a console script
exec "file"
GAME COMMANDS
game_forceambientlight # - Forces using specified ambient light
<0 = ignore, 1 = force>
game_ambientlight A R G B - Set game ambient light
<Alpha (Optional) Red Green Blue>
game_fillmode # - Set rendering mode
fillmode #
<0 = normal, 1 = wireframe, 2 = point
fill>
game_gamma # - Sets game gamma
<0-100, Default = 50>
game_allowsetcursorpos # - Sets whether the game is allowed to set
the cursor position
<0 = false, 1 = true>
game_minimize - Minimizes the game to the taskbar
game_exit - Exits the game to POL (character remains in world like going LD)
game_quit - Same as game_exit
game_terminate - Hard exits the game to desktop (not
recommended)
window_toggleframe - Toggles window frame on/off.
window_togglefullscreen - Sets game to psudeo-fullscreen
mode
KEYBOARD COMMANDS
keyboard_sendstring "string" - Sends a string to the
game
input "string"
keyboard_type "string" - This is the old functionality of keyboard_sendstring,
this types the string to
type "string" the chat input bar in game.
keyboard_blockinput # - Blocks keyboard input
<0 = unblock, 1 = block>
keyboard_allowmmf # - Allows or disables keyboard input via
MMF
<0 = disable, 1 = enable>
paste - Pastes the contents of the clipboard to the input buffer.
MOUSE COMMANDS
mouse_blockinput # - Blocks mouse input
<0 = unblock, 1 = block (MAJOR PROBLEMS)>
PLUGIN COMMANDS
plugin_load <plugin> - Loads a plugin
dll (.dll is optional, and
case is irrelevant)
load <plugin>
plugin_unload <plugin> - Unloads a plugin dll
unload <plugin>
toggle <plugin> - Will toggle a plugin. Designed to be bound to a key to turn off or on a plugin on a keystroke
For more information about these keys see the post here.
THESE KEYS HAVE ALREDY BEEN DEFINED WITH THE RELEASE OF THE WINDOWER THIS IS ONLY A LIST OF USABLE KEYS ADDING THE STRKEYMAPPING TO YOUR SCRIPS WILL DO ABSOLUTLY NOTHING
STRKEYMAPPING( "`", DIK_GRAVE)
STRKEYMAPPING("escape", DIK_ESCAPE)
STRKEYMAPPING("1", DIK_1)
STRKEYMAPPING("2", DIK_2)
STRKEYMAPPING("3", DIK_3)
STRKEYMAPPING("4", DIK_4)
STRKEYMAPPING("5", DIK_5)
STRKEYMAPPING("6", DIK_6)
STRKEYMAPPING("7", DIK_7)
STRKEYMAPPING("8", DIK_8)
STRKEYMAPPING("9", DIK_9)
STRKEYMAPPING("0", DIK_0)
STRKEYMAPPING("-", DIK_MINUS)
STRKEYMAPPING("=", DIK_EQUALS)
STRKEYMAPPING("backspace", DIK_BACK)
STRKEYMAPPING("tab", DIK_TAB)
STRKEYMAPPING("q", DIK_Q)
STRKEYMAPPING("w", DIK_W)
STRKEYMAPPING("e", DIK_E)
STRKEYMAPPING("r", DIK_R)
STRKEYMAPPING("t", DIK_T)
STRKEYMAPPING("y", DIK_Y)
STRKEYMAPPING("u", DIK_U)
STRKEYMAPPING("i", DIK_I)
STRKEYMAPPING("o", DIK_O)
STRKEYMAPPING("p", DIK_P)
STRKEYMAPPING("[", DIK_LBRACKET)
STRKEYMAPPING("]", DIK_RBRACKET)
STRKEYMAPPING("enter", DIK_RETURN)
STRKEYMAPPING("return", DIK_RETURN)
STRKEYMAPPING("ctrl", DIK_LCONTROL)
STRKEYMAPPING("lctrl", DIK_LCONTROL)
STRKEYMAPPING("a", DIK_A)
STRKEYMAPPING("s", DIK_S)
STRKEYMAPPING("d", DIK_D)
STRKEYMAPPING("f", DIK_F)
STRKEYMAPPING("g", DIK_G)
STRKEYMAPPING("h", DIK_H)
STRKEYMAPPING("j", DIK_J)
STRKEYMAPPING("k", DIK_K)
STRKEYMAPPING("l", DIK_L)
STRKEYMAPPING(";", DIK_SEMICOLON)
STRKEYMAPPING("'", DIK_APOSTROPHE)
STRKEYMAPPING("shift", DIK_LSHIFT)
STRKEYMAPPING("lshift", DIK_LSHIFT)
STRKEYMAPPING("\\", DIK_BACKSLASH)
STRKEYMAPPING("z", DIK_Z)
STRKEYMAPPING("x", DIK_X)
STRKEYMAPPING("c", DIK_C)
STRKEYMAPPING("v", DIK_V)
STRKEYMAPPING("b", DIK_B)
STRKEYMAPPING("n", DIK_N)
STRKEYMAPPING("m", DIK_M)
STRKEYMAPPING(",", DIK_COMMA)
STRKEYMAPPING(".", DIK_PERIOD)
STRKEYMAPPING("/", DIK_SLASH)
STRKEYMAPPING("rshift", DIK_RSHIFT)
STRKEYMAPPING("numpad*", DIK_MULTIPLY)
STRKEYMAPPING("alt", DIK_LMENU)
STRKEYMAPPING("lalt", DIK_LMENU)
STRKEYMAPPING("space", DIK_SPACE)
STRKEYMAPPING("capslock", DIK_CAPITAL)
STRKEYMAPPING("f1", DIK_F1)
STRKEYMAPPING("f2", DIK_F2)
STRKEYMAPPING("f3", DIK_F3)
STRKEYMAPPING("f4", DIK_F4)
STRKEYMAPPING("f5", DIK_F5)
STRKEYMAPPING("f6", DIK_F6)
STRKEYMAPPING("f7", DIK_F7)
STRKEYMAPPING("f8", DIK_F8)
STRKEYMAPPING("f9", DIK_F9)
STRKEYMAPPING("f10", DIK_F10)
STRKEYMAPPING("numlock", DIK_NUMLOCK)
STRKEYMAPPING("scrolllock", DIK_SCROLL)
STRKEYMAPPING("numpad7", DIK_NUMPAD7)
STRKEYMAPPING("numpad8", DIK_NUMPAD8)
STRKEYMAPPING("numpad9", DIK_NUMPAD9)
STRKEYMAPPING("numpad-", DIK_SUBTRACT)
STRKEYMAPPING("numpad4", DIK_NUMPAD4)
STRKEYMAPPING("numpad5", DIK_NUMPAD5)
STRKEYMAPPING("numpad6", DIK_NUMPAD6)
STRKEYMAPPING("numpad+", DIK_ADD)
STRKEYMAPPING("numpad1", DIK_NUMPAD1)
STRKEYMAPPING("numpad2", DIK_NUMPAD2)
STRKEYMAPPING("numpad3", DIK_NUMPAD3)
STRKEYMAPPING("numpad0", DIK_NUMPAD0)
STRKEYMAPPING("numpad.", DIK_DECIMAL)
STRKEYMAPPING("f11", DIK_F11)
STRKEYMAPPING("f12", DIK_F12)
STRKEYMAPPING("kana", DIK_KANA)
STRKEYMAPPING("convert", DIK_CONVERT)
STRKEYMAPPING("noconvert", DIK_NOCONVERT)
STRKEYMAPPING("yen", DIK_YEN)
STRKEYMAPPING("kanji", DIK_KANJI)
STRKEYMAPPING("numpadenter", DIK_NUMPADENTER)
STRKEYMAPPING("rctrl", DIK_RCONTROL)
STRKEYMAPPING("sysrq", DIK_SYSRQ)
STRKEYMAPPING("ralt", DIK_RMENU)
STRKEYMAPPING("pause", DIK_PAUSE)
STRKEYMAPPING("home", DIK_HOME)
STRKEYMAPPING("up", DIK_UP)
STRKEYMAPPING("pageup", DIK_PRIOR)
STRKEYMAPPING("left", DIK_LEFT)
STRKEYMAPPING("right", DIK_RIGHT)
STRKEYMAPPING("end", DIK_END)
STRKEYMAPPING("down", DIK_DOWN)
STRKEYMAPPING("pagedown", DIK_NEXT)
STRKEYMAPPING("insert", DIK_INSERT)
STRKEYMAPPING("delete", DIK_DELETE)
STRKEYMAPPING("windows", DIK_LWIN)
STRKEYMAPPING("lwindows", DIK_LWIN)
STRKEYMAPPING("rwindows", DIK_RWIN)
STRKEYMAPPING("apps", DIK_APPS)