Thread: Adding staves - communicating to the client you have infinite runes

Results 1 to 5 of 5
  1. #1 Adding staves - communicating to the client you have infinite runes 
    Registered Member
    Join Date
    Mar 2016
    Posts
    4
    Thanks given
    0
    Thanks received
    0
    Rep Power
    0
    So I'm messing around with an old 317 partially renamed server, and trying to add the different combination rune staves to the game. They "work" as intended, but don't tell the client that the player has infinite runes, so the spell buttons don't light up and it doesn't display that you have "*/3" or whatever runes to cast. I've been looking for a long time trying to figure this out, and I know where in the client class its triggering each sprite, around line 8550 if you're using a similar client:

    Code:
    } else if(class9_1.type == 5) {
    					Sprite sprite;
    					if(interfaceIsSelected(class9_1))
                            sprite = class9_1.sprite2;
                        else
                            sprite = class9_1.sprite1;
    					if(spellSelected == 1 && class9_1.id == spellID && spellID != 0 && sprite != null) { 
    						sprite.drawSprite(k2, l2, 0xffffff);
    					} else {
    						if (sprite != null)
    							sprite.drawSprite(k2, l2);
    					}
    I just can't seem to figure out where in the world its communicating if you have an elemental staff equipped or not. I know this might be a long shot because nobody really does this kind of thing anymore, but if any of you have any ideas or know anything I would appreciate it! Thanks a lot
    Reply With Quote  
     

  2. #2  
    Registered Member
    TheChosenOne's Avatar
    Join Date
    Jan 2013
    Posts
    974
    Thanks given
    47
    Thanks received
    161
    Rep Power
    366
    You are correct. That place is indeed where it is triggered.
    However, it is just the last step of something more complex. What you call "interfaceIsSelected" is a misleading name.
    Take a look at what I've made of it:
    Code:
    } else if(gameInterface.interfaceType == 5){ //Sprite
        Sprite sprite;
        if(allScriptConditionsMet(gameInterface))
            sprite = gameInterface.sprite2;
        else
            sprite = gameInterface.sprite1;
        if(spellSelected == 1 && gameInterface.id == spellID && spellID != 0 && sprite != null){
            sprite.drawSprite(leftX, topY, 0xffffff);
        } else {
            if(sprite != null)
                sprite.drawSprite(leftX, topY);
        }
        if(Autocast && gameInterface.id == spellID && gameInterface.id == autocastId){
            magicAuto.drawSprite(leftX - 3, topY - 3);
        }
    }
    I call your method "allScriptConditionsMet".
    In the 317 revisions, a sort of script could be embedded in the interfaces.
    These scripts could do all sorts of things.
    Chosing between sprites is one thing.
    Setting text in a certain colour is another.
    This is what my allScriptConditionsMet method looks like
    Code:
    private boolean allScriptConditionsMet(GameInterface gameInterface){
        if(gameInterface.scriptCondition == null)
            return false;
        for(int scriptIndex = 0; scriptIndex < gameInterface.scriptCondition.length; scriptIndex++){
            int value = extractInterfaceValues(gameInterface, scriptIndex);
            int comparisonValue = gameInterface.scriptConditionComparisonValue[scriptIndex];
            if(gameInterface.scriptCondition[scriptIndex] == 2){
                if(value >= comparisonValue)
                    return false;
            } else if(gameInterface.scriptCondition[scriptIndex] == 3){
                if(value <= comparisonValue)
                    return false;
            } else if(gameInterface.scriptCondition[scriptIndex] == 4){
                if(value == comparisonValue)
                    return false;
            } else if(value != comparisonValue)
                return false;
        }
        return true;
    }
    As you might be able to see, an interface is able to extract/calculate some values and use those values.
    Let's have a look at "extractInterfaceValues" to see what can be extracted and how this could explain your question.
    Code:
    private int extractInterfaceValues(GameInterface gameInterface, int scriptIndex){
        if(gameInterface.extractScripts == null || scriptIndex >= gameInterface.extractScripts.length)
            return -2;
        try{
            int instructions[] = gameInterface.extractScripts[scriptIndex];
            int finalValue = 0;
            int index = 0;
            int operation = 0;
            do{
                int opCode = instructions[index++];
                int tempValue = 0;
                byte doOperation = 0;
                if(opCode == 0)
                    return finalValue;
                if(opCode == 1)//Current skill level
                    tempValue = MyPlayer.skillLevel[instructions[index++]];
                else if(opCode == 2)//Max skill level
                    tempValue = MyPlayer.skillMaxLevel[instructions[index++]];
                else if(opCode == 3)//Current skill exp
                    tempValue = MyPlayer.skillExp[instructions[index++]];
                else if(opCode == 4){//Number of a certain item in an itemContainer
                    GameInterface containerInterface = GameInterface.interfaceCache[instructions[index++]];
                    int itemId = instructions[index++];
                    if(itemId >= 0 && itemId < ItemDefinition.totalItems && (isMembers || !ItemDefinition.forID(itemId).membersObject))
                        for(int containerIndex = 0; containerIndex < containerInterface.containerItemIds.length; containerIndex++)
                            if(containerInterface.containerItemIds[containerIndex] == itemId + 1)
                                tempValue += containerInterface.containerStackSizes[containerIndex];
                } else if(opCode == 5)//Setting value TODO
                    tempValue = ClientSettings.sessionSettings[instructions[index++]];
                else if(opCode == 6)//Levelup exp for a skill
                    tempValue = MyPlayer.levelUpExp[MyPlayer.skillMaxLevel[instructions[index++]] - 1];
                else if(opCode == 7)//TODO
                    tempValue = (ClientSettings.sessionSettings[instructions[index++]] * 100) / 46875;
                else if(opCode == 8)//Combat level
                    tempValue = myPlayer.combatLevel;
                else if(opCode == 9){//Total level
                    for(int skillId = 0; skillId < Skills.skillsCount; skillId++)
                        if(Skills.skillEnabled[skillId])
                            tempValue += MyPlayer.skillMaxLevel[skillId];
                } else if(opCode == 10){//if container contains item, tempValue is 999.999.999 (like in, wield staff)
                    GameInterface containerInterface = GameInterface.interfaceCache[instructions[index++]];
                    int itemId = instructions[index++] + 1;
                    if(itemId >= 0 && itemId < ItemDefinition.totalItems && (!ItemDefinition.forID(itemId).membersObject || isMembers)){
                        for(int containerIndex = 0; containerIndex < containerInterface.containerItemIds.length; containerIndex++){
                            if(containerInterface.containerItemIds[containerIndex] != itemId)
                                continue;
                            tempValue = 999999999;
                            break;
                        }
                    }
                } else if(opCode == 11)//Run energy
                    tempValue = MyPlayer.playerRunEnergy;
                else if(opCode == 12)//Weight
                    tempValue = MyPlayer.weight;
                else if(opCode == 13){
                    int settingValue = ClientSettings.sessionSettings[instructions[index++]];
                    int i3 = instructions[index++];      //TODO below: shifting, orly?
                    tempValue = (settingValue & 1 << i3) == 0 ? 0 : 1;
                } else if(opCode == 14){//TODO
                    int varbitId = instructions[index++];
                    tempValue = VarBit.getSettingValue(varbitId);
                } else if(opCode == 15)//Negation
                    doOperation = 1;
                else if(opCode == 16)//Division
                    doOperation = 2;
                else if(opCode == 17)//Multiplication
                    doOperation = 3;
                else if(opCode == 18)//Player XLoc
                    tempValue = (myPlayer.xPosition >> 7) + baseX;
                else if(opCode == 19)//Player YLoc
                    tempValue = (myPlayer.yPosition >> 7) + baseY;
                else if(opCode == 20)//Fixed instruction value
                    tempValue = instructions[index++];
                if(doOperation == 0){
                    if(operation == 0)
                        finalValue += tempValue;
                    else if(operation == 1)
                        finalValue -= tempValue;
                    else if(operation == 2 && tempValue != 0)
                        finalValue /= tempValue;
                    else if(operation == 3)
                        finalValue *= tempValue;
                    operation = 0;
                } else {
                    operation = doOperation;
                }
            } while(true);
        } catch(Exception _ex){
            return -1;
        }
    }
    If you look at opcode 10 you'll see something interesting: you're able to check (and return a large value) if you wield a certain item.
    In combination with this method you'll start to see the picture come even more together (the * part).
    Code:
    public final String replaceAmountPostFix(int amount){
        if(amount >= 0 && amount < 10000)
            return String.valueOf(amount);
        if(amount >= 10000 && amount < 10000000)
            return amount / 1000 + "K";
        if(amount >= 10000000 && amount < 999999999)
            return amount / 1000000 + "M";
        if(amount >= 999999999)
            return "*";
        else
            return "?";
    }
    Did I mention these values can be inserted in predetermined places of an interface? Hence the client knowing howmany runes you have.
    So to add more staves, you'd have to edit the scripts of these interfaces.

    TLDR; this functionality is part of a script that's attached to an interface.
    My informative threads:
    [Only registered and activated users can see links. ]
    [Only registered and activated users can see links. ]
    Reply With Quote  
     

  3. #3  
    Registered Member
    Join Date
    Mar 2016
    Posts
    4
    Thanks given
    0
    Thanks received
    0
    Rep Power
    0
    Awesome, that was super informative. I really appreciate you taking the time to share that info with me, I'm pretty new to getting into like actual client modification so again that was really helpful. Kind of annoying that you have to script it in, meaning that the client cache must read item info and pick between magicon and magicoff sprites outside of any deobfuscated code we can easily edit. I might have to take a crack at seeing if I can do this just as a pet project. Thanks again!
    Reply With Quote  
     

  4. #4  
    Registered Member

    Join Date
    Dec 2009
    Posts
    757
    Thanks given
    336
    Thanks received
    414
    Discord
    View profile
    Rep Power
    834
    Easy. CS1 of the spell component in the spell book interface. The instructions of the component contains the spell and staff combinations. Just add your own custom spells and staffs in there.
    link removed
    Reply With Quote  
     

  5. #5  
    Community Veteran

    mige5's Avatar
    Join Date
    Aug 2008
    Posts
    5,322
    Thanks given
    546
    Thanks received
    1,129
    Discord
    View profile
    Rep Power
    1806
    Easy to do if u have interface editor that supports adding them. (though some might allow editing them, but having to type all the new values manually.)
    ...
    Reply With Quote  
     


Thread Information
Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)


User Tag List

Similar Threads

  1. Adding a JFrame to the Elvarg Base Client
    By RainDropzZ in forum Help
    Replies: 1
    Last Post: 11-27-2018, 12:31 PM
  2. Replies: 158
    Last Post: 02-19-2012, 02:19 PM
  3. Replies: 77
    Last Post: 12-23-2011, 06:40 PM
  4. Replies: 5
    Last Post: 04-14-2011, 10:54 AM
  5. Adding New Items to your Client [My Way]
    By Exist2inspire in forum Tutorials
    Replies: 12
    Last Post: 10-16-2007, 10:10 PM
Posting Permissions
  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •