Author Topic: Scripting  (Read 6397 times)

ChillDave

  • Newbie
  • *
  • Posts: 3
Scripting
« on: January 30, 2011, 10:25:58 PM »
Tell me if I'm on the wrong track :)

In FormMain.cs ...
Code: [Select]
public void LoadScripts()
        {
            // loads all script
            loadedScripts.Clear();

            if (FormMain.Instance.IceChatOptions.ScriptFiles == null) return;

            foreach (string scriptFile in iceChatOptions.ScriptFiles)
            {
                System.Diagnostics.Debug.WriteLine("Load Script " + scriptFile);

                System.CodeDom.Compiler.CodeDomProvider cp = new Microsoft.CSharp.CSharpCodeProvider();

                string[] referenceAssemblies = { "System.dll", "System.Windows.Forms.dll" };

                System.CodeDom.Compiler.CompilerParameters par = new System.CodeDom.Compiler.CompilerParameters(referenceAssemblies);
                //par.ReferencedAssemblies.Add(Application.StartupPath + System.IO.Path.DirectorySeparatorChar + "IceChatScript.dll");
                par.ReferencedAssemblies.Add(Application.StartupPath + System.IO.Path.DirectorySeparatorChar + "IceChat2009.exe");
               
                par.GenerateExecutable = false;
                par.GenerateInMemory = true;
                par.CompilerOptions = "/target:library";
                par.IncludeDebugInformation = true;
                par.TreatWarningsAsErrors = false;
                par.MainClass = "IceChat.Script";

                System.Diagnostics.Debug.WriteLine("Total References Assemblies " + par.ReferencedAssemblies.Count);

                System.CodeDom.Compiler.CompilerResults err = cp.CompileAssemblyFromSource(par, File.ReadAllText(scriptFile));
                if (err.Errors.Count > 0)
                {
                    foreach (System.CodeDom.Compiler.CompilerError ce in err.Errors)
                    {                       
                        FormMain.Instance.WindowMessage(null, "Console", "Script Error: " + ce.ErrorNumber + ":" + ce.ToString(), 4, true);
                    }
                    FormMain.Instance.WindowMessage(null, "Console", "ERROR: Script \"" + scriptFile + "\". has " + err.Errors.Count + " errors. Script not loaded", 4, true);
                   
                    continue;  // jump to next script without loading this.
                }
               
                //object o = err.CompiledAssembly.CreateInstance("IceChat.Script"); // not needed, naming makes it fail anyway

                FormMain.Instance.WindowMessage(null, "Console", "Script \"" + scriptFile + "\". loaded.", 4, true);

                Type type = err.CompiledAssembly.GetType("IceChat.IceChatScript");
                if (type == null)
                {
                    FormMain.Instance.WindowMessage(null, "Console", "Script Error: 'class IceChatScript' not defined", 4, true);
                    continue;
                }
                MethodInfo mi = type.GetMethod("Main");
                if (mi == null)
                {
                    FormMain.Instance.WindowMessage(null, "Console", "Script Error: 'Main()' not defined", 4, true);
                    continue;
                }

                try
                {
                    mi.Invoke(null, null);
                    FormMain.Instance.WindowMessage(null, "Console", "Executed " + mi.Name + " in " + scriptFile, 5, true);
                }
                catch
                {
                    FormMain.Instance.WindowMessage(null, "Console", "Script Error @ " + mi.Name + " in " + scriptFile, 5, true);
                    continue;
                }

                loadedScripts.Add(type);
            }
        }

        public void callScriptMethods(String name, Object[] args)
        {
            MethodInfo mi ;

            foreach (Type t in loadedScripts)
            {
                mi = t.GetMethod(name);

                if (mi != null)
                {
                    System.Diagnostics.Debug.WriteLine("Invoking:" + mi.Name);
                    mi.Invoke(this, args);
                }
            }
        }

will require a new entry into each IRC event located in FormMainEvents.cs ...

Code: [Select]
       
