Jump to content

Does anyone here have L2net JingJing scripting knowledge?


Deviouz1
 Share

Recommended Posts

Pretty self explanatory, but i can't bear to leave the body empty, so, a little backstory.

I've been playing this shit since the beginning. before the beginning actually. closed beta march 2004 IIRC. i didnt get into botting until much later. had a thing against botters actually. then i grew up. went to college, got a job and, well, the rest is history. I got hooked on L2net and used it for a long time. but its been foreeeeeever since then and i cant quite figure out how to do the things i want to do anymore. it used to be i would go to the forums at insane gamers and d00d, mpj123, and... hell i dont even remember the other names anymore, were always willing to explain things.

but now i cant find anyone who knows it. Looking in some sample scripts helps to some degree, but without having anyone to clarify anything, i'm struggling pretty bad. it's like trying to remember russian, when i wasnt very good at it in the first place, by using a list of russian words and a couple of russian newspaper articles.

here are the JingJing commands and such. no descriptions, no definitions, nothing. just the commands:

https://github.com/Xackery/l2net/wiki/L2net-Jingjing-Table-of-Contents

And i cant seem to make heads or tails of a lot of it.

Anyone know this apparently dead language?

  • Like 1
Link to comment
Share on other sites

  • Toggle Staff
56 minutes ago, Deviouz1 said:

Pretty self explanatory, but i can't bear to leave the body empty, so, a little backstory.

I've been playing this shit since the beginning. before the beginning actually. closed beta march 2004 IIRC. i didnt get into botting until much later. had a thing against botters actually. then i grew up. went to college, got a job and, well, the rest is history. I got hooked on L2net and used it for a long time. but its been foreeeeeever since then and i cant quite figure out how to do the things i want to do anymore. it used to be i would go to the forums at insane gamers and d00d, mpj123, and... hell i dont even remember the other names anymore, were always willing to explain things.

but now i cant find anyone who knows it. Looking in some sample scripts helps to some degree, but without having anyone to clarify anything, i'm struggling pretty bad. it's like trying to remember russian, when i wasnt very good at it in the first place, by using a list of russian words and a couple of russian newspaper articles.

here are the JingJing commands and such. no descriptions, no definitions, nothing. just the commands:

https://github.com/Xackery/l2net/wiki/L2net-Jingjing-Table-of-Contents

And i cant seem to make heads or tails of a lot of it.

Anyone know this apparently dead language?

Hey!

Glad to see another insane gamer around! Shame that the forum went away.

I came back to L2Net few years ago and I definitely feel your pain. I ended up reading shared scripts and later on dug into the source of L2Net. There you can check what those methods actually do. I built a few extensive scripts, mostly processing and building packets myself. But in the end, it was easier for me to just code a feature into the bot instead of trying to deal with low level scripting language.

What question do you have, maybe I'll be able to help you.

  • Thanks 1
Link to comment
Share on other sites

oh a ton, mostly pretty basic stuff I'm sure. especially at first. honestly, if i can get a hunting script and that egg delivery quest script I can probably take the stuff in there and Frankenstein something that would be serviceable if not shareworthy. In essence, i want to create a few different script templates to use in a number of scenarios. one for a TH to go gather all the treasure chests he can find, lots... and lots of pathing. That, i know how to do, how to interact with the NPCs? i remember using the debugger, and i have the bypass lines saved, but i cant for the life of me remember how to send that to the NPC. 

another one for duos, ideally just a "get buffs, go to a spot, hunt it until you die, tap to town, get buffs go to a spot, hunt till you die, etc.." nothing overly fancy, not looking to drop off anything in a warehouse or make any trades or anything. just buff-kill-die, buff-kill-die, buff-kill-die, ad nauseum.

and one for full parties. I simply cannot get what I'm looking for with just the bot options it seems.


One of the issues I'm having is that I'm no developer, or coder really. More of a scripter. I'm a fair hand with PowerShell, but that's about the only language I can claim to know at all.

also, dear god will someone please help me understand how to make them login again automatically when disconnected.

On another note, I work ... well, lets just say i'm a SCOM Admin of sorts. thats the System Center Operations Manager if youre unfamiliar. It's used to monitor server environments and allows you to write management packs that are used to alert when a bad thing happens on your custom application. system center also has two other products, Orchestrator, or SCORCH, and Config Manager, or SCCM.

Using these things, i feel like i could effectively take the logistics nightmare out of running 50+ accounts at once. Basically, bot the bot. lol

but i need a starting place.

  1. the ability to log in and select a character
  2. a framework for starting the app with the appropriate switches for the appropriate party members and their roles
    1. This is already mostly complete. i run a script, and 9 l2nets pop up prepopulated with the appropriate bot options
  3. looping hunting scripts that include pathing, buffs, resurrection, etc
  4. a way to make l2net fire events into the... probably application event log. would make creating rule based monitors in scom easy.

i want to try to run like 200 accounts at once, without having to constantly tinker and fiddle. with what system center can do, if i can get the above things worked out, i can do this. eventually. will be a bitch to get it going, but once its rolling...

 

...

 

now consider the siege ramifications O.o

also, the hardware. I have two of these in my closet on CAT6, with SSDs, and a gigabit connection:

image.thumb.png.906bb242a4f4a23185cba1289e0f9943.png

 

Link to comment
Share on other sites

  • 2 weeks later...

