Multiple Scripts per Server

Discussion in 'Implemented' started by Pokemonexperte-Martin, Sep 16, 2011.

  1. Pokemonexperte-Martin

    Pokemonexperte-Martin Member

    Joined:
    May 15, 2010
    Messages:
    76
    Likes Received:
    0
    Scripts are growing and become confusing. For example the current scripts.js available from here has over 3000 lines of code. While some parts are interesting, others are not. I wish that there is a way to split up scripts. Some ideas:

    * A directory for scripts, all files inside are loaded
    * A function to include other scripts / snippets

    As a long-term quest, there could be a repository with snippets and feature collections.
     
  2. coyotte508

    coyotte508 Well-Known Member Administrator Server Owner Administrator Server Owner

    Joined:
    Apr 21, 2010
    Messages:
    6,363
    Likes Received:
    168
    Nice suggestion.

    This could be doable by creating sys.import(file, module). Then myengine.globalObject.setProperty(module, myengine.evaluate(readFromFile(file))).

    Actually, I did it (on branch devel).

    Code (text):
    1. sys.import("tour", "tournament.js"); //loads scripts/tournament.js and set it as the global tour property.
    2.  
    3. tour.doSomething();
    The imports can be placed before the ({ }) script object, or inside the code.

    Anyhow, branch devel, untested yet, and not definitive (I don't know if the order of the arguments should be reversed), but will be there for next version.

    As for the repository of script snippets, I count on the community of scripters to do that ;O.
     
  3. Lamperi

    Lamperi I see what you did there

    Joined:
    Apr 25, 2010
    Messages:
    2,647
    Likes Received:
    11
    I would prefer
    Code (text):
    1.  
    2. var tour = sys.import("tournaments.js");
    3.  
    actually ^

    Don't know if there should be some magic, you could do that import function in JS too..

    Code (text):
    1.  
    2. var import = function(filename) {
    3.     return eval(sys.getFileContents(filename));
    4. }
    5. var tour = import('tournaments.js')
    6.  
    and I actually used this a long time ago as a proof of separating stuff, but I actually added some pre-defined callbacks to the modules. PO will need them too if we want to make a script snippets library.
     
  4. Mystra

    Mystra Active Member

    Joined:
    Jul 12, 2010
    Messages:
    1,389
    Likes Received:
    4
    I'm just merging my separate files before adding them to PO.

    Code (makefile):
    1.  
    2. RESULT = result
    3.  
    4. all:
    5.     cat *.js > $(RESULT)/scripts.js
    6.  
    7. clean:
    8.     rm -f $(RESULT)/scripts.js
    9.  
    :}
     
  5. Pokemonexperte-Martin

    Pokemonexperte-Martin Member

    Joined:
    May 15, 2010
    Messages:
    76
    Likes Received:
    0
    When I checked out the po-sever-goodies this week, I had to cry - the scripts become more and more bloated.

    I still love the idea of a snippets / plugins / script library. For example, I am interested in the checkbot, but not at all in mafia, casino and other games.

    Here is a small proposal for script plugins (pseudo code of course):

    Code (text):
    1.  
    2. scripts.js MAIN:
    3.     importPlugin('common.js');
    4.     var mafia = importPlugin('mafia.js');
    5.     var tournament = importPlugin('tournament.js');
    6.     var checkbot = importPlugin('checkbot.js');
    7.  
    8. importPlugin(string file)
    9. {
    10.     plugin = load(file);
    11.     plugin.init();
    12.    
    13.     // http://tetlaw.id.au/view/blog/signals-and-slots-for-prototype-easy-custom-javaplugin-events/
    14.     // http://13thparallel.com/archive/sig-slots/
    15.     foreach(name in plugin.getHooks())
    16.         Signal.connect(script, name, plugin, name);
    17.    
    18.     GLOBAL.plugins.add(plugin);
    19.     return plugin;
    20. }
    21.  
    22. commandReceived(command, data)
    23. {
    24.     // Simple and stupid
    25.  
    26.     foreach(GLOBAL.plugins)
    27.         plugin.processCommand(command, data);
    28.        
    29.     // Cooler, further research neccessary to check if it is possible?
    30.    
    31.     Signal.emit(command + "Command", data);
    32. }
    33.  
    34. Displaying Commands and Rules:
    35. get them from each plugin and show alltogether (maybe with headings where they come from)
    36.  
    37. *** RULES ***
    38.  
    39. Global
    40. * 1
    41. * 2
    42. * 3
    43.  
    44. Mafia Game (script->name)
    45. * 1
    46. * 2
    47. * 3
    48.  
    49. *** COMMANDS ***
    50.  
    51. Global
    52. cmd1 Arguments: Description
    53.  
    54. Mafia Game
    55. cmd2 Arguments: Description
    56. =================================================
    57.  
    58. class Plugin
    59. {
    60.     string name;
    61.    
    62.     void init()
    63.     {
    64.         // Initialize variables, ensure files, etc ...
    65.     }
    66.    
    67.     string[][] getCommands()
    68.     {
    69.         return array[
    70.             'user': [
    71.                         ['command' : 'description'],
    72.                         ['command' : 'description'],
    73.                     ],
    74.             'mod':  [
    75.                         ['command' : 'description'],
    76.                         ['command' : 'description'],
    77.                     ]
    78.         ];
    79.     }
    80.    
    81.     string[] getHooks()
    82.     {
    83.         return array[
    84.             'afterChangeTeam',
    85.             'afterLogin'
    86.         ];
    87.     }
    88.    
    89.     string[] get Rules()
    90.     {
    91.         return array[
    92.             'Be nice',
    93.             'Dont cheat',
    94.             'Have a nive day'
    95.         ];
    96.     }
    97.    
    98.     // note: different plugins should be able to
    99.     bool processCommand(string command, string data)
    100.     {
    101.         switch(command)
    102.         {
    103.             case 'sample': return sampleCommandHandler(data);
    104.         }
    105.        
    106.         // Maybe using reflection?
    107.        
    108.         var method = command + "CommandHandler";
    109.         if( Reflection.methodExists(this, method) )
    110.         {
    111.             return Reflection.invoke(this, method);
    112.         }
    113.        
    114.         return false; // no command handler / command not processed
    115.     }
    116.    
    117.     function sampleCommandHandler(string data)
    118.     {
    119.     }
    120.    
    121.     function afterChangeTeam()
    122.     {
    123.         if(invalid) sys.stopEvent();
    124.        
    125.         // If solution above is not possible, return true (continue event) / false (stop event) and check in main
    126.     }
    127. }
    128.  
    What do you think about that?
     
  6. Lamperi

    Lamperi I see what you did there

    Joined:
    Apr 25, 2010
    Messages:
    2,647
    Likes Received:
    11