+ Reply to Thread
Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: E2 - Concommand Input

  1. #1
    Wirererer Incompatible's Avatar
    Join Date
    Jul 2007
    Posts
    156

    Default E2 - Concommand Input

    I was thinking of new ways of passing data from the outside world into the game, primarily for use in digital screen image displaying. So far I have been using a CPU with a massive amount of code generated from a PHP script I wrote to get all the colors of the pixels in game allowing me to mcopy it to the screen's memory.

    Although this worked great, it was fairly tedious and took ages to upload, compile, and execute the CPU.

    So I figured, why not add a concommand input to the E2, to allow it to receive data through concommands. So I did just that.

    Through my tests, I was able to send roughly 2000 commands a second and paint it correctly on the digital screens I had set up.

    There could be many other uses for this, including being able to bind keys to interface with the E2.

    I added a new concommand "wire_expression2_runcmd", and several functions for the E2.

    runOnCmd(N) -- toggles whether or not the E2 should execute when the command is entered, by default it is off, and this whole module will not work without it enabled before hand.

    cmdClk() -- Returns 1 if the E2 was executed by a command being run, 0 if not.

    cmdRan() -- Returns a string, of the command entered (The first argument)

    cmdArgs() -- Returns an array of strings returned by the command.
    If the expression was not executed by a concommand, cmdRan() will return "", and cmdArgs will return an empty array.


    And the part you have all been waiting for...

    Code:
    AddCSLuaFile('cmdinput.lua')
    
    //Original author: ZeikJT
    //Modified by Gwahir
    //Further Modified by Some Guy
    
    wire_exp2_RunOnCmd = {}
    local runByCmd = false
    local CmdRan = ""
    local CmdArgs = {}
    
    local function HasEnt(table, ent)
        if !ValidEntity(ent) then return false end
        local id = ent:EntIndex()
        for i,e in ipairs(wire_exp2_RunOnCmd) do
            if ValidEntity(e) && e:EntIndex() == id then return true end
        end
        return false
    end
    
    registerFunction("runOnCmd", "n", "", function(self, args)
        local op1 = args[2]
        local rv1 = op1[1](self, op1)
        if rv1 != 0 then
            if !HasEnt(wire_exp2_RunOnCmd, self.entity) then
                table.insert(wire_exp2_RunOnCmd,self.entity)
            end
        else
            for i,e in ipairs(wire_exp2_RunOnCmd) do
                if e == self.entity then
                    table.remove(wire_exp2_RunOnCmd,i)
                    break
                end
            end
        end
    end)
    
    registerFunction("cmdClk", "", "n", function(self, args)
        if runByCmd then return 1 else return 0 end
    end)
    
    registerFunction("cmdRan", "", "s", function(self, args)
        return CmdRan
    end)
    
    registerFunction("cmdArgs", "", "r", function(self, args)
        return CmdArgs
    end)
    
    registerCallback("destruct",function(self)
        if !ValidEntity(self.entity) then return end
        for i,e in ipairs(wire_exp2_RunOnCmd) do
            if e == self.entity then
                table.remove(wire_exp2_RunOnCmd,i)
                break
            end
        end
    end)
    
    function Exp2ReceiveCmd( ply, cmd, args )
        runByCmd = true
        CmdRan = args[1]
        table.remove(args,1)
        CmdArgs = args
        local clean = false
        for i,e in ipairs(wire_exp2_RunOnCmd) do
            if ValidEntity(e) && e.Execute != nil && e.player == ply then
                e:Execute()
            else
                clean = true
            end
        end
        runByCmd = false
        CmdRan = ""
        CmdArgs = {}
        if clean then
            local indexOffset = 0
            for i,e in ipairs(wire_exp2_RunOnCmd) do
                if e == nil || !e:IsValid() || e.Execute == nil then 
                    table.remove(wire_exp2_RunOnCmd, i - indexOffset)
                    indexOffset = indexOffset + 1
                    break 
                end
            end
        end
    end
    concommand.Add("wire_expression2_runcmd",Exp2ReceiveCmd)

    To use a concommand, it is quite simple. Just do:
    wire_expression2_runcmd <the command name> <args>...

    For example:
    wire_expression2_runcmd MyTest 13 47 56

    cmdRan() will return "MyTest"

    and cmdArgs() will return an array set up like so:
    [1] = "13"
    [2] = "47"
    [3] = "56"

    This is still limited by the max concommand length, which I believe is 255 characters.


    Credits: ZiekJT & Gwahi, I based this off the chat functions they wrote.


    If you have any questions, ideas, or suggestions, feel free to reply, or PM me.

  2. #2
    Wire Sofaking ZeikJT's Avatar
    Join Date
    Dec 2008
    Location
    California
    Posts
    1,391

    Default Re: E2 - Concommand Input

    All the credit for those particular code modifications go to Gwahir, I didn't write any of the clk functions.

    Also, it's a good idea for debug, but is it useful for anything else?

    EDIT: Useful in it's current state I mean.
    Against stupidity the Gods themselves contend in vain.
    -Friedrich Schiller

    The flame puts me in the mood to "Do it!".
    -Dart, Legend of Dragoon

  3. #3
    Expressionism 2.0 Syranide's Avatar
    Join Date
    Mar 2007
    Location
    Sweden
    Posts
    4,573

    Default Re: E2 - Concommand Input

    I discussed something along the lines of this not too long ago, however, for it to be reasonable, the commands needs to be registered clientside so one can't spam the server with useless commands.

    As far as use, I'd say it is limited, but it's one way for people to bind more keys for instance. But yeah, it's limited.

  4. #4
    Wirererer Incompatible's Avatar
    Join Date
    Jul 2007
    Posts
    156

    Default Re: E2 - Concommand Input

    As I mentioned I was looking for a better method of transfering data from the outside world, into the game. I was doing this for a long time with the CPU, by making a massive db and then mcopying it to the screens memory.

    Although it worked, it was tedious to set up, and took a long time to upload the CPU.


    I wouldn't say that this is very limited, since you could use it for almost any outside input. This is more of an "Interface with the outside world" type of thing. I have already begun drawing images on the digital screen with it, and it has been much faster than using the CPU method, and I am sure it is also much easier on the server.

    As for the commands being abuseable, I don't see how it would be more abuseable than any other command in the source engine. You would have to have an E2 that is enable to recieve a command for it to actually do anything major on the server. It could be used as a crude method of overclocking an E2, but the CPU has a far greater speed for that, since you are limited by how many commands you can send per tick. It is also currently limited to only the owner's expressions recieving the commands, to prevent other players from interfering.


    I can't currently think of a whole lot that could be done with this currently, other than transfering data from the client to the expression or binding keys to control it. But I do feel it is one of those very specialized tools that allows you to do things you otherwise could not.

  5. #5
    Expressionism 2.0 Syranide's Avatar
    Join Date
    Mar 2007
    Location
    Sweden
    Posts
    4,573

    Default Re: E2 - Concommand Input

    Quote Originally Posted by Incompatible View Post
    I wouldn't say that this is very limited, since you could use it for almost any outside input. This is more of an "Interface with the outside world" type of thing. I have already begun drawing images on the digital screen with it, and it has been much faster than using the CPU method, and I am sure it is also much easier on the server.
    Well, that's what I would call limited :P
    It has a pretty narrow purpose, transfering data as you say, that doesn't mean it's bad, just that it isn't likely that the majority of the E2-users would ever consider it.

    Quote Originally Posted by Incompatible View Post
    As for the commands being abuseable, I don't see how it would be more abuseable than any other command in the source engine. You would have to have an E2 that is enable to recieve a command for it to actually do anything major on the server. It could be used as a crude method of overclocking an E2, but the CPU has a far greater speed for that, since you are limited by how many commands you can send per tick. It is also currently limited to only the owner's expressions recieving the commands, to prevent other players from interfering.
    I didn't actually look or read closely, I though it looked like it created functions, not that it only was a single command. But then of course, it's not a problem.

    (Also, max command-length is less than 256, I think 256 is including the command name itself)

  6. #6
    Wirererer Incompatible's Avatar
    Join Date
    Jul 2007
    Posts
    156

    Default Re: E2 - Concommand Input

    So what do I need to do to get this included? It could be very useful in the future, although most people will have no idea what to do with it, it still expands capabilities and I cannot think of a single way that it can be exploited beyond what can already be done in the source engine itself.

  7. #7
    Aut
    Aut is offline
    Wire Amateur Aut's Avatar
    Join Date
    Jun 2007
    Posts
    66

    Default Re: E2 - Concommand Input

    I could see having a bit of use out of this, it would be quite useful.

  8. #8
    Expressionism 2.0 Syranide's Avatar
    Join Date
    Mar 2007
    Location
    Sweden
    Posts
    4,573

    Default Re: E2 - Concommand Input

    Quote Originally Posted by Incompatible View Post
    So what do I need to do to get this included? It could be very useful in the future, although most people will have no idea what to do with it, it still expands capabilities and I cannot think of a single way that it can be exploited beyond what can already be done in the source engine itself.
    There are a few things that would need to be improved, but I can definately see this being of use and it being on the SVN.

    1. E2s need to be registered per player, so they can be cleaned up on disconnect (destruct is only run when entities are removed)
    2. Perhaps some kind of call-sign system, so you can use it as "..._runcmd MyE2 1 2 3", and that will send "1 2 3" to whatever E2s are registered as "MyE2" (and perhaps add a cmdClk(S) to test for only certain commands)
    3. Make Your commands only be recognized by Your expressions

    Or what do you all think?

    (Check the GameTick-extension to get some of it for free)

  9. #9
    Wirererer Incompatible's Avatar
    Join Date
    Jul 2007
    Posts
    156

    Default Re: E2 - Concommand Input

    Quote Originally Posted by Syranide View Post
    There are a few things that would need to be improved, but I can definately see this being of use and it being on the SVN.

    1. E2s need to be registered per player, so they can be cleaned up on disconnect (destruct is only run when entities are removed)
    2. Perhaps some kind of call-sign system, so you can use it as "..._runcmd MyE2 1 2 3", and that will send "1 2 3" to whatever E2s are registered as "MyE2" (and perhaps add a cmdClk(S) to test for only certain commands)
    3. Make Your commands only be recognized by Your expressions

    Or what do you all think?

    (Check the GameTick-extension to get some of it for free)
    #1. Will do

    #2. It already Does that. cmdClk() only returns whether or not the E2 was run by a command or not. cmdRan() returns a string, of the first Argument, which is used as the "Command name" then cmdArgs() returns the 2nd and on args. So it I did: wire_expression2_runcmd MyE2 1 2 3, My E2 code would look like this:

    Code:
    if (first())
    {
         runOnCmd(1)
    }
    if (cmdClk())
    {
         if (cmdRan() == "MyE2")
         {
              Args = cmdArgs()
              print(Args:string(1))
              print(Args:string(2))
              print(Args:string(3))   
         }
    }
    #3. Does that as well.

    Code:
    if ValidEntity(e) && e.Execute != nil then
                if (e.player == ply) then //DO NOT RUN UNLESS IT IS YOUR EXPRESSION
                    e:Execute()
                end
            else

    I will fix #1 after I get breakfast.

  10. #10
    Wirererer Incompatible's Avatar
    Join Date
    Jul 2007
    Posts
    156

    Default Re: E2 - Concommand Input

    8 months late, but... Better now than never.

    I lost track of this after this post due to other things going on at the time, but THIS thread reminded me of it, so I fixed it up and it matches all the above discussed conditions.

    Code:
    //Base code by Gwahir
    //Functions and functionality by Incompatible
    
    /********Vars********/
    wire_exp2_RunOnCmd = {}
    local runByCmd = false
    local CmdRan = ""
    local CmdArgs = {}
    /********************/
    
    
    /********Helper Functions********/
    local function HasEnt(table, ent)
        if ValidEntity(ent) then
            for i,e in ipairs(wire_exp2_RunOnCmd) do
                if ValidEntity(e) && e == ent then return true end
            end
        end
        return false
    end
    
    
    
    /********Actual Functions********/
    
    registerFunction("runOnCmd", "n", "", function(self, args)
        local op1 = args[2]
        local rv1 = op1[1](self, op1)
        if rv1 != 0 then
            if !HasEnt(wire_exp2_RunOnCmd, self.entity) then
                table.insert(wire_exp2_RunOnCmd,self.entity)
            end
        else
            for i,e in ipairs(wire_exp2_RunOnCmd) do
                if e == self.entity then
                    table.remove(wire_exp2_RunOnCmd,i)
                    break
                end
            end
        end
    end)
    
    registerFunction("cmdClk", "", "n", function(self, args)
        if runByCmd then return 1 else return 0 end
    end)
    
    registerFunction("cmdRan", "", "s", function(self, args)
        return CmdRan
    end)
    
    registerFunction("cmdArgs", "", "r", function(self, args)
        return CmdArgs
    end)
    
    
    
    /********Cleanup Functions********/
    registerCallback("destruct",function(self)
        if !ValidEntity(self.entity) then return end
        for i,e in ipairs(wire_exp2_RunOnCmd) do
            if e == self.entity then
                table.remove(wire_exp2_RunOnCmd,i)
                break
            end
        end
    end)
    
    hook.Add( "EntityRemoved", "wire_expression2_concmd_playercleanup", function( ply )
        if (ply:IsPlayer()) then
            local indexOffset = 0
            for i,e in ipairs(wire_exp2_RunOnCmd) do
                if e.player == ply then
                    table.remove(wire_exp2_RunOnCmd, i - indexOffset)
                    indexOffset = indexOffset + 1
                end
            end
        end
    end )
    
    
    /********Backend Functionality********/
    function Exp2ReceiveCmd( ply, cmd, args )
        runByCmd = true
        CmdRan = args[1] or ""
        table.remove(args,1)
        CmdArgs = args or {}
        if (CmdRan != "" and CmdArgs != {}) then
            local clean = false
            for i,e in ipairs(wire_exp2_RunOnCmd) do
                if ValidEntity(e) && e.Execute != nil then
                    if (e.player == ply) then
                        e:Execute()
                    end
                else
                    clean = true
                end
            end
            if clean then
                local indexOffset = 0
                for i,e in ipairs(wire_exp2_RunOnCmd) do
                    if !ValidEntity(e) || e.Execute == nil then 
                        table.remove(wire_exp2_RunOnCmd, i - indexOffset)
                        indexOffset = indexOffset + 1
                        break 
                    end
                end
            end
        end
        runByCmd = false
        CmdRan = ""
        CmdArgs = {}
    end
    concommand.Add("wire_expression2_runcmd",Exp2ReceiveCmd)

+ Reply to Thread
Page 1 of 2 12 LastLast

Similar Threads

  1. E2 Developer Concommand
    By ZeikJT in forum Wiremod Addons & Coding
    Replies: 18
    Last Post: 03-11-2009, 05:58 PM
  2. Exp concommand
    By somone77 in forum Ideas & Suggestions
    Replies: 4
    Last Post: 01-21-2009, 06:11 AM
  3. Expressions with concommand('say $')
    By Captain Maim in forum Bug Reports
    Replies: 3
    Last Post: 10-26-2008, 03:56 AM
  4. ConCommand blocked
    By Ergzay in forum Bug Reports
    Replies: 5
    Last Post: 06-06-2008, 01:18 PM
  5. Concommand blocked (Crosshair 1)
    By andy1976uk in forum Installation and Malfunctions Support
    Replies: 0
    Last Post: 02-03-2008, 04:45 AM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
proceed-collector
proceed-collector
proceed-collector
proceed-collector
linguistic-parrots
linguistic-parrots
linguistic-parrots
linguistic-parrots