Hello Mantosh, anyone else,

I feel like i may have come across wrong. I am literally not asking anyone to provide me a script that does everything i want. which is what i think i came off as. what i am looking for is some back and forth regarding whatever im working on. please bear in mind i have very limited scripting experience, and even that is only in powershell. I have added some comments to the below script. It was found on max cheaters and looks like it could very likely be modified to do what i am looking for. All of the original writers comments are intact, anything that starts with '//--' is from me.


I've already made some changes that i think are putting me on the right track, mainly adding the Npc.l2c reference, and the objects one which i plan on using later, and then modifying everything in the ifs from Player* to Npc*. the Char_ vs Npc_ is a question, i have no idea how to know whether the info in the player has the same properties as the info in the npc. sorry for the terminology here, im sure im saying it wrong, but i hope you get my meaning. the comments i added are just comments to myself about what needs to be done to accomplish what i want to do, as well as places where im not sure about something or whatever. Also, i added the appropriate values for a dagger class. just something i modified, doesnt really matter much. more to show that i went through everything and did what i could before addressing things that would have to be addressed before event testing it really.

One obvious thing to point out, i know the PVPFLAG references are NOT going to be available for an npc, at least, i wouldnt expect it to, and that that is something that i will need to change, just no idea what to change it to atm and figure i'll learn that going forward. i understand that is something to change, can you show me how to figure out what to change it to? lol

Anyway, any assistance would be greatly appreciated and i will be happy to clarify my questions or anything if that would help.

 

/* This Scipt was created with JingJing IDE. 
* Author: Phear3d
* @ 2012.March.09 at 05:40 PM 
* -- Reworked by deviouz1 11/10/20
*/
INCLUDE StdLib\Player.l2c
INCLUDE StdLib\Object.l2c
INCLUDE StdLib\Npc.l2c
INCLUDE StdLib\inventory.l2c
INCLUDE \char_buffs.l2c
DEFINE_GLOBAL SORTEDLIST DoNotAttack 0

//Chars to not target and not attack (add as many as you like)
DoNotAttack.ADD 1 "MyFriend1"
DoNotAttack.ADD 1 "MYFriend2"

//Leave blank, "" , if not using toggle1 or toggle2
DEFINE_GLOBAL STRING Toggle1 "Vicious stance"
DEFINE_GLOBAL STRING Toggle2 ""

//Buff Type: 1=Warrior, 2=Tanker , 3=Mage
DEFINE_GLOBAL INT BuffType 1
//Rebuff if char has under # of buffs (toggles/self buffs are counted as buffs)
DEFINE_GLOBAL INT Buff_If_Under 20
//Skill and Attack Range
DEFINE_GLOBAL INT Range 600
//Click To Village Delay/Sleep(ms), 12000 ms = 12 seconds (increase delay if you get ported to nearest village)
DEFINE_GLOBAL INT To_Village_Delay 11000


//--**--**--**--**--**--**--**--**--**--**--**--**--**--**
//DO NOT CHANGE ANYTHING BELOW!!!!!!! - Phear3d
//-- I DO WHAT I WAWNT!!  ,,|,(>.<),|,, ~ Deviouz1
DEFINE_GLOBAL STRING Nearest_Npc ""
DEFINE_GLOBAL ARRAYLIST FlagList 0
DEFINE_GLOBAL SORTEDLIST MyBuffs 0
DEFINE_GLOBAL STRING NoName ""
DEFINE_GLOBAL INT NeedBuffs 0
DEFINE_GLOBAL INT Toggle_1 0
DEFINE_GLOBAL INT Toggle_2 0

SET_EVENT "<&SCRIPTEVENT_SERVERPACKET&>" "<&SYSTEM_CURRENTFILE&>" SystemMessage 98
SET_EVENT "<&SCRIPTEVENT_SERVERPACKET&>" "<&SYSTEM_CURRENTFILE&>" AbnormalStatusUpdate 133
//-- Add more events like chat events, treasure chest on radar(? but prolly not), if my target is affected by w/e, etc... stuff to react to.

PRINT_TEXT " Started <&SYSTEM_CURRENTFILE&> ] "

SKILL_GET_ID Toggle_1 "<&Toggle1&>"
SKILL_GET_ID Toggle_2 "<&Toggle2&>"
//-- add more toggles

THREAD CheckEQ
THREAD Get_Target
THREAD Check_Dead
THREAD Check_Buffs
//--  ^ is this the main order in which things happen? and then the while keeps these looping? Please clarify.

THREAD Spam_HP
THREAD Spam_MP
//THREAD Spam_CP

DEFINE ARRAYLIST NpcList 0
DEFINE INT dist 0

DO
  FlagList.CLEAR
  GET_NPCS NpcList
  SLEEP 500
  FOREACH P Npc NpcList
     IF ( NpcList.P.PVPFLAG == 1 ) && ( NpcList.P.LOOKS_DEAD == 0 )
          DISTANCE dist NpcList.P.X NpcList.P.Y NpcList.P.Z CHAR_X CHAR_Y CHAR_Z  
          