private void OnChannelJoin(IRCConnection connection, string channel, string nick, string host, bool refresh)
        {
            callScriptMethods("OnChannelJoin",new Object[] { connection, channel, nick, host, refresh });

            IceTabPage t = GetWindow(connection, channel, IceTabPage.WindowType.Channel);
            if (t != null)
            {
                if (refresh)
                {
                    string msg = GetMessageFormat("Channel Join");
             ....

I'm new to reflection (as you may be able to tell), so any hints and tips always welcome ...

finally, the script file ...

Code: [Select]
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Reflection;

namespace IceChat
{
    public class IceChatScript
    {
        public delegate void OutGoingCommandDelegate(string command, object connection);
        public static event OutGoingCommandDelegate OutGoingCommand;

        static Timer t = new Timer();

        public static void SendCommand(string command, object connection)
        {
            System.Diagnostics.Debug.WriteLine("fire send command from IceChatScript Class");
            if (OutGoingCommand != null)
            {
                System.Diagnostics.Debug.WriteLine("run outgoingcommand");
                OutGoingCommand(command, connection);
            }
        }

        public static void IceChatScript_OutGoingCommand(string command, object connection)
        {
            System.Diagnostics.Debug.WriteLine("put it out:" + command);
        }

        public static void Main()
        {
            OutGoingCommand += new OutGoingCommandDelegate(IceChatScript_OutGoingCommand);

            MessageBox.Show("Script running :)");

            t.Tick += new EventHandler(tock);
            t.Interval = 600000;
            t.Start();
        }

        public static void OnChannelJoin(IRCConnection connection, string channel, string nick, string host, bool refresh)
        {
            System.Diagnostics.Debug.WriteLine(channel+ " < " + nick);
        }

        public static void OnChannelPart(IRCConnection connection, string channel, string nick, string host, string reason)
        {
            System.Diagnostics.Debug.WriteLine(channel + " > " + nick);
        }

        public static void tock(Object obj, EventArgs args)
        {
            System.Diagnostics.Debug.WriteLine("Tick Tock - still alive !");
        }
    }
}

The only problem I currently have is actually calling methods inside IceChat from the script, I imagine it's because IceChat needs to expose it methods (somehow!)
On Time, Cheap, Bug Free : Pick any two ...

Snerf

  • Administrator
  • Hero Member
  • *****
  • Posts: 1968
    • IceChat IRC Client
Re: Scripting
« Reply #1 on: January 31, 2011, 09:01:25 AM »
It is quite simple.  The Script Engine still needs to be worked on, as the contept is there, but most of the coding is not. It does need to re-done though, because the way it is now, will not work properly.

So the code will change dramatically once we get to that stage. Just working on other parts of the client to make sure it is all stable and good, and then work on the script engine, as it is the most complicated part of the client.
The IceChat God

ChillDave

  • Newbie
  • *
  • Posts: 3
Re: Scripting
« Reply #2 on: January 31, 2011, 10:04:54 AM »
I guess I was asking the wrong question then.

I'd like to contribute to the project, but need some direction from you as to whether or not you want some contribution, and if so, what would you like me to look at ?

I'm currently looking for a pet project to sink some time into, but will look elsewhere if your happy with your current set-up.

Have fun !
On Time, Cheap, Bug Free : Pick any two ...

Snerf

  • Administrator
  • Hero Member
  • *****
  • Posts: 1968
    • IceChat IRC Client
Re: Scripting
« Reply #3 on: January 31, 2011, 10:14:15 AM »
I was not saying you could not contribute, I was just saying that the way the code currently is for the script engine, it will change dramatically, so there is not any point on building on what is there.
The IceChat God

ChillDave

  • Newbie
  • *
  • Posts: 3
Re: Scripting
« Reply #4 on: January 31, 2011, 10:30:33 PM »
I was not saying you could not contribute, I was just saying that the way the code currently is for the script engine, it will change dramatically, so there is not any point on building on what is there.

ok, I appreciate that  :-)  So where would you like some work done - I know managing a project sucks, but are there a few areas where you would like to see some work done that would help, and not duplicate what is already being done ?
On Time, Cheap, Bug Free : Pick any two ...

Snerf

  • Administrator
  • Hero Member
  • *****
  • Posts: 1968
    • IceChat IRC Client
Re: Scripting
« Reply #5 on: January 31, 2011, 11:29:37 PM »
Currently, it is looking for bugs in the client.  I also believe outgoing DCC is not functional yet, you could take a look at that.
The IceChat God