Python Scripts | Merry Christmas 2016!

Results 1 to 10 of 10
  1. #1
    Interesting... SharpAceX is offline
    MemberRank
    Oct 2008 Join Date
    2,011Posts

    Python Scripts | Merry Christmas 2016!

    Is your server trash because it is exactly like everybody else's? Are you desperately looking for anything unique to differentiate your server from the competition? Well, look no further.

    Introducing Python scripts! Think about the level of prestige, status and elitism that comes with being the only public live server that uses Python for its scripts. You can put that feature on your gtop listing and draw in hundreds of new players.

    Alright so let's get started on implementing this bad boy. I did this implementation on the masterrace source Solaxia but since Odin's scripting engine hasn't really been touched since the Vietnam war, this should work on every source.

    In ServerConstants, add this:
    PHP Code:
    //Scripting Configuration
    public static final String SCRIPTING_ENGINE "javascript";
    public static final 
    String SCRIPT_EXTENSION ".js"
    This helps modularize the language used for scripts in your source so you can painlessly change it back to Javascript should you choose to, or perhaps even use another language entirely.

    The following changes are going to be pretty repetitive but I will still list out all. In EventScriptManager, replace
    PHP Code:
    Invocable iv getInvocable("event/" script ".js"null); 
    with
    PHP Code:
    Invocable iv getInvocable("event/" script ServerConstants.SCRIPT_EXTENSIONnull); 
    In ItemScriptManager, replace
    PHP Code:
    File scriptFile = new File("scripts/item/" scriptName ".js");
    File scriptFile = new File("scripts/item/" scriptName ".js");
    sef sem.getEngineByName("javascript").getFactory(); 
    with
    PHP Code:
    File scriptFile = new File("scripts/item/" scriptName ServerConstants.SCRIPT_EXTENSION);
    File scriptFile = new File("scripts/item/" scriptName ServerConstants.SCRIPT_EXTENSION);
    sef sem.getEngineByName(ServerConstants.SCRIPTING_ENGINE).getFactory(); 
    In MapScriptManager, replace
    PHP Code:
    sef sem.getEngineByName("javascript").getFactory();
    File scriptFile = new File("scripts/map/" + (firstUser "onFirstUserEnter/" "onUserEnter/") + scriptName ".js");
    File scriptFile = new File("scripts/map/" type scriptName ".js"); 
    with
    PHP Code:
    sef sem.getEngineByName(ServerConstants.SCRIPTING_ENGINE).getFactory();
    File scriptFile = new File("scripts/map/" + (firstUser "onFirstUserEnter/" "onUserEnter/") + scriptName ServerConstants.SCRIPT_EXTENSION);
    File scriptFile = new File("scripts/map/" type scriptName ServerConstants.SCRIPT_EXTENSION); 
    In NPCScriptManager, replace
    PHP Code:
    iv getInvocable("npc/world" c.getWorld() + "/" fileName ".js"c);
    iv getInvocable("npc/world" c.getWorld() + "/" npc ".js"c);
    resetContext("npc/world" c.getWorld() + "/" cm.getScriptName() + ".js"c);
    resetContext("npc/world" c.getWorld() + "/" cm.getNpc() + ".js"c); 
    with
    PHP Code:
    iv getInvocable("npc/world" c.getWorld() + "/" fileName ServerConstants.SCRIPT_EXTENSIONc);
     
    iv getInvocable("npc/world" c.getWorld() + "/" npc ServerConstants.SCRIPT_EXTENSIONc);
    resetContext("npc/world" c.getWorld() + "/" cm.getScriptName() + ServerConstants.SCRIPT_EXTENSIONc);
    resetContext("npc/world" c.getWorld() + "/" cm.getNpc() + ServerConstants.SCRIPT_EXTENSIONc); 
    In PortalScriptManager, replace
    PHP Code:
    sef sem.getEngineByName("javascript").getFactory();
    File scriptFile = new File("scripts/portal/" scriptName ".js"); 
    with
    PHP Code:
    sef sem.getEngineByName(ServerConstants.SCRIPTING_ENGINE).getFactory();
    File scriptFile = new File("scripts/portal/" scriptName ServerConstants.SCRIPT_EXTENSION); 
    In QuestScriptManager, replace
    PHP Code:
    Invocable iv getInvocable("quest/" questid ".js"c);
    Invocable iv getInvocable("quest/" questid ".js"c);
    resetContext("quest/" qm.getQuest() + ".js"c); 
    with
    PHP Code:
    Invocable iv getInvocable("quest/" questid ServerConstants.SCRIPT_EXTENSIONc);
    Invocable iv getInvocable("quest/" questid ServerConstants.SCRIPT_EXTENSIONc);
    resetContext("quest/" qm.getQuest() + ServerConstants.SCRIPT_EXTENSIONc); 
    In ReactorScriptManager, replace
    PHP Code:
    Invocable iv getInvocable("reactor/" reactor.getId() + ".js"c);
    Invocable iv getInvocable("reactor/" reactor.getId() + ".js"c); 
    with
    PHP Code:
    Invocable iv getInvocable("reactor/" reactor.getId() + ServerConstants.SCRIPT_EXTENSIONc);
    Invocable iv getInvocable("reactor/" reactor.getId() + ServerConstants.SCRIPT_EXTENSIONc); 
    Finally, in your AbstractScriptManager, replace
    PHP Code:
    engine sem.getEngineByName("javascript");
    if (
    ServerConstants.JAVA_8){
        
    engine.eval("load('nashorn:mozilla_compat.js');");

    with
    PHP Code:
    engine sem.getEngineByName(ServerConstants.SCRIPTING_ENGINE);
    if (
    ServerConstants.JAVA_8 && ServerConstants.SCRIPTING_ENGINE.equals("javascript")){
        
    engine.eval("load('nashorn:mozilla_compat.js');");

    And there you have it, the implementation is that easy. This could obviously be accomplished with a simple IDE search + replace, but I listed out all the steps anyways. Now that you can switch your source's scripting language, let's switch it to Python boyssssssssssssss.

    PHP Code:
    //Scripting Configuration
    public static final String SCRIPTING_ENGINE "python";
    public static final 
    String SCRIPT_EXTENSION ".py"
    We will need a dependency for this to actually work, and for this we will use Jython. Grab yourself a copy by clicking here. I used Jython 2.5.4rc1 so I recommend you also use that. I cannot vouch for Jython 2.7.0 or any other version since I did not personally test it on those. Once you have your standalone jar, put in your dist folder and add it as an external jar like you would when originally setting up any source. Once you have done this, your source is fully ready to read and evaluate python scripts!

    Being Christmas and all, I have decided to release a carbon-copy conversion of a random Javascript NPC script into Python, just to show how relatively easy it actually is to switch over entirely.

    Below is a basic NPC script in Javascript written by RageZone's greatest member ever, Moogra, and then followed by my carbon-copy version in Python.
    PHP Code:
    /*
        This file is part of the OdinMS Maple Story Server
        Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
                   Matthias Butz <matze@odinms.de>
                   Jan Christian Meyer <vimes@odinms.de>

        This program is free software: you can redistribute it and/or modify
        it under the terms of the GNU Affero General Public License as
        published by the Free Software Foundation version 3 as published by
        the Free Software Foundation. You may not use, modify or distribute
        this program under any other version of the GNU Affero General Public
        License.

        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU Affero General Public License for more details.

        You should have received a copy of the GNU Affero General Public License
        along with this program.  If not, see <http://www.gnu.org/licenses/>.
    */
    /* NPC:     Thomas Swift
     * Maps:    100000000, 680000000
     * Author:  Moogra
     * Purpose: Amoria warper.
    */

    status = -1;

    function 
    start() {
        if (
    cm.getPlayer().getMapId() == 100000000)
            
    cm.sendYesNo("I can take you to the Amoria Village. Are you ready to go?");
        else
            
    cm.sendYesNo("I can take you back to Henesys. Are you ready to go?");
    }

    function 
    action(modetypeselection) {
        
    status++;
        if (
    mode != 1) {
            if (
    mode == 0)
                
    cm.sendOk("Ok, feel free to hang around until you're ready to go!");
            
    cm.dispose();
            return;
        }
        if (
    status == 0)
            
    cm.sendNext("I hope you had a great time! See you around!");
        else if (
    status == 1) {
            if (
    cm.getPlayer().getMapId() == 100000000)
                
    cm.warp(6800000000);
            else
                
    cm.warp(1000000005);
            
    cm.dispose();
        }

    and now my version in Python
    PHP Code:
    '''
        This file is part of the OdinMS Maple Story Server
        Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
                   Matthias Butz <matze@odinms.de>
                   Jan Christian Meyer <vimes@odinms.de>

        This program is free software: you can redistribute it and/or modify
        it under the terms of the GNU Affero General Public License as
        published by the Free Software Foundation version 3 as published by
        the Free Software Foundation. You may not use, modify or distribute
        this program under any other version of the GNU Affero General Public
        License.

        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU Affero General Public License for more details.

        You should have received a copy of the GNU Affero General Public License
        along with this program.  If not, see <http://www.gnu.org/licenses/>.
    '''
    ''' NPC:     Thomas Swift
        Maps:    100000000, 680000000
        Author:  Moogra
        Purpose: Amoria warper.
    '''

    status = -1;

    def start():
        if (
    cm.getPlayer().getMapId() == 100000000):
            
    cm.sendYesNo("I can take you to the Amoria Village. Are you ready to go?")
        else:
            
    cm.sendYesNo("I can take you back to Henesys. Are you ready to go?")

    def action(modetypeselection):
        global 
    status
        status 
    += 1
        
    if (mode != 1):
            if (
    mode == 0):
                
    cm.sendOk("Ok, feel free to hang around until you're ready to go!")
            
    cm.dispose()
            return
        if (
    status == 0):
            
    cm.sendNext("I hope you had a great time! See you around!")
        
    elif (status == 1):
            if (
    cm.getPlayer().getMapId() == 100000000):
                
    cm.warp(6800000000)
            else:
                
    cm.warp(1000000005)
            
    cm.dispose() 
    As you can see, it practically takes no effort at all to convert. There are virtually no real differences between those two above scripts. As a general overview, you simply add a colon where an opening brace would be, delete all closing braces and semicolons, use Python's comment syntax instead of Javascript's, and you're already like literally 90% of the way done converting. The remaining 10% will simply be resolving any little quirks unique to Python like
    PHP Code:
    global status 
    Without going into too much detail since this obviously isn't a Python tutorial thread, without that line, Python would read the variable "status"
    PHP Code:
    status += 
    as a new local variable instead of the externally defined one. The global keyword tells Python that you are referring to the "status" variable defined outside of action's scope, and thus it now works exactly as you would expect it to, like the Javascript version.

    Frequently Asked Questions
    Spoiler:

    1) Okay that's cool but all my scripts are in Javascript...?
    Spoiler:
    lol tru

    2) So basically you want me to rewrite all my scripts to Python?
    Spoiler:
    lol yea tbh

    3) So is there any practical use for this release?
    Spoiler:
    In all seriousness, it's cool to do things differently and while it probably isn't worth the effort to convert all your scripts over, I'm like 85% confident I could simply write a tool to translate all OdinMS Javascript scripts to Python in such a way that you could realistically be fully converted in just a few hours of work from start to finish. A couple hours of work for a pretty unique feature like this with little to no side effect (at least none I can think of right now) could be worth it depending on how you view things. So to ultimately answer this question, it is legitimately practical if you actually want to put in a bit of effort to make the switch entirely. Otherwise, then no, this release isn't all that practical for you. I just needed something memey af to release for Christmas and this was perfect.

    4) So are you also releasing that conversion tool?
    Spoiler:
    If by some miracle there is legitimate interest in Python scripts, then yeah, I actually would write and release a conversion tool. But obviously not if nobody would use it.



    Shameless Plug
    Spoiler:
    If you're not part of the MapleStory development discord by now, you should certainly join it by clicking here. You can dick around with the greatest memers around including the likes of Zygon, Eric, PacketBakery and many others.


    Merry Christmas everybody!



  2. #2
    Yuki Zygon is offline
    MemberRank
    Aug 2008 Join Date
    IllinoisLocation
    1,208Posts

    Re: Python Scripts | Merry Christmas 2016!

    This release gives me cancer. Good work.

  3. #3
    Valued Member xenophyr is offline
    MemberRank
    Nov 2015 Join Date
    100Posts

    Re: Python Scripts | Merry Christmas 2016!

    I honestly do not think that Python will attract new players, but thank you for the release.

  4. #4
    I'm overrated. Fraysa is offline
    MemberRank
    Apr 2008 Join Date
    4,891Posts

    Re: Python Scripts | Merry Christmas 2016!

    Quote Originally Posted by xenophyr View Post
    I honestly do not think that Python will attract new players, but thank you for the release.
    de_memes...?

    @op ty for rls, i actually use python as well =)
    masterrace!


  5. #5
    Account Upgraded | Title Enabled! Buya is offline
    MemberRank
    Oct 2008 Join Date
    1,303Posts

    Re: Python Scripts | Merry Christmas 2016!

    This idea is actually very interesting (though I don't need your code, lol).
    I will consider using Python as the scripting engine for my C++ source.
    I have never thought of this before, thank you.

  6. #6
    Interesting... SharpAceX is offline
    MemberRank
    Oct 2008 Join Date
    2,011Posts

    Re: Python Scripts | Merry Christmas 2016!

    Quote Originally Posted by xenophyr View Post
    I honestly do not think that Python will attract new players, but thank you for the release.
    Clearly you have never run a popular server in your life. Python DOES attract new players.

    Quote Originally Posted by Fraysa View Post
    de_memes...?

    @op ty for rls, i actually use python as well =)
    masterrace!

    Nice, at least they aren't hardcoded.

    Quote Originally Posted by Buya View Post
    This idea is actually very interesting (though I don't need your code, lol).
    I will consider using Python as the scripting engine for my C++ source.
    I have never thought of this before, thank you.
    Let's launch the Python revolution and take down the Javascript empire.

  7. #7
    Valued Member Burgundy is offline
    MemberRank
    Mar 2015 Join Date
    126Posts

    Re: Python Scripts | Merry Christmas 2016!

    Down with js!

    Edit: Groovy would also be a cool substitute

  8. #8
    Account Upgraded | Title Enabled! GabrielSin is offline
    MemberRank
    Apr 2010 Join Date
    483Posts

    Re: Python Scripts | Merry Christmas 2016!

    Yes, I also advise Groovy, it's light years ahead of Phyton!

  9. #9
    Valued Member xenophyr is offline
    MemberRank
    Nov 2015 Join Date
    100Posts

    Re: Python Scripts | Merry Christmas 2016!

    Quote Originally Posted by SharpAceX View Post
    Clearly you have never run a popular server in your life. Python DOES attract new players.
    No need to get aggressive; I was just stating my opinion from the perspective of a player.

  10. #10
    Account Upgraded | Title Enabled! Snopboy is offline
    MemberRank
    Sep 2011 Join Date
    Kerning PQLocation
    1,057Posts

    Re: Python Scripts | Merry Christmas 2016!

    Quote Originally Posted by xenophyr View Post
    No need to get aggressive; I was just stating my opinion from the perspective of a player.
    Python is so good at attracting players to your server that even Neckson will come ;)



Advertisement