//--  need to verify the CHAR_* vs a possible NPC_*. It's likely, but unsure
          
          IF dist <= 9
               CALL ADD_LIST VOID 1 NpcList.P.NAME
          ENDIF
     ENDIF
  NEXTEACH
  FOREACH P Npc NpcList
     IF ( NpcList.P.PVPFLAG == 1 ) && ( NpcList.P.LOOKS_DEAD == 0 )
          DISTANCE dist NpcList.P.X NpcList.P.Y NpcList.P.Z CHAR_X CHAR_Y CHAR_Z
          IF ( dist > 9 ) && ( dist <= 99 )
               CALL ADD_LIST VOID 1 NpcList.P.NAME
          ENDIF
     ENDIF
  NEXTEACH
  FOREACH P Npc NpcList
     IF ( NpcList.P.PVPFLAG == 1 ) && ( NpcList.P.LOOKS_DEAD == 0 )
          DISTANCE dist NpcList.P.X NpcList.P.Y NpcList.P.Z CHAR_X CHAR_Y CHAR_Z
          IF ( dist > 99 ) && ( dist <= 499 )
               CALL ADD_LIST VOID 1 NpcList.P.NAME
          ENDIF
     ENDIF
  NEXTEACH
  FOREACH P PLAYER PlayerList
     IF ( PlayerList.P.PVPFLAG == 1 ) && ( PlayerList.P.LOOKS_DEAD == 0 )
          DISTANCE dist PlayerList.P.X PlayerList.P.Y PlayerList.P.Z CHAR_X CHAR_Y CHAR_Z
          IF ( dist > 499 ) && ( dist <= 999 )
               CALL ADD_LIST VOID 1 PlayerList.P.NAME
          ENDIF
     ENDIF
  NEXTEACH
  FOREACH P PLAYER PlayerList
     IF ( PlayerList.P.PVPFLAG == 1 ) && ( PlayerList.P.LOOKS_DEAD == 0 )
          DISTANCE dist PlayerList.P.X PlayerList.P.Y PlayerList.P.Z CHAR_X CHAR_Y CHAR_Z
          IF ( dist > 999 ) && ( dist <= 1499 )
               CALL ADD_LIST VOID 1 PlayerList.P.NAME
          ENDIF
     ENDIF
  NEXTEACH
  FOREACH P Npc NpcList
     IF ( NpcList.P.PVPFLAG == 1 ) && ( NpcList.P.LOOKS_DEAD == 0 )
          DISTANCE dist NpcList.P.X NpcList.P.Y NpcList.P.Z CHAR_X CHAR_Y CHAR_Z
          IF ( dist > 1499 ) && ( dist <= 1999 )
               CALL ADD_LIST VOID 1 NpcList.P.NAME
          ENDIF
     ENDIF
  NEXTEACH
  FOREACH P Npc NpcList
     IF ( NpcList.P.PVPFLAG == 1 ) && ( NpcList.P.LOOKS_DEAD == 0 )
          DISTANCE dist NpcList.P.X NpcList.P.Y NpcList.P.Z CHAR_X CHAR_Y CHAR_Z
          IF ( dist > 1999 ) && ( dist <= 2499 )
               CALL ADD_LIST VOID 1 NpcList.P.NAME
          ENDIF
     ENDIF
  NEXTEACH
  FOREACH P Npc NpcList
     IF ( NpcList.P.PVPFLAG == 1 ) && ( NpcList.P.LOOKS_DEAD == 0 )
          DISTANCE dist NpcList.P.X NpcList.P.Y NpcList.P.Z CHAR_X CHAR_Y CHAR_Z
          IF ( dist > 2499 ) && ( dist <= 2999 )
               CALL ADD_LIST VOID 1 NpcList.P.NAME
          ENDIF
     ENDIF
  NEXTEACH
  FOREACH P Npc NpcList
     IF ( NpcList.P.PVPFLAG == 1 ) && ( NpcList.P.LOOKS_DEAD == 0 )
          DISTANCE dist NpcList.P.X NpcList.P.Y NpcList.P.Z CHAR_X CHAR_Y CHAR_Z
          IF ( dist > 2999 ) && ( dist <= 3499 )
               CALL ADD_LIST VOID 1 NpcList.P.NAME
          ENDIF
     ENDIF
  NEXTEACH
  FOREACH P Npc NpcList
     IF ( NpcList.P.PVPFLAG == 1 ) && ( NpcList.P.LOOKS_DEAD == 0 )
          DISTANCE dist NpcList.P.X NpcList.P.Y NpcList.P.Z CHAR_X CHAR_Y CHAR_Z
          IF ( dist > 3499 ) && ( dist <= 3999 )
               CALL ADD_LIST VOID 1 NpcList.P.NAME
          ENDIF
     ENDIF
  NEXTEACH
  FOREACH P Npc NpcList
     IF ( NpcList.P.PVPFLAG == 1 ) && ( NpcList.P.LOOKS_DEAD == 0 )
          DISTANCE dist NpcList.P.X NpcList.P.Y NpcList.P.Z CHAR_X CHAR_Y CHAR_Z
          IF ( dist > 3999 ) && ( dist <= 4999 )
               CALL ADD_LIST VOID 1 NpcList.P.NAME
          ENDIF
     ENDIF
  NEXTEACH

SLEEP 2000
LOOP 1 == 1
END_SCRIPT



//---------------------------------------------------------------------------------------
FUNCTION Get_Target
DEFINE INT _dist 0
DEFINE INT F 0

