RE: [hlcoders] Examples of uses for IEngine-ServerInsertCommand()

2005-06-11 Thread Karl \XP-Cagey\ Patrick
 Yet, even in the case of a full blown scripting language, not having
 InsertCommand() means that any scripts/commands that you wished to
 invoke via a normal Valve cfg file would have the same ordering problem if

 they needed to pass commands back to the server (e.g. exec, changelevel,
 kickid, etc).

One solution to your problem that doesn't require an API change is
instructing users to write a one-line config file that simply calls your
plugin-enabled parser to run on another file.  E.g. have the entire contents
of autoexec.cfg be eventscripts_exec autoexec_script.cfg\n.  Once you have
that arrangement, there aren't any commands that you need to preempt from
the top level scripts--load and manipulate the entire autoexec_script.cfg
file in memory to perform whatever transforms you need, then feed the entire
transformed file to the server in a block.  Delayed insertion removes the
need for preemptive insertion, and as far as your end users know or care,
they're still using Valve's config system.

Placement of the entire config into a one-off file isn't seamless, but it's
not hard for users to understand and it doesn't require much extra work or
drive space.  If HL2 calls two script files, say autoexec.cfg and
server.cfg, at nearly the same time and they both contain a single call into
a one-off, the execution order will appear to be the same to end users even
if the second exec comes before or in the middle of the interpreted commands
from the first file, since the effect of calling the second file would place
its commands after the complete set of commands from the intial file
(assuming the whole file interpret-and-stuff mechanism described above and
synchronous server command execution).

You really don't need out-of-order placement for variable substitution or
subscript execution using this scheme--you could even support calls into
other files and process them entirely in place before you begin inserting
the top level file. You might want to have preemptive insertion for live
evaluation of loop conditions, but that problem can also be solved through
delayed insertion - keep all commands after the evaluation statement in
memory until you get back your result. Simple loop counters can be unrolled
in place instantly, and I'm not sure how much complexity a configuration
script really needs.

My 2 cents,

Karl


 -Original Message-
 From: [EMAIL PROTECTED] [mailto:hlcoders-
 [EMAIL PROTECTED] On Behalf Of Jeremy Swigart
 Sent: Friday, June 10, 2005 6:20 AM
 To: hlcoders@list.valvesoftware.com
 Subject: Re: [hlcoders] Examples of uses for IEngine-
 ServerInsertCommand()

 I could be wrong, but even if ServerInsertCommand() puts the script
 command at the front of the queue as opposed to the back, that still
 wouldn't be executed until the current script is finished. Sounds like
 really what you need is ServerCommandNow() that executes it right now,
 so that when the next line of the current script runs, it can be sure
 that the results of the script it just invoked is already done. Sounds
 like even with ServerInsertCommand() it is gonna be a pain to get the
 ordering right.

 On 6/10/05, Mattie Casper [EMAIL PROTECTED] wrote:
  Thanks for the suggestion, but, as you may have guessed, this has been
  considered. ;)  Yet, creating an entire scripting engine isn't the goal
 of
  EventScripts. There are lots of different scripting engines out there,
 and they
  definitely have their place for administrators who understand coding.
  EventScripts is trying to be the middle-ground between a
 structured/scoped
  language and the console commands they know and love. As I mentioned
 below, ES
  doesn't yet support looping and the like and may never do so--- it's not
  intended to be a full-powered scripting language.
 
  With EventScripts, we're trying to enhance the console commands so that
 even
  everyday normal console/rcon commands and normal autoexec.cfg/server.cfg
 files
  can take advantage of very simple logic and variable expansion. We don't
 need
  everything a scripting language can do, we just want some basic
 enhancements to
  the command console. Most of these console enhancements would be along
 the lines
  Valve was already been moving, e.g. with setinfo and incrementvar.
 
  Yet, even in the case of a full blown scripting language, not having
  InsertCommand() means that any scripts/commands that you wished to
 invoke via a
  normal Valve cfg file would have the same ordering problem if they
 needed to
  pass commands back to the server (e.g. exec, changelevel, kickid, etc).
 These
  commands would execute *after* the current .cfg file was totally
 resolved and
  not in-place. This wouldn't be intuitive and would likely cause
 problems! It
  wouldn't be a problem if you didn't allow the console to launch scripts,
 but the
  server console is a great place for invoking things like that
 (especially
  remotely).
 
  *** TO CLARIFY, this isn't a problem just for scripting engines! ***
 It's

Re: [hlcoders] Examples of uses for IEngine-ServerInsertCommand()

