Target support function

Possible to add an option to attack the same mob a certain player is attacking?

2 Likes

I was planning to share the plugin, but was never tested after the recent changes.

Try it and comment us, teorically works.

xMobSelector
from phBot import *
import QtBind
import struct
import json
import os

pName = 'xMobSelector'
pVersion = '0.0.1'
pUrl = 'https://raw.githubusercontent.com/JellyBitz/phBot-xPlugins/master/xMobSelector.py'

# Globals
selectedUID = 0
isActived = False

# Initializing gui_
gui = QtBind.init(__name__,pName)

lblMobs = QtBind.createLabel(gui,"List of monsters near to you",39,10)
lstMobs = QtBind.createList(gui,6,30,200,229)
lstMobsData = []
btnRefreshMobs = QtBind.createButton(gui,'btnRefreshMobs_clicked',"   Refresh   ",71,259) 

lblAutoSelectMobs = QtBind.createLabel(gui,"Auto select mobs from this list",281,10)
lstAutoSelectMobs = QtBind.createList(gui,256,30,200,229)
lstAutoSelectMobsData = []
btnScanMobs = QtBind.createButton(gui,'btnScanMobs_clicked',"  Start Scanner  ",315,259)

btnAddMob = QtBind.createButton(gui,'btnAddMob_clicked',"  ►  ",217,90)
btnRemMob = QtBind.createButton(gui,'btnRemMob_clicked',"  ◄  ",217,110)

# Return character configs path (JSON)
def getConfig():
	return get_config_dir()+pName+ ".json"

# Load default configs
def loadDefaultConfig():
	# Clear data
	global isActived,lstAutoSelectMobsData
	isActived = False
	lstAutoSelectMobsData = []

	QtBind.setText(gui,btnScanMobs,"  Start Scanner  ")
	QtBind.clear(gui,lstMobs)
	QtBind.clear(gui,lstAutoSelectMobs)

# Save all config
def saveConfigs():
	# Save all data
	data = {}

	lstAutoSelect = []
	for mob in lstAutoSelectMobsData:
		lstAutoSelect.append({'name':mob['name'],'type':mob['type']});
	data["Mobs"] = lstAutoSelect

	# Override
	with open(getConfig(),"w") as f:
		f.write(json.dumps(data, indent=4, sort_keys=True))

# Loads all config previously saved
def loadConfigs():
	loadDefaultConfig()
	# Check config exists to load
	if os.path.exists(getConfig()):
		data = {}
		with open(getConfig(),"r") as f:
			data = json.load(f)
		# Load channels
		if "Mobs" in data:
			for mob in data["Mobs"]:
				QtBind.append(gui,lstAutoSelectMobs,mob['name']+" ("+getMobType(mob['type'])+")")
			global lstAutoSelectMobsData
			lstAutoSelectMobsData = data["Mobs"]

def getMobType(t):
	if t == 0:
		return 'General'
	if t == 1:
		return 'Champion'
	if t == 4:
		return 'Giant'
	if t == 5:
		return 'Titan'
	if t == 6:
		return 'Strong'
	if t == 7:
		return 'Elite'
	if t == 8:
		return 'Unique'
	if t == 16:
		return 'Party General'
	if t == 17:
		return 'Party Champion'
	if t == 20:
		return 'Giant'

	return 'Unknown['+str(t)+']'

# Start/Stop scaneer the list of mobs around you
def btnScanMobs_clicked():
	global isActived
	if isActived:
		isActived = False
		QtBind.setText(gui,btnScanMobs,"  Start Scanner  ")
	else:
		isActived = True
		QtBind.setText(gui,btnScanMobs,"  Stop Scanner  ")

		global selectedUID
		selectedUID = 0

# List of mobs actually around you
def btnRefreshMobs_clicked():
	# Clear the list
	QtBind.clear(gui,lstMobs)
	global lstMobsData
	lstMobsData = []

	# Get all mobs near to you
	mobs = get_monsters()
	if mobs:
		# add all kind of mobs actually found
		for uid, mob in mobs.items():
			# Add mob
			QtBind.append(gui,lstMobs,mob['name']+" ("+getMobType(mob['type'])+") - [UID:"+str(uid)+"]")
			lstMobsData.append(mob)

# Check if is already on the selector list
def ListAutoSelectMob_Contains(mob):
	for _mob in lstAutoSelectMobsData:
		if _mob['name'] == mob['name'] and _mob['type'] == mob['type']:
			return True
	return False