DO
IF NeedBuffs != 1
F = 0
Nearest_Npc = ""
FOREACH F STRING FlagList
     IF F == 0
          Nearest_Npc = FlagList.F
     ENDIF
NEXTEACH

     IF ( TARGET_NAME == NULL ) || ( TARGET_NAME == "#$<&NoName&>" )
          IF ("DoNotAttack.CONTAINS_KEY <&Nearest_Npc&>" == FALSE)
               COMMAND "/target <&Nearest_Npc&>"
          ENDIF
     ELSE
          DISTANCE _dist TARGET_X TARGET_Y TARGET_Z CHAR_X CHAR_Y CHAR_Z
          IF ( TARGET_LOOKS_DEAD == 1 ) || ( TARGET_NAME == CHAR_NAME ) || ( _dist > Range )
               CANCEL_TARGET
          ENDIF
     ENDIF

SLEEP 1300
ENDIF
LOOP 1 == 1
RETURN VOID


//---------------------------------------------------------------------------------------
FUNCTION Check_Dead
DEFINE INT randSleep 0
DEFINE INT t_max 0
DEFINE INT t_min 0
t_min = To_Village_Delay - 1500
t_max = To_Village_Delay + 3500

DO
    IF CHAR_CUR_HP <= 0
     CALL To_Village
    ENDIF
SLEEP 1000
LOOP 1 == 1
RETURN VOID


//---------------------------------------------------------------------------------------
FUNCTION To_Village
LOCK TV
DEFINE INT randSleep 0
DEFINE INT t_max 0
DEFINE INT t_min 0
t_min = To_Village_Delay - 1500
t_max = To_Village_Delay + 3500


     CANCEL_TARGET
     GET_RAND randSleep "<&t_min&>" "<&t_max&>"
     SLEEP "<&randSleep&>"
     TAP_TO TOWN
     SLEEP 2500
     //toggle1
     IF Toggle_1 > 0
          USE_SKILL "<&Toggle_1&>"
     ENDIF
     SLEEP 1000
     //toggle2
     IF Toggle_2 > 0
          USE_SKILL "<&Toggle_2&>"
     ENDIF


SLEEP 1000
UNLOCK TV
RETURN VOID


//---------------------------------------------
FUNCTION ADD_LIST 1 _name
LOCK ADDL

IF ("DoNotAttack.CONTAINS_KEY <&_name&>" == FALSE)
     FlagList.ADD _name
     //PRINT_TEXT " Added FlagList List:  <&_name&> ]"
ELSE
     //PRINT_TEXT " Found _name on DoNotAttack List: <&_name&> ]"
ENDIF

UNLOCK ADDL
RETURN VOID


//---------------------------------------------------------------------------------------
FUNCTION SPAM_CP
DEFINE INT CPOT 1
ITEM_GET_ID CPOT "Greater CP Potion"
DO
    IF CHAR_CUR_CP < CHAR_MAX_CP
        USE_ITEM "<&CPOT&>"
    ENDIF
SLEEP 500
LOOP 1 == 1
RETURN VOID


//---------------------------------------------------------------------------------------
FUNCTION Spam_MP
DEFINE INT MPOT 1
DEFINE INT Half_MP
Half_MP = CHAR_MAX_MP / 2
ITEM_GET_ID MPOT "Mana Potion"

DO
    IF CHAR_CUR_MP < Half_MP
            USE_ITEM "<&MPOT&>"
            SLEEP 500
    ENDIF
SLEEP 500
LOOP 1 == 1
RETURN VOID


//---------------------------------------------------------------------------------------
FUNCTION Spam_HP
DEFINE INT HPOT 1
ITEM_GET_ID HPOT "Greater Healing Potion"
DO
    IF CHAR_CUR_HP < CHAR_MAX_HP
        USE_ITEM "<&HPOT&>"
        SLEEP 11000
    ENDIF
SLEEP 500
LOOP 1 == 1
RETURN VOID


//---------------------------------------------------------------------------------------
// Needs to be completely redone. Need to figure out how to access alt+b
//---------------------------------------------------------------------------------------
FUNCTION Check_Buffs

DO
IF NeedBuffs == 1
     COMMAND "/target Jack Sage"
     SLEEP 1000
     COMMAND "/target Jack Sage"
     SLEEP 1000
     IF BuffType == 1
          NPC_DIALOG "bypass -h npc_<&TARGET_ID&>_Buff 1501 1499 1504 1500 1502 1519 825 829 4699 1363 1461 1364 1416 1238 914 271 272 274 275 309 310 915 530 264 265 266 267 268 269 304 305 349 364 529 1035 1397 1259 1542 1062 1388 1191 1182 1189 1354 1392 1393 1352 1307 1044 1323"
     ENDIF
     IF BuffType == 2
          NPC_DIALOG "bypass -h npc_<&TARGET_ID&>_Buff 1501 1499 1504 1500 1502 1519 1503 825 828 4699 1363 1461 1364 1416 1238 914 271 272 274 275 309 310 530 264 266 267 268 269 265 304 305 349 364 529 1035 1397 1259 1542 1389 1191 1182 1189 1354 1392 1393 1352 1307 1044 1323"
     ENDIF
     IF BuffType == 3
          NPC_DIALOG "bypass -h npc_<&TARGET_ID&>_Buff 1501 1499 1504 1500 1503 830 4703 1363 1461 1364 1416 1238 914 273 276 309 365 915 530 264 266 267 268 265 304 305 349 529 1035 1078 1085 1397 1303 1259 1542 1062 1389 1191 1182 1189 1354 1392 1393 1352 1307 1044 1323"
     ENDIF
     SLEEP 2000