2005-06-10 Thread Jeremy Swigart
Have you considered using a scripting language such as lua or
gamemonkeyscript or another one that supports fake threading?
Specifically you might be interested in their ability to execute over
many frames, yet still be written in a top down manner. Here's an
example of GMS, which I use in my bot.

/ server.cfg
if(sv_gravity  800)
{
exec(reset_grav.cfg);
echo(gravity reset);
yield(); // suspend execution of the script till the next frame, can
also do sleep() commands
}
else
{
echo(gravity is fine);
}
echo(this happens the frame after the gravity is reset, or right away
if the exec didnt happen);

Everything you do and much more would be possible using the features
of an existing scripting language, and with it you'd get the power of
conditionals, tables, loops, and much more.

Just an idea.

J

On 6/9/05, Mattie Casper [EMAIL PROTECTED] wrote:

 As promised, this email contains examples of the sorts of things that plugin
 authors cannot manage in Source without some method to insert commands at the
 beginning of the server command queue. This ability is vital for any plugin
 wishing to create meta console commands. I.e. commands like alias, exec,
 incrementvar, etc.

 Variable expansion --
 
   EventScripts makes extensive use of variable expansion for its console
 commands, and it's crippled without InsertCommand(). There's no way to arrange
 for expanded commands to execute right away before the rest of a config file.
 For example, let's say I added the following lines to a .cfg file (e.g.
 server.cfg):

 // server.cfg
 // let's say 'mypluginvar' is a variable exposed by my plugin
 mypluginvar ClanMatch
 expandvars echo *** mypluginvar equals %mypluginvar%
 echo *** The above line should say mypluginvar equals ClanMatch
 echo *** server.cfg is completely done. should see nothing else.
 // end server.cfg

 So, if my plugin's 'expandvars' command expanded variables in the string
 provided to it and then passed it back to the server, the only mechanism it 
 can
 use is ServerCommand(). This will place it AFTER everything else in the queue.
 As such, the output would be:

 *** The above line should say mypluginvar equals ClanMatch
 *** server.cfg is completely done. should see nothing else.
 *** mypluginvar equals ClanMatch

 This is definitely not what someone writing a .cfg file would be expecting. 
 They
 expect the commands to go in order of writing. EventScripts supports a great
 deal of variable expansion, but there's no support for intuitive ordering. 
 This
 example is trivial compared to the complicated scripts people are creating. It
 really weakens the plugin when admins can't trust that your variables will be
 expanded properly in relation to other commands in the cfg file.
 -

 Conditional expressions --
 -
   EventScripts supports conditional expressions. These are also hindered 
 without
 InsertCommand(). The order of execution again gets all out of phase. For
 example, let's say I added the following lines to a .cfg file (e.g. 
 server.cfg):

 // server.cfg
 // let's say my plugin exposes an exec_if command
 exec_if sv_gravity  800 then reset_grav.cfg
 echo *** sv_gravity was set back to 800 by increase_grav.cfg
 exec_if sv_gravity  800 then something_wrong.cfg
 // end of server.cfg

 In this case, the plugin command exec_if would test the condition 
 sv_gravity
   800 and then use, sadly, ServerCommand() to place exec reset_grav.cfg in
 the queue where it could reset the gravity back to 800. Unfortunately, this 
 goes
 to the very end of the queue, so the rest of the server.cfg executes first. 
 This
 means the second conditional will STILL see sv_gravity incorrectly because it
 goes through the server command queue like this:

 1. exec_if
 2. echo
 3. exec_if
 4. exec reset_grav.cfg
 5. exec something_wrong.cfg

 #5 should never happen-- and #4 should happen before the 'echo' does. Yet we
 can't do this because InsertCommand() isn't yet available to plugin writers.
 -

 Loops --
 --
   EventScripts does not yet support loops, but these would also be possible if
 Valve provided a way to insert commands at the beginning of the queue. Without
 it, you cannot be certain that the loop lines will execute before the next 
 line
 in a script.
 --

 Enhanced versions of alias, exec, etc
 -
  EventScripts doesn't do this yet, but if I wanted to create an enhanced 
 version
 of these Valve commands, the new commands will always be deficient without
 InsertCommand(). For example, if we wanted to write an optimized exec 
 command
 that cached the .cfg file in memory on the first execution and then always ran
 it from memory whenever called (to avoid refetches from disk):

 // server.cfg
 memexec only_changes_on_reboot.cfg
 exec load_plugins.cfg
 // end of server.cfg

 In this case, simulating 