# Add specific type of mobs to the selector list
def btnAddMob_clicked():
	# Selecting mob from the scan list
	selectedIndex = QtBind.currentIndex(gui,lstMobs)
	if selectedIndex >= 0:
		selectedMob = lstMobsData[selectedIndex]

		if not ListAutoSelectMob_Contains(selectedMob):
			QtBind.append(gui,lstAutoSelectMobs,selectedMob['name']+" ("+getMobType(selectedMob['type'])+")")

			global lstAutoSelectMobsData
			lstAutoSelectMobsData.append(selectedMob)
			saveConfigs()

# remove mobs from the selector list
def btnRemMob_clicked():
	selectedIndex = QtBind.currentIndex(gui,lstAutoSelectMobs)
	if selectedIndex >= 0:
		QtBind.removeAt(gui,lstAutoSelectMobs,selectedIndex)

		global lstAutoSelectMobsData
		lstAutoSelectMobsData.pop(selectedIndex)
		saveConfigs()

# Called every 500ms.
def event_loop():
	if isActived:
		SearchAndDestroy()

# Scann mobs and target it if is required
def SearchAndDestroy():
	if len(lstAutoSelectMobsData) > 0:

		# Get nearby mobs
		mobs = get_monsters()

		# Check if mob died or gone far away
		if selectedUID:
			if mobs:
				for uid, mob in mobs.items():
					if uid == selectedUID:
						return
			global selectedUID
			selectedUID = 0

		# Check for a new target
		if mobs:
			for uid, mob in mobs.items():
				if ListAutoSelectMob_Contains(mob):
					Inject_SelectTarget(uid)
					return

# Inject Packet - Select Target
def Inject_SelectTarget(targetUID):
	packet = bytearray()
	packet = packet + struct.pack('<I',targetUID)
	inject_joymax(0x7045,packet, False)

# All packets received from Silkroad will be passed to this function
# Returning True will keep the packet and False will not forward it to the game server
def handle_joymax(opcode, data):
	if opcode == 0xB045:
		global selectedUID
		if data[0]:
			selectedUID = struct.unpack_from("<I",data,1)[0]
		else:
			selectedUID = 0

# Plugin load success
log('Plugin: '+pName+' v'+pVersion+' successfully loaded')

# Adding RELOAD plugin support
loadConfigs()

… a certain player is attacking?

Ah, I didn’t read it, but it’s something quick through plugins, has been done before!

Example: Target Support ("JellyBitz" as leader)
from phBot import *
import QtBind

pName = 'xSupport'

# globals
character_data = get_character_data()

# Initializing GUI
gui = QtBind.init(__name__,pName)
cbxEnabled = QtBind.createCheckBox(gui,'checkbox_clicked','Enable '+pName+' plugin',21,13)

# All packets received from Silkroad will be passed to this function
# Returning True will keep the packet and False will not forward it to the game server
def handle_joymax(opcode, data):
	if opcode == 0xB070 and QtBind.isChecked(gui,cbxEnableAttackSupport): # Object Action & Enabled AttackSupport
		if data[0] == 1: # Success
			if data[1] == 2: # Type. 0: Buff - 2: Attack
				AttackerID = struct.unpack_from("<I",data,7)[0]
				TargetID = struct.unpack_from("<I",data,15)[0]
				# Ensure is not a Buff
				if AttackerID != TargetID:
					# Check the nickname from attacker
					if getNickname(AttackerID) == "JellyBitz":
						Inject_SelectTarget(targetUID)


# Return Nick of player from ID only if is near
def getNickname(UniqueID):
	# Load all near players
	# players = get_players() << obsolete >>
	players = get_party()
	
	# Checking if UID is mine
	if PlayerID == character_data['player_id']:
		return character_data['name']
	
	# Check the UID with all players
	if players:
		for key, player in players.items():
			if key == PlayerID:
				return player['name']
	return ""

# Inject Packet - Select Target
def Inject_SelectTarget(targetUID):
	packet = bytearray()
	packet = packet + struct.pack('<I',targetUID)
	inject_joymax(0x7045,packet, False)

# Called when the character enters the game world
def joined_game():
	global character_data
	character_data = get_character_data()

log('Plugin: '+pName+' successfully loaded')
1 Like