ENDIF
IF ( NeedBuffs == 0 ) && ( TARGET_NAME == "#$Jack Sage" )
     CANCEL_TARGET
     SLEEP 1000
ENDIF
SLEEP 2000
LOOP 1 == 1
RETURN VOID


//---------------------------------------------
FUNCTION AbnormalStatusUpdate
LOCK ASU
MyBuffs.CLEAR

  DEFINE INT PacketType 0
  DEFINE INT ListSize 0
  DEFINE INT SkillId 0
  DEFINE INT SkillLevel 0
  DEFINE INT Duration 0

  PACKET.READ_BYTE PacketType
  PACKET.READ_INT16 ListSize

  //PRINT_TEXT " Received AbnormalStatusUpdate packet: Size: <&ListSize&> ]"

  DEFINE char_buffs my_buff

  FOR MyBuffsEntryIDX 0 "<&ListSize&>" 1
     PACKET.READ_INT32 SkillId
     PACKET.READ_INT16 SkillLevel
     PACKET.READ_INT32 Duration
     Duration = ( ( Duration * TICKS_PER_S ) + NOW )

     my_buff.cha_id = CHAR_ID
     my_buff.sk_id = SkillId
     my_buff.sk_level = SkillLevel
     my_buff.sk_dur = Duration

     IF SkillId != 0
         IF ("MyBuffs.CONTAINS_KEY <&SkillId&>" == FALSE)
               MyBuffs.ADD my_buff.clone "<&SkillId&>"
          ENDIF
     ENDIF
  NEXT

  IF MyBuffs.COUNT < Buff_If_Under
     NeedBuffs = 1
  ELSE
     NeedBuffs = 0
  ENDIF

UNLOCK ASU
RETURN VOID


//---------------------------------------------------------------------------------------
//--  Should be reworked
FUNCTION SystemMessage

  DEFINE INT PacketType 0
  DEFINE INT MsgID 0
  DEFINE INT typesCount 0
  DEFINE INT Unk1 0
  DEFINE INT TypeID 0
  DEFINE STRING SName " "

  PACKET.READ_BYTE PacketType
  PACKET.READ_INT32 MsgID
  PACKET.READ_INT32 typesCount
  PACKET.READ_INT32 Unk1
  //PACKET.READ_STRING SName
  PACKET.READ_INT32 TypeID

     IF MsgID == 113
          IF TypeID == 1539
               CANCEL_TARGET
               PRINT_TEXT " MsgID=<&MsgID&> | TypeID: <&TypeID&> (cannot be used due to unsuitable terms.) ]"
               //PRINT_TEXT " MsgID=<&MsgID&> | TypeID: <&TypeID&> | Packet: <&PACKET.GET_HEX&> ]"
               SLEEP 1000
               CALL To_Village
          ENDIF
     ENDIF

     IF MsgID == 144
          PRINT_TEXT " MsgID=<&MsgID&> | Cancelling Target! (That is an incorrect target.) ]"
           FOREACH F STRING FlagList
               IF ( F == 0 ) && ( TARGET_NAME == FlagList.F )
                  FlagList.REMOVE F
                  SLEEP 500
                  CANCEL_TARGET
               ENDIF
           NEXTEACH
     ENDIF

     IF MsgID == 1996
          CANCEL_TARGET
          PRINT_TEXT " MsgID=<&MsgID&> | Cancelling Target! (The attack has been blocked) ]"
          SLEEP 1000
     ENDIF

     IF MsgID == 181
          CANCEL_TARGET
          PRINT_TEXT " MsgID=<&MsgID&> | Cancelling Target! (Cannot see target.)]"
          SLEEP 1000
     ENDIF

     IF MsgID == 748
          CANCEL_TARGET
          PRINT_TEXT " MsgID=<&MsgID&> | Cancelling Target! (The distance is too far and so the casting has been stopped.) ]"
          SLEEP 1000
     ENDIF

     IF MsgID == 2187
          CANCEL_TARGET
          PRINT_TEXT " MsgID=<&MsgID&> | Cancelling Target! (The target is located where you cannot charge.) ]"
          SLEEP 1000
     ENDIF

RETURN VOID


//---------------------------------------------------------------------------------------
FUNCTION CheckEQ
DEFINE STRING WEAPON ""
DEFINE STRING USE_ME ""
DEFINE STRING TEMP ""
DEFINE ARRAYLIST INV_LIST 0

GET_INVENTORY INV_LIST
SLEEP 1000
  FOREACH I Inventory INV_LIST
     IF ( ( INV_LIST.I.EQUIPPED == 1 ) ) && ( ( INV_LIST.I.SLOT == 16384 ) || ( INV_LIST.I.SLOT == 128 ) )
          WEAPON = INV_LIST.I.NAME
          PRINT_TEXT " Detected Weapon Being Used: <&WEAPON&> ]"
          TEMP = INV_LIST.I.ID.GET_HEX32
          USE_ME = "#$19 <&TEMP&> 00 00 00 00"
     ENDIF
  NEXTEACH