Re: [hlcoders] Examples of uses for IEngine-ServerInsertCommand()

2005-06-10 Thread Mattie Casper

Thanks for the suggestion, but, as you may have guessed, this has been
considered. ;)  Yet, creating an entire scripting engine isn't the goal of
EventScripts. There are lots of different scripting engines out there, and they
definitely have their place for administrators who understand coding.
EventScripts is trying to be the middle-ground between a structured/scoped
language and the console commands they know and love. As I mentioned below, ES
doesn't yet support looping and the like and may never do so--- it's not
intended to be a full-powered scripting language.

With EventScripts, we're trying to enhance the console commands so that even
everyday normal console/rcon commands and normal autoexec.cfg/server.cfg files
can take advantage of very simple logic and variable expansion. We don't need
everything a scripting language can do, we just want some basic enhancements to
the command console. Most of these console enhancements would be along the lines
Valve was already been moving, e.g. with setinfo and incrementvar.

Yet, even in the case of a full blown scripting language, not having
InsertCommand() means that any scripts/commands that you wished to invoke via a
normal Valve cfg file would have the same ordering problem if they needed to
pass commands back to the server (e.g. exec, changelevel, kickid, etc). These
commands would execute *after* the current .cfg file was totally resolved and
not in-place. This wouldn't be intuitive and would likely cause problems! It
wouldn't be a problem if you didn't allow the console to launch scripts, but the
server console is a great place for invoking things like that (especially
remotely).

*** TO CLARIFY, this isn't a problem just for scripting engines! *** It's a
problem for ANY PLUGIN that uses console commands and needs to interact with the
console. Let's say I wrote a console command mattie_exec that took Con_Argv(1)
and passed it to exec with a different directory prefix (e.g. my mod's
directory).

// server.cfg
mattie_exec blah.cfg
exec load_plugins.cfg
// end of server.cfg

Now, the mattie_exec command, all it does is call engine-ServerCommand(exec
matties_mod\blah.cfg\n). In this case, the console would execute like this:

1. (contents of server.cfg added to the queue around LevelInit())
2. mattie_exec runs (places exec mattie_mod\blah.cfg at end of queue)
3. exec load_plugins.cfg runs (all plugins activated, configured, etc)
4. exec mattie_mod\blah.cfg runs

You see that even though the mattie_exec command was placed in a certain order
in the cfg file, it's irrelevant. Any server commands those commands rely upon
cannot be activated until after the entire .cfg file has been processed. This
means that if the load_plugins.cfg relied upon any settings created in
blah.cfg, there's no way at all to get it to work short of bypassing the plugin
commands.

Admittedly, this is a simple example, but it underscores the issue outside of a
scripting context. Plugin console commands could be calling back to any number
of other console commands. We all have access to ServerCommand(), right? Well,
just like Valve, we need it's sister command in order to create proper console
commands. Sometimes we don't care about ordering, so ServerCommand() might be
appropriate, but many times ordering *will* be important. We truly need
ServerInsertCommand(), and I hope everyone can see that.

Thanks for your help and for reading this far,
-Mattie

- Original Message -
From: Jeremy Swigart [EMAIL PROTECTED]
To: hlcoders@list.valvesoftware.com
Sent: Friday, June 10, 2005 7:17 AM
Subject: Re: [hlcoders] Examples of uses for IEngine-ServerInsertCommand()



Have you considered using a scripting language such as lua or
gamemonkeyscript or another one that supports fake threading?
Specifically you might be interested in their ability to execute over
many frames, yet still be written in a top down manner. Here's an
example of GMS, which I use in my bot.

/ server.cfg
if(sv_gravity  800)
{
exec(reset_grav.cfg);
echo(gravity reset);
yield(); // suspend execution of the script till the next frame, can
also do sleep() commands
}
else
{
echo(gravity is fine);
}
echo(this happens the frame after the gravity is reset, or right away
if the exec didnt happen);

Everything you do and much more would be possible using the features
of an existing scripting language, and with it you'd get the power of
conditionals, tables, loops, and much more.

Just an idea.

J

On 6/9/05, Mattie Casper [EMAIL PROTECTED] wrote:


As promised, this email contains examples of the sorts of things that plugin
authors cannot manage in Source without some method to insert commands at the
beginning of the server command queue. This ability is vital for any plugin
wishing to create meta console commands. I.e. commands like alias, exec,
incrementvar, etc.

Variable expansion --

  EventScripts makes extensive use of variable expansion for its console
