How To: add Proxy/No Confuse/Fullscreen hacks to your client!

Discussion in 'Maplestory Accounts - Buy Sell Trade' started by toddddd, 12/17/16.

Thread Status:
Not open for further replies.
  1. toddddd

    toddddd
    Expand Collapse
    High Risk Status: This user has been flagged as high risk due to one or more reasons

    Offline
    Im not going to be releasing Proxy Only or Proxy + No Confuse or Proxy + No Confuse + Fullscreen clients anymore, the ones i just released for the most recent update are the last. I will only be releasing clients with all the hacks i like in them. So this will be a quick tutorial on how to add these 3 basic hacks to the game client on your own. And you can then pick and choose which hacks you want! If you only want fullscreen, then make one with just fullscreen! If you only want no confuse, then make one with no confuse! Etc etc etc etc you get the point.


    What you need:
    * JPEXS
    * Latest version of ROTMG swf file

    JPEXS: Okay so first you need to go download and install JPEXS decompiler. I love this thing, its very easy to use and does pretty much everything you will need to do for basic client hacking. I know a lot of people out there say to use RABCDAsm, but i feel like that tool is more advanced to use and is not needed if you are only going to add a few small hacks.

    Latest ROTMG swf: there is a nice url that auto-updates to the latest client build, so just go here and save it somewhere on your computer https://www.realmeye.com/appspot


    Once you have JPEXS installed and the swf file downloaded and saved, its time to get started!

    OPEN THE CLIENT
    Open the client swf file with JPEXS. Theres 2 ways to do this. You can either start JPEXS, go to "Open", and then locate the file and let it load. Or, depending if you installed JPEXS with this option or not, you can actually go to the client swf file in your computers file browser and right click on the swf, if you see an option in the drop down menu that says "Open with FFDec" then that will open JPEXS with the swf you selected already loaded. So do either one of those methods to get the file loaded and you should see something like this:
    [​IMG]

    JPEXS
    Get familiar with the layout of JPEXS and the swf. You will notice in the side bar of JPEXS there are some different folders under the client like "shapes, sprites, images, etc". These are the different parts of the swf. If you are going to edit something like the images you would expand the "images" folder or whatever you want. What we are going to be editing is the code, which is under the "scripts" folder. So go ahead and expand that folder to see the layout of the scripts inside the client. You should be seeing something like this now:
    [​IMG]

    ADDING HACKS
    Now its time to add some hacks. I would suggest looking through all the folders first and just get a feel for where things are, its helps to know where to find specific files. But to keep this tutorial simple i am just going to tell you how to find the files you need.

    The first hack i will cover with a little more detail to show how to use JPEXS to do the hacks, but the last two hacks i will just tell you the files and what to add to them.

    No Confuse
    This is by far the easiest hack to add, so i will cover it first. In JPEXS, under scripts, expand the folder "com", under that expand the folder "company", under that expand the folder "assembleegameclient", under that expand the folder "objects", and finally find the script called "GameObject" and click on it. When you click on the script the "ActionScript Source" panel should now look like this:
    [​IMG]
    Inside the Source panel, scroll down until about line 500. You should start seeing a lot of functions that look similar with names like "isQuite","isWeak","isSlowed","isDazed",etc etc. These are the functions that the client will use to determine if the player has a certain condition. So look through these functions until you find the one "isConfused" and click on the name of it. When you do this, you should now see the actionscript bytecode of that function appear in the 3rd panel like this:
    [​IMG]
    The "isConfused" function is a pretty simple function, and all it does is return a boolean value: "true" meaning you are confused, or "false" meaning you are not. To prevent us from being confused we need this function to return "false" all the time. The easiest way to do this is to add this code directly below the line that says "pushscope":
    Code:
    pushfalse
    returnvalue
    So to do this, hit the "Edit" button at the bottom of the third panel (not the one below the second panel that says "experimental" next to it!!!). This will allow you to make changes to the byte code of the function. So add those 2 lines to the code right below the pushscope line so it looks like this:
    [​IMG]
    Now hit the "Save" button at the bottom of the panel. Once you do this it should compile the changes you just made and reopen the Actionscript Source panel with the modifications you made. Now if you go and look at the "isConfused" function you should see the function looks like this:
    [​IMG]
    The function is going to always return false! No more confuse!!!!
    Now you aren't finished yet so dont close anything! To make the changes permanent you need to save the actual swf file! If you notice, the file name in the far left panel is actually in bold now. This is because you made changes to it and it isnt saved yet. So at the top of JPEXS hit the "Save" or "Save as..." button to save your new client swf file! Once you do this you can now go open the swf file you just saved with your flash projector and enjoy the game without confuse :)



    Proxy Server
    This hack is a little more complicated then no confuse, but still relatively simple. You need to go open the file "/kabam/rotmg/servers/control/ParseServerDataCommand". If the middle panel looks like this then you opened the right file (ignore the red circle for now, thats explained below):
    [​IMG]
    The idea behind this hack is to make a new function that acts almost exactly like the function "makeServer" in the code from the file. But our function will set up the localhost server for us.
    So first step is to create a new function and call it "LocalhostServer". To create a new function in JPEXS you need to press the button at the top left of the second panel that says "Add Trait" when you hover over it (i circled the button in the image above if you want to look). When you press it, a new window will popup titled "New Trait". We want this to be a public function, and not static. So make sure the static checkbox isnt checked, the first drop down has public selected, and the second drop down has Method selected. Then the textbox is where you put the name for the new function, so put LocalhostServer.
    [​IMG]
    Once you hit OK it will create an empty function at the very bottom of the script in the second panel. Go click on this function so it opens the bytecode in the third panel (if you dont know what that means you might want to read the No Confuse hack as i go into more detail about using JPEXS). Hit the "Edit" button to edit the functions byte code, select it all and replace it with this and then hit save:
    Code:
    trait method Qname(PackageNamespace(""),"LocalhostServer") dispid 0
    method
    name null
    returns Qname(PackageNamespace("kabam****tmg.servers.api"),"Server")

    body
    maxstack 6
    localcount 2
    initscopedepth 4
    maxscopedepth 5

    code
    getlocal_0
    pushscope
    findpropstrict Qname(PackageNamespace("kabam****tmg.servers.api"),"Server")
    constructprop Qname(PackageNamespace("kabam****tmg.servers.api"),"Server") 0
    pushstring "## Proxy Server ##"
    callproperty Qname(PackageNamespace(""),"setName") 1
    pushstring "127.0.0.1"
    callproperty Qname(PackageNamespace(""),"setAddress") 1
    getlex Qname(PackageNamespace("com.company.assembleegameclient.parameters"),"Parameters")
    getproperty Qname(PackageNamespace(""),"PORT")
    callproperty Qname(PackageNamespace(""),"setPort") 1
    findpropstrict Qname(PackageNamespace(""),"Number")
    pushint 50000
    callproperty Qname(PackageNamespace(""),"Number") 1
    findpropstrict Qname(PackageNamespace(""),"Number")
    pushint 50000
    callproperty Qname(PackageNamespace(""),"Number") 1
    callproperty Qname(PackageNamespace(""),"setLatLong") 2
    pushint 0
    callproperty Qname(PackageNamespace(""),"setUsage") 1
    pushfalse
    callproperty Qname(PackageNamespace(""),"setIsAdminOnly") 1
    returnvalue
    The function in the second window should now resemble like this:
    [​IMG]
    The last thing we need to do to is make the client call the function. To do this we are going to edit the "makeListOfServers" function in the same file we are already in. So click on the makeListOfServers function so the byte code for the function is in the 3rd panel. Now, as i said before, our function we just made is essentially a copy of the "makeServer" function. You can see that function is being called inside the makeListOfServers function. We want to mimic how that function is being called but at the very end of the function. Hit the "Edit" button to start editing the byte code. Scroll all the way down to the bottom of the code and look for the two lines that start with "kill". Those lines are the end of a for loop. So right after the second "kill" line add this code and hit save:
    Code:
    getlocal_2
    getlocal_0
    callproperty Qname(PackageNamespace(""),"LocalhostServer") 0
    callpropvoid Qname(Namespace("http://adobe.com/AS3/2006/builtin"),"push") 1
    After you hit save the code in the 2nd panel should update, and you should see this new line in the makeListOfServers function:
    [​IMG]

    Now all you need to do is save the swf file and try it out! Hit the "Save" button at the very top of JPEXS to save the changes you just made. Go open the swf you just saved using your flash projector and view the servers screen. At the very bottom of the list you should now see the proxy server you just added!


    Fullscreen
    This is the last hack i will be showing you how to do today. From my understanding, this would be called "Fullscreen version 2". Orape uses v2, but Nilly's uses v3. If you like v3 you can always decompile nilly's and see how its done in there, but v2 is pretty quick and simple to set up so i usually settle for it instead.
    Okay this hack is going to involve editing a few different files. The list of files i will be changing are:
    WebMain
    com.company.assembleegameclient.engine3d.Face3D
    com.company.assembleegameclient.map.Camera
    com.company.assembleegameclient.map.Map
    com.company.assembleegameclient.background.NexusBa ckground
    com.company.assembleegameclient.game.GameSprite
    Because this hack takes a bit more work then the previous two, im not going to be going into as much detail. I will share the code and how to find where to place it, but that is all.
    WebMain: this prevents the window from stretching everything
    Inside the "setup" function, locate the line that has "EXACT_FIT" in it. It needs to be changed to "NO_SCALE" like this:
    Code:
    getproperty Qname(PackageNamespace(""),"NO_SCALE")
    com.company.assembleegameclient.engine3d.Face3D: this removes the black that prevents you from seeing beyond your normal view
    Inside the "draw" function, locate the boolean var that is set to true, it is line line 141 in the second panel or line 122 in the functions byte code (for 27.7.XMAS client). You can also find it by locating the first "pushtrue" line after all the "getproperty Qname(PackageNamespace(""),"clipRect_")" lines. All you need to do is change it from true to false, so find the "pushtrue" and simple change it to:
    Code:
    pushfalse
    com.company.assembleegameclient.map.Camera: this part give you a greater view distance
    Inside the "configure" function, go to the very bottom of the code. Find the first occurrence of "pushbyte 1" starting from the bottom and going up. It should be right below a line that has "sqrt" in it. (in 27.7.XMAS the line is 273 in the functions byte code). We want to change this from 1 to 16. So edit the line to read:
    Code:
    pushbyte 16
    com.company.assembleegameclient.map.Map: we need to remove the gradient line that is below the hud, otherwise it will be in the wrong place when you go fullscreen. I like to just remove it, some people choose to move it though.
    Inside the "draw" function. Find the block of code that looks like this:
    Code:
    getlex Qname(PackageNamespace(""),"gradientOverlay_")
    pushtrue
    setproperty Qname(PackageNamespace(""),"visible")
    getlex Qname(PackageNamespace(""),"gradientOverlay_")
    All you need to do is change the "pushtrue" to "pushfalse". That same block of code should look like this when you change it:
    Code:
    getlex Qname(PackageNamespace(""),"gradientOverlay_")
    pushfalse
    setproperty Qname(PackageNamespace(""),"visible")
    getlex Qname(PackageNamespace(""),"gradientOverlay_")
    com.company.assembleegameclient.background.NexusBa ckground: ill be honest, not too sure this part does anything anymore, but it doesnt hurt to add
    Inside the "draw" function, right after the "pushscope" at the start add:
    Code:
    returnvoid
    com.company.assembleegameclient.game.GameSprite: this is the hardest part. Positioning the hud and everything
    First you need to click on the line that says "private var currentPackage:DisplayObject;" in the second panel. Then in the 3rd panel (the byte code) make note of the value that should be like 273 or something. For example, the current client byte code starts like this when you click on that line: "trait Qname(PrivateNamespace(null,"273"),"currentPackage ")"
    Now, you need to add a new function called "onScreenResize". its a public function, not static. Once you add it, go replace the byte code with this:
    Code:
    trait method Qname(PackageNamespace("","1"),"onScreenResize") dispid 0
    method
    name null
    param Qname(PackageNamespace("flash.events"),"Event")
    returns Qname(PackageNamespace("","1"),"void")

    body
    maxstack 5
    localcount 14
    initscopedepth 9
    maxscopedepth 10

    code
    getlocal_0
    pushscope
    getlocal_0
    getproperty Qname(PackageNamespace(""),"chatBox_")
    dup
    pushshort 400
    getlex Qname(PackageNamespace(""),"stage")
    getproperty Qname(PackageNamespace(""),"stageWidth")
    convert_d
    pushbyte 2
    convert_d
    divide
    subtract
    setproperty Qname(PackageNamespace(""),"x")
    getlex Qname(PackageNamespace(""),"stage")
    getproperty Qname(PackageNamespace(""),"stageHeight")
    convert_d
    pushbyte 2
    convert_d
    divide
    pushshort 0
    subtract
    setproperty Qname(PackageNamespace(""),"y")
    getlocal_0
    getproperty Qname(PackageNamespace(""),"hudView")
    pushnull
    ifeq ofs004c
    getlocal_0
    getproperty Qname(PackageNamespace(""),"hudView")
    pushshort 200
    getlex Qname(PackageNamespace(""),"stage")
    getproperty Qname(PackageNamespace(""),"stageWidth")
    convert_d
    pushbyte 2
    convert_d
    divide
    add
    setproperty Qname(PackageNamespace(""),"x")
    ofs004c:getlocal_0
    getproperty Qname(PackageNamespace(""),"creditDisplay_")
    pushnull
    ifeq ofs0083
    getlocal_0
    getproperty Qname(PackageNamespace(""),"creditDisplay_")
    pushshort 194
    getlex Qname(PackageNamespace(""),"stage")
    getproperty Qname(PackageNamespace(""),"stageWidth")
    convert_d
    pushbyte 2
    convert_d
    divide
    add
    setproperty Qname(PackageNamespace(""),"x")
    getlocal_0
    getproperty Qname(PackageNamespace(""),"creditDisplay_")
    pushshort 300
    getlex Qname(PackageNamespace(""),"stage")
    getproperty Qname(PackageNamespace(""),"stageHeight")
    convert_d
    pushbyte 2
    convert_d
    divide
    subtract
    setproperty Qname(PackageNamespace(""),"y")
    ofs0083:getlocal_0
    getproperty Qname(PackageNamespace(""),"rankText_")
    pushnull
    ifeq ofs00fb
    getlocal_0
    getproperty Qname(PackageNamespace(""),"rankText_")
    pushshort 408
    getlex Qname(PackageNamespace(""),"stage")
    getproperty Qname(PackageNamespace(""),"stageWidth")
    convert_d
    pushbyte 2
    convert_d
    divide
    subtract
    setproperty Qname(PackageNamespace(""),"x")
    getlocal_0
    getproperty Qname(PackageNamespace(""),"rankText_")
    pushshort 304
    getlex Qname(PackageNamespace(""),"stage")
    getproperty Qname(PackageNamespace(""),"stageHeight")
    convert_d
    pushbyte 2
    convert_d
    divide
    subtract
    setproperty Qname(PackageNamespace(""),"y")
    getlocal_0
    getproperty Qname(PackageNamespace(""),"giftStatusDisplay")
    getlocal_0
    getproperty Qname(PackageNamespace(""),"rankText_")
    getproperty Qname(PackageNamespace(""),"x")
    pushbyte 2
    subtract
    setproperty Qname(PackageNamespace(""),"x")
    getlocal_0
    getproperty Qname(PackageNamespace(""),"giftStatusDisplay")
    getlocal_0
    getproperty Qname(PackageNamespace(""),"rankText_")
    getproperty Qname(PackageNamespace(""),"y")
    pushbyte 58
    add
    setproperty Qname(PackageNamespace(""),"y")
    getlocal_0
    getproperty Qname(PrivateNamespace(null,"273"),"currentPackage")
    getlocal_0
    getproperty Qname(PackageNamespace(""),"giftStatusDisplay")
    getproperty Qname(PackageNamespace(""),"x")
    setproperty Qname(PackageNamespace(""),"x")
    getlocal_0
    getproperty Qname(PrivateNamespace(null,"273"),"currentPackage")
    getlocal_0
    getproperty Qname(PackageNamespace(""),"rankText_")
    getproperty Qname(PackageNamespace(""),"y")
    pushbyte 30
    add
    setproperty Qname(PackageNamespace(""),"y")
    ofs00fb:getlocal_0
    getproperty Qname(PackageNamespace(""),"guildText_")
    pushnull
    ifeq ofs0132
    getlocal_0
    getproperty Qname(PackageNamespace(""),"guildText_")
    pushshort 464
    getlex Qname(PackageNamespace(""),"stage")
    getproperty Qname(PackageNamespace(""),"stageWidth")
    convert_d
    pushbyte 2
    convert_d
    divide
    subtract
    setproperty Qname(PackageNamespace(""),"x")
    getlocal_0
    getproperty Qname(PackageNamespace(""),"guildText_")
    pushshort 306
    getlex Qname(PackageNamespace(""),"stage")
    getproperty Qname(PackageNamespace(""),"stageHeight")
    convert_d
    pushbyte 2
    convert_d
    divide
    subtract
    setproperty Qname(PackageNamespace(""),"y")
    ofs0132:returnvoid
    If you notice, there are 2 lines in there that you need to make sure the value we found right before this are matching. Look for the 2 lines that have "currentPackage" on them and make sure the value just before that (in this code its 273) matches what we found earlier.
    Now we need to call this function anytime the screen changes size.
    Look for the "connect" function. You need to add this code:
    Code:
    getlex Qname(PackageNamespace("","4"),"stage")
    getlex Qname(PackageNamespace("flash.events"),"Event")
    getproperty Qname(PackageNamespace("","5"),"RESIZE")
    getlocal_0
    getproperty Qname(PackageNamespace("","3"),"onScreenResize")
    callpropvoid Qname(PackageNamespace("","3"),"addEventListener") 2
    getlex Qname(PackageNamespace("","3"),"stage")
    findpropstrict Qname(PackageNamespace("flash.events"),"Event")
    getlex Qname(PackageNamespace("flash.events"),"Event")
    getproperty Qname(PackageNamespace("","3"),"RESIZE")
    constructprop Qname(PackageNamespace("flash.events"),"Event") 1
    callpropvoid Qname(PackageNamespace("","3"),"dispatchEvent") 1
    Right here (should be line 40 in the functions byte code):
    Code:
    getproperty Qname(PrivateNamespace(null,"273"),"onMoneyChanged")
    callpropvoid Qname(PackageNamespace(""),"addEventListener") 2
    [***THIS IS WHERE YOU ADD THE CODE***]
    getlex Qname(PackageNamespace(""),"stage")
    getlex Qname(PackageNamespace("flash.events"),"Event")
    getproperty Qname(PackageNamespace(""),"ENTER_FRAME")
    The code you just added creates a listener that triggers anytime the window is resized. Now we need to remove that listener too.
    Look for the function "disconnect" (should be right below the "connect" function).
    Just like before, you are going to add this code:
    Code:
    getlex Qname(PackageNamespace("","3"),"stage")
    getlex Qname(PackageNamespace("flash.events"),"Event")
    getproperty Qname(PackageNamespace("","3"),"RESIZE")
    getlocal_0
    getproperty Qname(PackageNamespace("","3"),"onScreenResize")
    callpropvoid Qname(PackageNamespace("","3"),"removeEventListener") 2
    getlex Qname(PackageNamespace("","3"),"stage")
    findpropstrict Qname(PackageNamespace("flash.events"),"Event")
    getlex Qname(PackageNamespace("flash.events"),"Event")
    getproperty Qname(PackageNamespace("","3"),"RESIZE")
    constructprop Qname(PackageNamespace("flash.events"),"Event") 1
    callpropvoid Qname(PackageNamespace("","3"),"dispatchEvent") 1
    Right here (should be line 33 in the functions byte code):
    Code:
    getproperty Qname(PrivateNamespace(null,"273"),"onMoneyChanged")
    callpropvoid Qname(PackageNamespace(""),"removeEventListener") 2
    [***THIS IS WHERE YOU ADD THE CODE***]
    getlex Qname(PackageNamespace(""),"stage")
    getlex Qname(PackageNamespace("flash.events"),"Event")
    getproperty Qname(PackageNamespace(""),"ENTER_FRAME")
    Okay last thing we need to do is we want to manually trigger the resize event anytime the screen is reset, otherwise the display will be wrong anytime you enter a portal. You would have to resize the screen to get the display in the right place all the time.
    Go find the function "initialize" (around line 218 in the actionscript panel).
    Scroll to the very bottom of the byte code and add this right above the very last line, which should be "returnvoid":
    Code:
    getlex Qname(PackageNamespace("","3"),"stage")
    findpropstrict Qname(PackageNamespace("flash.events"),"Event")
    getlex Qname(PackageNamespace("flash.events"),"Event")
    getproperty Qname(PackageNamespace("","4"),"RESIZE")
    constructprop Qname(PackageNamespace("flash.events"),"Event") 1
    callpropvoid Qname(PackageNamespace("","3"),"dispatchEvent") 1
    Now you are done! Save the swf file and give it a try! (the loading screen/title screen/account screen dont resize though, so being in fullscreen may cause some of the elements on these screens to be hidden). When you are in game you can now play with fullscreen and see a lot more then on the tiny little 800x600!

    One last thing that i like to add to my fullscreen code, this part is optional though: normally when you are in fullscreen, if you hit "O" to open the options menu, you will notice that the "Continue" and "Go back Home" links are in the wrong place! Infact you cant even see the "home" button! So i like to fix this, that way i dont have to shrink my window just to open the options menu.
    com.company.assembleegameclient.ui.options.Options: fix the location of the continue/home links in the option menu
    This fix is pretty simple as well. Find the "onAddedToStage" function.
    First, locate this block of code (it should be almost at the very top. Line 17-22 of the functions byte code):
    Code:
    getproperty Qname(PrivateNamespace(null,"286"),"continueButton_")
    getlex Qname(PackageNamespace(""),"stage")
    getproperty Qname(PackageNamespace(""),"stageWidth")
    pushbyte 2
    divide
    setproperty Qname(PackageNamespace(""),"x")
    It needs to be changes to read:
    Code:
    getproperty Qname(PrivateNamespace(null,"286"),"continueButton_")
    pushshort 400
    setproperty Qname(PackageNamespace(""),"x")
    Now we need to fix the Home button. Locate this block of code (should be like lines 33-38 of the functions byte code):
    Code:
    getproperty Qname(PrivateNamespace(null,"286"),"homeButton_")
    getlex Qname(PackageNamespace(""),"stage")
    getproperty Qname(PackageNamespace(""),"stageWidth")
    pushbyte 20
    subtract
    setproperty Qname(PackageNamespace(""),"x")
    Change that to read:
    Code:
    getproperty Qname(PrivateNamespace(null,"286"),"homeButton_")
    pushshort 780
    setproperty Qname(PackageNamespace(""),"x")
    And thats it! All there is too it!


    Hopefully this was easy enough to follow along for anyone. I tried to keep this simple but also didnt want to waste a ton of time on it. The first 2 hacks i went over are extremely basic though so i think anyone can follow those. The fullscreen is a bit more work and i tried to make it easy to find where you need to edit though.

    A good tip for anyone looking to get into making their own hacks: Download the client with the hacks you like and open it using JPEXS. Then you can go look at the code and see how they did things! It can help a lot with finding where things need to be changed and whatnot.


    Good luck everyone, if you have any questions related to this post feel free to ask! Ill do my best to answer them
     
    • This user is inactive. Hasn't logged into their account in over 60 days.
Thread Status:
Not open for further replies.