DO
GET_INVENTORY INV_LIST
SLEEP 500
  FOREACH I Inventory INV_LIST
    IF INV_LIST.I.NAME == "#$<&WEAPON&>"
        IF INV_LIST.I.EQUIPPED == #i0
          PRINT_TEXT " Equipping <&WEAPON&> ]"
          INJECT "<&USE_ME&>"
        ENDIF
    ENDIF
  NEXTEACH
SLEEP 1000
LOOP 1 == 1
RETURN VOID

 

  • Like 1
Link to comment
Share on other sites

  • Toggle Staff

Hey! Let's try to simplify things and work one thing at a time. I can't promise you much, but let's see what we can do
 

THREAD CheckEQ
THREAD Get_Target
THREAD Check_Dead
THREAD Check_Buffs
//--  ^ is this the main order in which things happen? and then the while keeps these looping? Please clarify.

Yes, these call functions into separate threads, so that they can run independently.

//---------------------------------------------------------------------------------------
FUNCTION CheckEQ

  <..>

DO
GET_INVENTORY INV_LIST
SLEEP 500
  FOREACH I Inventory INV_LIST
    IF INV_LIST.I.NAME == "#$<&WEAPON&>"
        IF INV_LIST.I.EQUIPPED == #i0
          PRINT_TEXT " Equipping <&WEAPON&> ]"
          INJECT "<&USE_ME&>"
        ENDIF
    ENDIF
  NEXTEACH
SLEEP 1000
LOOP 1 == 1
RETURN VOID

The DO - LOOP 1 == 1 is the part that is looping inside of a thread, so it's always checking the inventory. You can find DO - LOOP 1 == 1 in Get_Target function too.

 

//--  need to verify the CHAR_* vs a possible NPC_*. It's likely, but unsure
DISTANCE dist NpcList.P.X NpcList.P.Y NpcList.P.Z CHAR_X CHAR_Y CHAR_Z 

 

3 hours ago, Deviouz1 said:

the Char_ vs Npc_ is a question, i have no idea how to know whether the info in the player has the same properties as the info in the npc.

The distance calculation is correct.

 

IF ( NpcList.P.ATTACKABLE == 1 ) && ( NpcList.P.LOOKS_DEAD == 0 )

I would change PVPFLAG to ATTACKABLE. I'm not sure if NPCs have LOOKS_DEAD but you can test it out.

  • Like 1
Link to comment
Share on other sites

1 hour ago, Mantosh said:

These call functions into separate threads, so that they can run independently.

Ok, is there any reason it should be in that part of the script? coming from powershell, it seems way out of place. like it just kinda shows up in the middle somewhere for no particular reason. if thats the case, is there anywhere it should NOT be? like, x has to happen first, then you start the threading, then you  put in your functions or something? the flow of it confuses me.

Quote

//---------------------------------------------------------------------------------------
FUNCTION CheckEQ

  <..>

DO
GET_INVENTORY INV_LIST
SLEEP 500
  FOREACH I Inventory INV_LIST
    IF INV_LIST.I.NAME == "#$<&WEAPON&>"
        IF INV_LIST.I.EQUIPPED == #i0
          PRINT_TEXT " Equipping <&WEAPON&> ]"
          INJECT "<&USE_ME&>"
        ENDIF
    ENDIF
  NEXTEACH
SLEEP 1000
LOOP 1 == 1
RETURN VOID

The DO - LOOP 1 == 1 is the part that is looping inside of a thread, so it's always checking the inventory. You can find DO - LOOP 1 == 1 in Get_Target function too.

yeah, just wondering where the loop for those threads comes in. if they run in that order, which would make sense, ... wait.

...

 

... i feel like something just clicked. they arent running in an order. theyre constantly running "in their own thread" DUH! lol so lets say the function does not have a loop in it. does that mean that as soon as the function completes that thread goes away and you would have to spin up another one? if that's the case then basically, i could make as many threads as my box can handle, which is a lot, for things like keeping an eye on everything that is going on around each toon, based on whatever role they happen to play in my party. so i could have one monitoring for specific things to become perceivable like, say treasure chests, and if one becomes visible or whatever, stop the bot options, target the chest,  move_to like in the other part of the script, and once within like 50 or so, use_item keyid, then pickup anything that popped out, and then re-enable the bot options to continue farming, for example.

?

but if thats the case, isnt that what a function does anyway? whats the point of threading it? I feel like im missing something important here

Quote

//--  need to verify the CHAR_* vs a possible NPC_*. It's likely, but unsure
DISTANCE dist NpcList.P.X NpcList.P.Y NpcList.P.Z CHAR_X CHAR_Y CHAR_Z 

 

The distance calculation is correct.

Yeah i figured that just a few moments before i popped back in her to see if i got a response. the above is basically filling the variable DISTANCE with a calculation made between the NPC coordinates, vs my "CHAR_" coordinates which ends up being an INT that will be used to determine which action to take next, based on how far away it is.

Quote

 


IF ( NpcList.P.ATTACKABLE == 1 ) && ( NpcList.P.LOOKS_DEAD == 0 )

I would change PVPFLAG to ATTACKABLE. I'm not sure if NPCs have LOOKS_DEAD but you can test it out.

So, i was looking in the IDE for JingJing, and it lists the classes and such on the left and i can open them up and see most of the things in here, but i still dont understand how to reference each one of them.