commands, and it's crippled without

Re: [hlcoders] Examples of uses for IEngine-ServerInsertCommand()

2005-06-10 Thread Jeremy Swigart
I could be wrong, but even if ServerInsertCommand() puts the script
command at the front of the queue as opposed to the back, that still
wouldn't be executed until the current script is finished. Sounds like
really what you need is ServerCommandNow() that executes it right now,
so that when the next line of the current script runs, it can be sure
that the results of the script it just invoked is already done. Sounds
like even with ServerInsertCommand() it is gonna be a pain to get the
ordering right.

On 6/10/05, Mattie Casper [EMAIL PROTECTED] wrote:
 Thanks for the suggestion, but, as you may have guessed, this has been
 considered. ;)  Yet, creating an entire scripting engine isn't the goal of
 EventScripts. There are lots of different scripting engines out there, and 
 they
 definitely have their place for administrators who understand coding.
 EventScripts is trying to be the middle-ground between a structured/scoped
 language and the console commands they know and love. As I mentioned below, ES
 doesn't yet support looping and the like and may never do so--- it's not
 intended to be a full-powered scripting language.

 With EventScripts, we're trying to enhance the console commands so that even
 everyday normal console/rcon commands and normal autoexec.cfg/server.cfg files
 can take advantage of very simple logic and variable expansion. We don't need
 everything a scripting language can do, we just want some basic enhancements 
 to
 the command console. Most of these console enhancements would be along the 
 lines
 Valve was already been moving, e.g. with setinfo and incrementvar.

 Yet, even in the case of a full blown scripting language, not having
 InsertCommand() means that any scripts/commands that you wished to invoke via 
 a
 normal Valve cfg file would have the same ordering problem if they needed to
 pass commands back to the server (e.g. exec, changelevel, kickid, etc). These
 commands would execute *after* the current .cfg file was totally resolved and
 not in-place. This wouldn't be intuitive and would likely cause problems! It
 wouldn't be a problem if you didn't allow the console to launch scripts, but 
 the
 server console is a great place for invoking things like that (especially
 remotely).

 *** TO CLARIFY, this isn't a problem just for scripting engines! *** It's a
 problem for ANY PLUGIN that uses console commands and needs to interact with 
 the
 console. Let's say I wrote a console command mattie_exec that took 
 Con_Argv(1)
 and passed it to exec with a different directory prefix (e.g. my mod's
 directory).

 // server.cfg
 mattie_exec blah.cfg
 exec load_plugins.cfg
 // end of server.cfg

 Now, the mattie_exec command, all it does is call engine-ServerCommand(exec
 matties_mod\blah.cfg\n). In this case, the console would execute like this:

 1. (contents of server.cfg added to the queue around LevelInit())
 2. mattie_exec runs (places exec mattie_mod\blah.cfg at end of queue)
 3. exec load_plugins.cfg runs (all plugins activated, configured, etc)
 4. exec mattie_mod\blah.cfg runs

 You see that even though the mattie_exec command was placed in a certain order
 in the cfg file, it's irrelevant. Any server commands those commands rely upon
 cannot be activated until after the entire .cfg file has been processed. This
 means that if the load_plugins.cfg relied upon any settings created in
 blah.cfg, there's no way at all to get it to work short of bypassing the 
 plugin
 commands.

 Admittedly, this is a simple example, but it underscores the issue outside of 
 a
 scripting context. Plugin console commands could be calling back to any number
 of other console commands. We all have access to ServerCommand(), right? Well,
 just like Valve, we need it's sister command in order to create proper console
 commands. Sometimes we don't care about ordering, so ServerCommand() might be
 appropriate, but many times ordering *will* be important. We truly need
 ServerInsertCommand(), and I hope everyone can see that.

 Thanks for your help and for reading this far,
 -Mattie

 - Original Message -
 From: Jeremy Swigart [EMAIL PROTECTED]
 To: hlcoders@list.valvesoftware.com
 Sent: Friday, June 10, 2005 7:17 AM
 Subject: Re: [hlcoders] Examples of uses for IEngine-ServerInsertCommand()


  Have you considered using a scripting language such as lua or
  gamemonkeyscript or another one that supports fake threading?
  Specifically you might be interested in their ability to execute over
  many frames, yet still be written in a top down manner. Here's an
  example of GMS, which I use in my bot.
 
  / server.cfg
  if(sv_gravity  800)
  {
  exec(reset_grav.cfg);
  echo(gravity reset);
  yield(); // suspend execution of the script till the next frame, can
  also do sleep() commands
  }
  else
  {
  echo(gravity is fine);
  }
  echo(this happens the frame after the gravity is reset, or right away
  if the exec didnt happen);
 
  Everything you do and much more would be possible using