Thanks! for some reason using xSupport it won’t let me connect into the game after a fresh phBot start. When i move the plugin into the plugins folder i get this as error:
[22:56:00] Python Error: name ‘cbxEnableAttackSupport’ is not defined
And my silkroad client crashes :confused:

Was an example really quick, I didn’t expect to work.

This could be working as intended (It should be targeting even players).

xTargetSupport
from phBot import *
import QtBind
import struct

pName = 'xTargetSupport'
pVersion = '0.0.1'
#pUrl = 'https://raw.githubusercontent.com/JellyBitz/phBot-xPlugins/master/xTargetSupport.py'

# The player nickname has to be in your party to work
PARTY_LEADER_NICKNAME = "JellyBitz"

# globals
character_data = get_character_data() # RELOAD support
PARTY_LEADER_NICKNAME = PARTY_LEADER_NICKNAME.lower()

# Initializing GUI
gui = QtBind.init(__name__,pName)
cbxEnabled = QtBind.createCheckBox(gui,'cbxDoNothing','Enabled',6,10)

# All packets received from Silkroad will be passed to this function
# Returning True will keep the packet and False will not forward it to the game server
def handle_joymax(opcode, data):
	# Object skill action & Enabled xTargetSupport
	if opcode == 0xB070 and QtBind.isChecked(gui,cbxEnabled):
		 # Success
		if data[0] == 1:
			# Type: Attack = 2
			if data[1] == 2:
				AttackerID = struct.unpack_from("<I",data,7)[0]
				TargetID = struct.unpack_from("<I",data,15)[0]
				# Ensure is not a Buff
				if AttackerID != TargetID:
					# Check the nickname from attacker
					if getNickname(AttackerID) == PARTY_LEADER_NICKNAME:
						Inject_SelectTarget(TargetID)
	return True

# Return Nick of player from ID only if is near
def getNickname(UniqueID):
	# Load all near players
	# players = get_players() << obsolete >>
	players = get_party()
	
	# Checking if UID is mine
	if UniqueID == character_data['player_id']:
		return character_data['name']
	
	# Check the UID with all players
	if players:
		for key, player in players.items():
			if key == UniqueID:
				return player['name']
	return ""

# Inject Packet - Select Target
def Inject_SelectTarget(targetUID):
	packet = bytearray()
	packet = packet + struct.pack('<I',targetUID)
	inject_joymax(0x7045,packet, False)

# Called when the character enters the game world
def joined_game():
	global character_data
	character_data = get_character_data()

# Plugin load success
log('Plugin: '+pName+' v'+pVersion+' successfully loaded')

phBot recently is crashing on overloaded packet stuffs, maybe a lock over there, like “untick a checkbox while is being checked”, happen me frequently on xPacketTool.

1 Like

The problem still continues. After installing the plugin, phbot does not connect to the server.

1 Like

Same for me

Right, I fix it. Mistakes by copy and paste stuffs you know.

1 Like

Its not an official release yet, JellyBlitz decides on what he want’s to do with it. Therefor there is no updates or URL’s yet.
Edit: Would be better to have this as a bot function rather than a plugin (imo).

2 Likes

Do I have to change JellyBitz @ .py to my charname?

Imgur: The magic of the Internet Is this what the plugin looks like?

Isn’t there a little irregular issue? :slight_smile: What is going on here

Scaling.

this is xmobselector. I was asking about xtargetsupport.

xTargetSupport does not work. JellyBlitz has done nothing on it yet.
The function of xTargetSupport is to attack the same monster/person a user is attacking.
This would rather be functional in the party settings in phBot itself than as a plugin.
The use for this would be:

  • ks’ing other party’s in the same training spot. (attack the same monster a specific party member is attacking)

  • prioritising a mob a party member is attacking (for example your warlock is attacking a giant party. all your wizards would target support him rather than attacking general party’s/champ party’s around them.)

  • easily target enemies in fortress war with party leader (maybe a hotkey function)

This is a visual idea of what i mean

  • If you’re botting. It will attack the same monster the named player is attacking.

  • If you’re not botting. It will select the same monster the named player is attacking/selecting.

All of this above can be done with target support. Its a hotkey in SRO itself.

4 Likes

@Ryan thoughts/idea’s/possibilities?

On the subject, not Ryan, I think Jelly Bitz is more active, I think he will edit and publish soon.

2 Likes

Really interesting! It would be so helpful. Waiting whether someone could implement this.

1 Like

Totally forgot about this. @Ryan ideas, thoughts & possibilities?