for example, the screenshots below are of the npc and player class files. their properties do seem to be pretty similar. as expected, the pvpflag one is not in the npc class:

image.thumb.png.87fdfa8310ca72f6d35dd08c9d9a476e.pngimage.thumb.png.2a0308f6333619f25c2bde93c7c126c4.png

 

Having said that, I dont think the looks dead one will be very useful for this particular piece... but i do think its something i can incorporate somewhere else.

what i desperately need now is a way to send that alt+b command and try to figure out how to navigate the menus and select what i am looking for.

Edited by Deviouz1
Link to comment
Share on other sites

  • Toggle Staff
2 minutes ago, Deviouz1 said:

does that mean that as soon as the function completes that thread goes away and you would have to spin up another one?

Exactly 🧐

3 minutes ago, Deviouz1 said:

but if thats the case, isnt that what a function does anyway? whats the point of threading it?

The point would be that multiple things could be ran separately from each other. If you'd do one loop that would go through all the check and call functions in one thread then bot would do only that one thing until it's done. If it's casting a spell it wouldn't check for potion usage (just an example).
Another thing to consider, you could pause threaded loops with global variables for cases like if the character is now in town, so a restock function will be called. While that is in progress we might want to stop auto potions, because it might interrupt purchasing (item usage closes trade dialog). Not a great example, but I hope it makes sense.

11 minutes ago, Deviouz1 said:

but i still dont understand how to reference each one of them.

Each parameter or each NPC?

Parameter:

NpcList.P.HP > 0

Each NPC:

  NpcList.CLEAR <---- btw, this name was not changed
  GET_NPCS NpcList
  SLEEP 500
  FOREACH P Npc NpcList
    NpcList.P.PARAMATER
  NEXTEACH

Note: NpcList wasn't cleared every loop. Maybe you've noticed by now.
 

11 minutes ago, Deviouz1 said:

I dont think the looks dead one will be very useful for this particular piece

It would skip dead mobs that didn't fade-out yet.

Link to comment
Share on other sites

59 minutes ago, Mantosh said:

The point would be that multiple things could be ran separately from each other. If you'd do one loop that would go through all the check and call functions in one thread then bot would do only that one thing until it's done. If it's casting a spell it wouldn't check for potion usage (just an example).
Another thing to consider, you could pause threaded loops with global variables for cases like if the character is now in town, so a restock function will be called. While that is in progress we might want to stop auto potions, because it might interrupt purchasing (item usage closes trade dialog). Not a great example, but I hope it makes sense.

iiiinteresting... ok, ok, so then what if i had a main script, that looped forever basically, and its entire job is to do nothing but "perceive" for the toon its running on, and interpret/react to events?

i've seen some examples of setting up chat reception events, taking the message and using it to trigger functions. if i can figure out how that works, which im fairly sure i can, i can write a set of functions that could be called to do all sorts of things based on what i tell the toons to do, and from which chat it was received. theoretically, i could use clan and ally chats to send commands to an entire alliance/clan of toons. maybe make a clan for each 2 parties, and then use ally chats to send commands to specific clan leaders which would then, in turn send their own messages to their respective minions, and i could literally command an army of fearless, fanatically loyal, though admittedly kinda stupid toons to do my bidding on a party, clan, and alliance level, all from my dead toons ability to talk to teh bots.

"/allychat ClanName01 LeaderName Delegate Party01 Function01 my_target"

to which the clan leader would post in their clan chat a similar message telling the leader of Party01 to attack my_target

Then i could send the next:

"/allychat ClanLeaderName01 Delegate Party02 Function02  Party01"

to which the clan leader would send party02 to monitor the area around party01, and engage any newcomers that come within range of party01.. or something.

could even use them as macros allowing me to interactively control the individual parties when i want to, but allow them to do their normal thing otherwise.

hrm... sorry, you may have noticed that i tend to dive headlong into my thoughts. anyway,

59 minutes ago, Mantosh said:

Each parameter or each NPC?

Parameter:


NpcList.P.HP > 0

Each NPC:


  NpcList.CLEAR <---- btw, this name was not changed
  GET_NPCS NpcList
  SLEEP 500
  FOREACH P Npc NpcList
    NpcList.P.PARAMATER
  NEXTEACH

Note: NpcList wasn't cleared every loop. Maybe you've noticed by now.
 

not a chance, i'm not running it until i fully understand what it SHOULD be doing, and how so i can understand why it isnt doing what i want it to when it fails. 

For the moment i'm working on something a little less ambitious. one of the things that drives me nuts about the bot options is that it doesnt seem to work with toggle skills. takes a ton of DPS away from my AW parties. I need to rectify that.

Like, now. my minions are hitting 70-76 currently. up until now things have been fairly smooth and with the buffs i wasnt really missing the damage, but now that theyre higher and my gear still kinda sucks, relatively speaking, i am definitely missing it and i could use all the help i can get with clearing rooms. suddenly using VS on 5 AWs should help accomplish that nicely 🙂 

// New Script
INCLUDE StdLib\Player.l2c
INCLUDE StdLib\Skill.l2c

DEFINE_GLOBAL STRING Toggle1 "Vicious Stance"
DEFINE_GLOBAL INT Toggle_1 0

SKILL_GET_ID Toggle_1 "<&Toggle1&>"