[hlcoders] Examples of uses for IEngine-ServerInsertCommand()

2005-06-09 Thread Mattie Casper


As promised, this email contains examples of the sorts of things that plugin
authors cannot manage in Source without some method to insert commands at the
beginning of the server command queue. This ability is vital for any plugin
wishing to create meta console commands. I.e. commands like alias, exec,
incrementvar, etc.

Variable expansion --

 EventScripts makes extensive use of variable expansion for its console
commands, and it's crippled without InsertCommand(). There's no way to arrange
for expanded commands to execute right away before the rest of a config file.
For example, let's say I added the following lines to a .cfg file (e.g.
server.cfg):

// server.cfg
// let's say 'mypluginvar' is a variable exposed by my plugin
mypluginvar ClanMatch
expandvars echo *** mypluginvar equals %mypluginvar%
echo *** The above line should say mypluginvar equals ClanMatch
echo *** server.cfg is completely done. should see nothing else.
// end server.cfg

So, if my plugin's 'expandvars' command expanded variables in the string
provided to it and then passed it back to the server, the only mechanism it can
use is ServerCommand(). This will place it AFTER everything else in the queue.
As such, the output would be:

*** The above line should say mypluginvar equals ClanMatch
*** server.cfg is completely done. should see nothing else.
*** mypluginvar equals ClanMatch

This is definitely not what someone writing a .cfg file would be expecting. They
expect the commands to go in order of writing. EventScripts supports a great
deal of variable expansion, but there's no support for intuitive ordering. This
example is trivial compared to the complicated scripts people are creating. It
really weakens the plugin when admins can't trust that your variables will be
expanded properly in relation to other commands in the cfg file.
-

Conditional expressions --
-
 EventScripts supports conditional expressions. These are also hindered without
InsertCommand(). The order of execution again gets all out of phase. For
example, let's say I added the following lines to a .cfg file (e.g. server.cfg):

// server.cfg
// let's say my plugin exposes an exec_if command
exec_if sv_gravity  800 then reset_grav.cfg
echo *** sv_gravity was set back to 800 by increase_grav.cfg
exec_if sv_gravity  800 then something_wrong.cfg
// end of server.cfg

In this case, the plugin command exec_if would test the condition sv_gravity
 800 and then use, sadly, ServerCommand() to place exec reset_grav.cfg in
the queue where it could reset the gravity back to 800. Unfortunately, this goes
to the very end of the queue, so the rest of the server.cfg executes first. This
means the second conditional will STILL see sv_gravity incorrectly because it
goes through the server command queue like this:

1. exec_if
2. echo
3. exec_if
4. exec reset_grav.cfg
5. exec something_wrong.cfg

#5 should never happen-- and #4 should happen before the 'echo' does. Yet we
can't do this because InsertCommand() isn't yet available to plugin writers.
-

Loops --
--
 EventScripts does not yet support loops, but these would also be possible if
Valve provided a way to insert commands at the beginning of the queue. Without
it, you cannot be certain that the loop lines will execute before the next line
in a script.
--

Enhanced versions of alias, exec, etc
-
EventScripts doesn't do this yet, but if I wanted to create an enhanced version
of these Valve commands, the new commands will always be deficient without
InsertCommand(). For example, if we wanted to write an optimized exec command
that cached the .cfg file in memory on the first execution and then always ran
it from memory whenever called (to avoid refetches from disk):

// server.cfg
memexec only_changes_on_reboot.cfg
exec load_plugins.cfg
// end of server.cfg

In this case, simulating exec is impossible if I wish to maintain the order of
a .cfg file. I.e., we can't cycle through the lines of the file and have them
inserted at the beginning of the command queue like Valve does. This means that
anytime we try to add the lines, they'll always fall *after* every other line in
the .cfg file. Order is important at times for plugins and the like, and without
that we just can't improve upon the console commands very well.
-


Anyway, I'm going to stop now because this is getting so long that I'm sure no
one will read it. ;) Rest assured that all of these things and more would be
possible if Valve enhanced the Source SDK to include a mechanism for adding
commands to the beginning of the queue.

Anyone curious about using EventScripts, you can find my forums here:
http://www.sourcemod.net/forums/viewforum.php?f=20

Thanks for reading this far. Maybe it will give other coders some ideas, too,
-Mattie