//toggle1
DO
     //this should be different... i need to reference whether or not vicious stance is currently active
     //not whether or not its skillID is > 0 ... right?
     IF Toggle_1 > 0
          USE_SKILL "<&Toggle_1&>"
     ENDIF
     SLEEP 1000
LOOP 1 == 1 

unfortunately, it just turns on and off every second. I believe this is because Toggle_1 is the skillID for VS, which will always be greater than 0. So, any idea how i can determine whether or not VS is currently active? i guess a better question would be, how do you see what is currently populating a variable? in powershell i would write-verbose "$var" after setting it to verify that it had what i was expecting it to have. But i cant seem to figure out how to do that. I did see this in the player.l2c:

image.png.c1707cd8595ef718c3e85d313457583a.png

but i havent the foggiest how to dig into that list to see whats in it.

Link to comment
Share on other sites

  • Toggle Staff

Didn't I say one thing at a time? lol. Having quite fun actually.

46 minutes ago, Deviouz1 said:

i've seen some examples of setting up chat reception events, taking the message and using it to trigger functions.

That's what I (maybe we) call ChatControl or CC. :classic_happy: I wrote quite extensive such script for Adrenaline, but haven't found time converting it to JJ. What I found in the archive is a script I wrote to send out academy (and later clan) invites, so our clanmates could always get an invite (and some cash). 

Here's a part of it which you could easily extend into your function calling and later on function call parsing as you've described.

DEFINE_GLOBAL STRING ChatCommandExampleName "ActualChatTextToTriggerAnAction"
  
// This is the bind on event to call ChatCheck function; 25 is (as far as I remember) EVENT (Action) ID
SET_EVENT "<&SCRIPTEVENT_CHAT&>" "<&SYSTEM_CURRENTFILE&>" ChatCheck 25
  
// Infinity loop so that script wouldn't quit
WHILE ZERO == ZERO
	SLEEP 2000
WEND

END_SCRIPT
  
FUNCTION ChatCheck
	IF MESSAGETYPE == CHANNEL_PRIVATE //In your example use CLAN or ALLY here
		IF MESSAGE == ChatCommandExampleName
			DEFINE INT CharID 0
			CHAR_GET_ID CharID "<&SENDERNAME&>"
			SLEEP 500
			// Do something else; In our case it was sending an academy invite
			SLEEP 200
			SAY_TEXT "<&CHANNEL_PRIVATE&>" "Welcome to 'Get A Life' Clan! Happy Leveling!" "<&SENDERNAME&>"
		ENDIF
		// Other message triggers <...>
	ENDIF
RETURN VOID

By the way, I had a similar idea a few years ago. Ended up building a site to add things to the task queue :classic_biggrin: The hardest part was creating actual scripts to perform things IG. Stopped after 3 weeks. One day...

Link to comment
Share on other sites

  • Toggle Staff
21 minutes ago, Deviouz1 said:

wehehehehelll now....

I may have to dump tower.

<goes to dig up the IG login process again>

it's been foreeever since i last used IG L2net

l2.ini -> 127.0.0.1

L2.net -> IG ->

Spoiler

149.56.28.81



profit -> good

Link to comment
Share on other sites

this changes everything.

this will let me go set up a polygon, get them going, and then exit the client. half the time i wake up and my party leader is dead because the client bugged out and crashed. this should help avoid that. 🙂

Edited by Deviouz1
Link to comment
Share on other sites

 

ah HAH! that is, in fact, what I'm using.


image.png.9fc4ff06504f55efe8b4efd6556da9cb.png

 

My D drive.

image.png.ff728b79ab73d9671099b17c889e989e.png
 

Since it (the error) referenced Virtual Memory, which is slightly odd as I have 32 GB of DDR4, my memory usage never got above like 45% or so, I removed the page file from the C drive and added it to the E drive and set it to 100GB. It's made quite the difference in my Tower toon's performance, but it didn't seem to have any affect whatsoever with the L2net IG, which I also thought was odd. why would it affect one but not the other? 😞

Anyway, once I reach a stopping point, I'll go log out one of my toons and log it in with L2net IG, let it die, and post the error it throws. Maybe I'm missing something?

Edited by Deviouz1
Link to comment
Share on other sites

On 10/29/2020 at 1:13 PM, Mantosh said:

I built a few extensive scripts, mostly processing and building packets myself.

So, i went into L2net and turned on the client dump mode then went into the client and hit alt+b. this produced the following:

alt+b:
9:14:52 PM :[CLIENT DUMP: 23 5F 00 62 00 62 00 73 00 68 00 6F 00 6D 00 65 00 00 00

if i want to tell the client to do that via script, how would i do it? O.o i see some similar references in the script above, but they're all referring to speaking to an npc. i'm assuming this wouldn't be the same process but i cant seem to find anything poking around the internet.

 

I then went and performed the same action using the packet window and see this

GAH... dammit, i didnt mean to post that yet. to be continued momentarily.

Edited by Deviouz1
Link to comment
Share on other sites

image.thumb.png.5e0a27fc646814ba99e9d2e7cd28bf3e.png

 

When i copy the hex found on the right into the field at the bottom and hit inject,. i can see the community window pop open and if i hit it again, it closes. soi i know thats the right thing to do, but i've no earthly idea how to send that packet via script.

Tips?

Link to comment
Share on other sites

  • 4 years later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...