# Introduction

This GitBook is for documenting the phBot plugin API.

### What is Python?

From [Wikipedia](https://en.wikipedia.org/wiki/Python_\(programming_language\)):

> Python is a widely used general-purpose, high-level programming language. Its design philosophy emphasizes code readability, and its syntax allows programmers to express concepts in fewer lines of code than would be possible in languages such as C++ or Java.

Python 3.4/3.8 was chosen for the plugin system because it is easy to learn and does not require a compiler. Simply save your script inside the `Plugins` folder and launch the bot. Done!

### Where can I get help?

There is a forum section dedicated to plugins where you can publish your plugins and get help if you require it. <https://forum.projecthax.com/c/phbot/plugins/11>

You may also join our [Discord ](https://discord.com/channels/722060739765862410/722073386099933278/811643022114422814)and ask your questions there!

### What can I do with the plugin system?

I have made many functions available to Python. These functions allow you to get all players near you, get all NPCs/teleporters near you, and much more. You can do anything you want with the data. It's all up to you.

For example, a chat API is available; with this you can send messages to all nearby players.

### What do I need to get started?

You'll need the new stable release of phBot and the `python34` scripts which you can get by clicking [here](https://projecthax.com/showthread.php?t=14618). It comes with an example script named `example.py`, which can be deleted.

## phBot

* [Purchase](https://phbot.org/phbot/)
* [Guide](http://guide.phbot.org/)
* [Download](https://phbot.org/download/)

## Socials

* [Twitter](https://twitter.com/projecthax)
* [Facebook](https://facebook.com/projecthax)
* [Discord](https://discord.com/invite/e97chmQ)

## Learning Python

It is not necessary to install Python for phBot plugins to function.

* [Download](https://www.python.org/downloads/)
* [Python Documentation](https://docs.python.org/3/)
* [Code Academy](https://www.codecademy.com/en/tracks/python)


# Example Plugins

Plugins must be saved inside the `Plugins` folder otherwise they will not be loaded.

## Packet Processing Plugin

This simple plugin will display all packets going to/from Silkroad/Joymax.

```
from phBot import *

# Called when the bot successfully connects to the game server
def connected():
    pass

# 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_silkroad(opcode, data):
    log('Python: (Silkroad) 0x%02X' % opcode)
    return True

# All packets received from Joymax will be passed to this function
# Returning True will keep the packet and False will not forward it to the client
def handle_joymax(opcode, data):
    log('Python: (Joymax) 0x%02X' % opcode)
    return True

# Called when the character enters the game world
def joined_game():
    pass

# Called when the character teleports
# This function will also be called after the "joined_game" function
def teleported():
    pass

log('[%s] Loaded' % __name__)
```

## GUI Plugin

This next plugin creates a basic GUI on the `Plugins` tab inside the bot.

```
from phBot import *
import QtBind

gui = QtBind.init(__name__, 'GUI Example')

QtBind.createLabel(gui, 'Welcome to the GUI example Python script! From here you\'ll be able to add your own GUI to the \'Plugins\' tab inside phBot. Being able to create a UI\nopens up far more possibilies.\n\n- Do not replace the __name__ var in the QtBind.init() call. It is used for passing events to the correct module.\n- Only call QtBind.init() during module load\n- Labels are auto resized after text is set', 10, 10)

button1 = QtBind.createButton(gui, 'button_clicked', 'Button', 10, 125)
checkbox1 = QtBind.createCheckBox(gui, 'checkbox_clicked', 'Check Box', 10, 150)
label1 = QtBind.createLabel(gui, 'Label', 10, 175)
lineedit1 = QtBind.createLineEdit(gui, 'Text in box', 10, 200, 32, 16)

QtBind.createLabel(gui, 'The only downside is that you must create the UI by hand.', 10, 250)

def button_clicked():
    log('Button clicked')

def checkbox_clicked(checked):
    log('Check Box: %s' % checked)

log('[%s] Loaded' % __name__)
```

![](https://i.imgur.com/oUTuwAO.png)

## Socket Plugin

Sockets are now supported as of [v2.0.0](https://projecthax.com/showthread.php?t=14618). Some "pyd" files were missing (aka DLLs) which caused it to not work previously.

```
from phBot import *
import socket

log('[%s] Loaded' % __name__)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('www.example.com', 80))
s.send('GET / HTTP/1.0\r\nHost: www.example.com\r\n\r\n'.encode('utf-8'))
data = s.recv(1024)
s.close()

log('%s' % data)
```

```
[01:21:03] [socket_test] Loaded
[01:21:03] b'HTTP/1.0 200 OK\r\nCache-Control: max-age=604800\r\nContent-Type: text/html\r\nDate: Sun, 01 Apr 2018 05:21:01 GMT\r\nEtag: "1541025663+gzip+ident"\r\nExpires: Sun, 08 Apr 2018 05:21:01 GMT\r\nLast-Modified: Fri, 09 Aug 2013 23:54:35 GMT\r\nServer: ECS (phl/9D2C)\r\nVary: Accept-Encoding\r\nX-Cache: HIT\r\nContent-Length: 1270\r\nConnection: close\r\n\r\n<!doctype html>\n<html>\n<head>\n    <title>Example Domain</title>\n\n    <meta charset="utf-8" />\n    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />\n    <meta name="viewport" content="width=device-width, initial-scale=1" />\n    <style type="text/css">\n    body {\n        background-color: #f0f0f2;\n        margin: 0;\n        padding: 0;\n        font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;\n        \n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n        padding: 50px;\n        background-color: #fff;\n        border-radius: 1em;\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @med'
```


# phBot API


# Client

## get\_client()

This function returns information about the game client.

#### **Usage**

```
get_client()
```

#### **Returns**

`None` or a dictionary about the game client.

`window` - Window handle of the client

`pid` - Process ID of the client

`path` - Path to the client

`running` - State of the client. The process state is checked each time this function is called.

```
{
	'window': 859850,
	'pid': 18420,
	'path': 'C:/Users/...',
	'running': True
}
```

```
{
	'window': 0,
	'pid': 0,
	'path': '',
	'running': False
}
```


# Guild

## get\_guild()

Returns a dictionary of all guild members.

#### **Usage**

`get_guild()`

#### **Returns**

A dictionary of guild members or `None` if you are not in game. The dictionary key is the guild member ID.

```
 {
 	10944: {
 		'donated_gp': 35774,
 		'authority': 13,
 		'level': 50,
 		'online': 0,
 		'name': 'TAKER',
 		'region': 0,
 		'model': 14884
 	},
 	12308: {
 		'donated_gp': 265026,
 		'authority': 13,
 		'level': 69,
 		'online': 0,
 		'name': 'Pattylacks',
 		'region': 0,
 		'model': 1911
 	},
 	9780: {
 		'donated_gp': 281785,
 		'authority': 4294967295,
 		'level': 90,
 		'online': 0,
 		'name': 'NotAnt',
 		'region': 0,
 		'model': 1927
 	},
 	10837: {
 		'donated_gp': 282416,
 		'authority': 13,
 		'level': 81,
 		'online': 0,
 		'name': 'shark',
 		'region': 0,
 		'model': 1912
 	},
 	10281: {
 		'donated_gp': 266365,
 		'authority': 13,
 		'level': 70,
 		'online': 0,
 		'name': 'Zach',
 		'region': 0,
 		'model': 14891
 	},
 	10265: {
 		'donated_gp': 367015,
 		'authority': 31,
 		'level': 87,
 		'online': 0,
 		'name': 'Dave',
 		'region': 0,
 		'model': 1927
 	},
 	10826: {
 		'donated_gp': 318875,
 		'authority': 29,
 		'level': 73,
 		'online': 0,
 		'name': 'Nick',
 		'region': 0,
 		'model': 14887
 	},
 	10839: {
 		'donated_gp': 457117,
 		'authority': 29,
 		'level': 89,
 		'online': 0,
 		'name': 'Alexander',
 		'region': 0,
 		'model': 14882
 	},
 	7758: {
 		'donated_gp': 260691,
 		'authority': 31,
 		'level': 90,
 		'online': 1,
 		'name': '1337WeeMan',
 		'region': 0,
 		'model': 1928
 	}
 }
```

## get\_guild\_union

Returns a dictionary of guild union members.

#### **Usage**

`get_guild_union()`

#### **Returns**

A dictionary of guild union members or `None` if you are not in game. The dictionary key is the union ID.

```
{
	928: {
		'name': 'ResPecT',
		'count': 49,
		'level': 5,
		'master': 'Ruger'
	},
	1130: {
		'name': 'Defiance',
		'count': 11,
		'level': 5,
		'master': '_SwipeR_'
	},
	982: {
		'name': '_ResPecT_',
		'count': 20,
		'level': 5,
		'master': 'Serenity'
	}
}
```


# Events

If you do not need one of these functions, you should not add it to your Python script.

## finished

This function gets called when Python is being unloaded and the bot is exiting. You should close any open files here.

## connected

This function gets called when the bot connects to the game server.

## disconnected

This function is called when the bot disconnects from the server. It can be called several times on a disconnect.

## handle\_joymax(opcode, data)

All packets received from the server are passed to this function.

## handle\_silkroad(opcode, data)

All packets received from the game client are passed to this function.

## joined\_game()

Called when the user successfully selects a character. No character data has been loaded yet.

## teleported()

Called when the character teleports and right after `joined_game()`

## event\_loop()

Called every 500ms.

## character\_listing(args)

Called when the character listing is received. `args` is a string list of character names. Character name will include `*` at the beginning of its name if it is being deleted.

## handle\_chat(t, player, msg)

Called when a chat message is received. `t` is the type sent by the server.

All chat messages received are sent to this function. `player` can be `None` if it's not a private message.

## handle\_event(t, data)

Called for specific events. `data` field will always be a string. Cast it to an `int` if needed.

Current event list (`t`):

```
EVENT_UNIQUE_SPAWN = 0 # data = monster name
EVENT_HUNTER_SPAWN = 1 # data = player name (includes traders)
EVENT_THIEF_SPAWN = 2 # data = player name
EVENT_TRANSPORT_DIED = 3 # data = transport id (includes horses)
EVENT_PLAYER_ATTACKING = 4 # data = player name
EVENT_RARE_DROP = 5 # data = item model (equippable only)
EVENT_ITEM_DROP = 6 # data = item model (equippable only)
EVENT_DIED = 7 # data = empty string
EVENT_ALCHEMY_FINISHED = 8 # data = empty string
EVENT_GM_SPAWNED = 9 # data = player name
EVENT_LEVEL_UP = 10 # data = new level
```


# Players

This function is disabled.

#### Usage

`get_players()`

#### Returns

`None` or an object containing players nearby.

* The object can be empty.
* The `key` in the object is the player's ID.

```
{
    8654977: {
        'name': 'Excsajom',
        'guild': '7SHINOBI',
        'items': [
            {
                'name': 'GirinHornHeadgear',
                'degree': 9,
                'model': 5264,
                'servername': 'ITEM_CH_W_LIGHT_09_HA_C_RARE',
                'level': 79,
                'plus': 5
            },
            {
                'name': 'HolyWitacheonLamellar',
                'degree': 10,
                'model': 1430,
                'servername': 'ITEM_CH_W_LIGHT_10_BA_A',
                'level': 92,
                'plus': 5
            },
            {
                'name': 'WitacheonShell',
                'degree': 10,
                'model': 5338,
                'servername': 'ITEM_CH_W_LIGHT_10_SA_B_RARE',
                'level': 90,
                'plus': 5
            },
            {
                'name': 'GirinHornGlove',
                'degree': 9,
                'model': 5443,
                'servername': 'ITEM_CH_W_LIGHT_09_AA_B_RARE',
                'level': 76,
                'plus': 3
            },
            {
                'name': 'HolyWitacheonTasset',
                'degree': 10,
                'model': 1466,
                'servername': 'ITEM_CH_W_LIGHT_10_LA_A',
                'level': 92,
                'plus': 2
            },
            {
                'name': 'BlackFootgear',
                'degree': 10,
                'model': 5229,
                'servername': 'ITEM_CH_W_HEAVY_10_FA_A_RARE',
                'level': 91,
                'plus': 2
            },
            {
                'name': "Ye's Divine Bow",
                'degree': 10,
                'model': 4186,
                'servername': 'ITEM_CH_BOW_10_B_RARE',
                'level': 90,
                'plus': 7
            },
            {
                'name': 'Arrow',
                'degree': 0,
                'model': 62,
                'servername': 'ITEM_ETC_AMMO_ARROW_01',
                'level': 0,
                'plus': 0
            },
            {
                'name': 'SkeletonKnightArmor(F)',
                'degree': 0,
                'model': 36167,
                'servername': 'ITEM_PRE_MALL_AVATAR_W_DARKLKNIGHT_2011',
                'level': 0,
                'plus': 0
            },
            {
                'name': 'SkeletonKnightscythe(F)',
                'degree': 0,
                'model': 36173,
                'servername': 'ITEM_PRE_MALL_AVATAR_W_DARKLKNIGHT_ATTACH_2011',
                'level': 0,
                'plus': 0
            },
            {
                'name': "Devil's Spirit B grade(F)",
                'degree': 0,
                'model': 41181,
                'servername': 'ITEM_EVENT_AVATAR_W_NASRUN_BASIC',
                'level': 0,
                'plus': 0
            }
        ],
        'y': 1096.9185791015625,
        'grant': 'Piroszka',
        'dead': False,
        'x': 6433.58837890625
    },
    6590658: {
        'name': 'Lps',
        'guild': '___MeSKeN___',
        'items': [
            {
                'name': 'JewelCasque',
                'degree': 7,
                'model': 29456,
                'servername': 'ITEM_EVENT_CH_M_HEAVY_07_HA_A_RARE',
                'level': 55,
                'plus': 0
            },
            {
                'name': 'JewelArmor',
                'degree': 7,
                'model': 29564,
                'servername': 'ITEM_EVENT_CH_M_HEAVY_07_BA_A_RARE',
                'level': 57,
                'plus': 0
            },
            {
                'name': 'JewelShoulder',
                'degree': 7,
                'model': 29528,
                'servername': 'ITEM_EVENT_CH_M_HEAVY_07_SA_A_RARE',
                'level': 53,
                'plus': 0
            },
            {
                'name': 'JewelBracer',
                'degree': 7,
                'model': 29634,
                'servername': 'ITEM_EVENT_CH_M_HEAVY_07_AA_A_RARE',
                'level': 52,
                'plus': 0
            },
            {
                'name': 'JewelHose',
                'degree': 7,
                'model': 29598,
                'servername': 'ITEM_EVENT_CH_M_HEAVY_07_LA_A_RARE',
                'level': 56,
                'plus': 0
            },
            {
                'name': 'JewelFootgear',
                'degree': 7,
                'model': 29670,
                'servername': 'ITEM_EVENT_CH_M_HEAVY_07_FA_A_RARE',
                'level': 54,
                'plus': 0
            },
            {
                'name': 'GuardSword',
                'degree': 7,
                'model': 25851,
                'servername': 'ITEM_EVENT_CH_SWORD_07_A_RARE',
                'level': 52,
                'plus': 0
            },
            {
                'name': "Jecheonseong's Shield",
                'degree': 7,
                'model': 26022,
                'servername': 'ITEM_EVENT_CH_SHIELD_07_A_RARE',
                'level': 52,
                'plus': 0
            }
        ],
        'y': 1099.228271484375,
        'grant': '',
        'dead': False,
        'x': 6431.9716796875
    }
}
```


# Party

This function returns all party members.

#### Usage

`get_party()`

#### Returns

`None` or an object containing party members.

* The object can be empty.
* The `key` in the object is the player's party ID.
* `player_id` will be `0` until they spawn near you.
* `hp_percent` and `mp_percent` are values ranging from `0` to `10`. This is how Joymax sends the percentage data.

```
{
    9958419: {
        'name': 'xxxxxxxxxx',
        'mp_percent': 10,
        'player_id': 0,
        'hp_percent': 10,
        'y': 0.0,
        'guild': '',
        'level': 9,
        'x': 0.0
    },
    18466554: {
        'name': 'KyrieIrVinG_',
        'mp_percent': 10,
        'player_id': 0,
        'hp_percent': 10,
        'y': 0.0,
        'guild': 'Succubus',
        'level': 103,
        'x': 0.0
    },
    18478427: {
        'name': '__LeGo0LaS__',
        'mp_percent': 10,
        'player_id': 0,
        'hp_percent': 10,
        'y': 0.0,
        'guild': 'FGFDGDFGDF',
        'level': 84,
        'x': 0.0
    },
    18459759: {
        'name': '_SrK_KhaN_',
        'mp_percent': 10,
        'player_id': 0,
        'hp_percent': 10,
        'y': 0.0,
        'guild': 'Succubus',
        'level': 103,
        'x': 0.0
    }
}
```


# NPC

This function returns all nearby NPCs and teleporters.

#### Usage

`get_npcs()`

#### Returns

`None` or an object containing all nearby NPCs and teleporters.

* The object can be empty.
* The `key` in the object is the NPCs ID.

```
{
	346: {
		'name': 'Magic POP Guide Gori',
		'servername': 'NPC_CH_GACHA_OPERATOR',
		'model': 9252,
		'region': 25000,
		'x': 6433.72802734375,
		'y': 1032.762939453125
	},
	241: {
		'name': 'Grocery Trader Jinjin',
		'servername': 'NPC_CH_ACCESSORY',
		'model': 2008,
		'region': 25000,
		'x': 6501.85498046875,
		'y': 1067.8189697265625
	},
	348: {
		'name': 'Event So-Ok',
		'servername': 'NPC_CH_EVENT_KISAENG1',
		'model': 3861,
		'region': 25000,
		'x': 6446.16796875,
		'y': 1045.4300537109375
	},
	179: {
		'name': 'Storage-Keeper Wangu',
		'servername': 'NPC_CH_WAREHOUSE_M',
		'model': 2013,
		'region': 25000,
		'x': 6434.080078125,
		'y': 1058.9129638671875
	},
	196: {
		'name': 'Storage-Keeper Sansan',
		'servername': 'NPC_CH_WAREHOUSE_W',
		'model': 2014,
		'region': 25000,
		'x': 6434.03515625,
		'y': 1058.9189453125
	},
	347: {
		'name': 'Magic POP',
		'servername': 'NPC_CH_GACHA_MACHINE',
		'model': 9251,
		'region': 25000,
		'x': 6497.296875,
		'y': 1079.300048828125
	},
	10: {
		'name': 'Jangan',
		'servername': 'GATE_CH',
		'model': 2094,
		'region': 25000,
		'x': 6461.39990234375,
		'y': 1097.4000244140625
	},
	273: {
		'name': 'Herbalist Yangyun',
		'servername': 'NPC_CH_POTION',
		'model': 2005,
		'region': 25000,
		'x': 6494.408203125,
		'y': 1100.72900390625
	}
}
```

## NPC Goods

This function returns all of the items associated with the NPC.

#### Usage

`get_npc_goods(model)`

#### Returns

`None` or a dictionary of NPC goods.

```
goods = get_npc_goods(7537)
model = goods[0][0]['model'] # model of page 0 / slot 0 (19693)
```

```
{
	0: {
		0: {
			'name': 'Blaze Blade',
			'servername': 'ITEM_CH_BLADE_08_A_RARE_HONOR',
			'model': 19693
		},
		1: {
			'name': 'Blaze Blade',
			'servername': 'ITEM_CH_BLADE_08_B_RARE_HONOR',
			'model': 19694
		},
		2: {
			'name': 'Blaze Blade',
			'servername': 'ITEM_CH_BLADE_08_C_RARE_HONOR',
			'model': 19695
		},
		3: {
			'name': 'Moon Bow',
			'servername': 'ITEM_CH_BOW_08_A_RARE_HONOR',
			'model': 19711
		},
		4: {
			'name': 'Moon Bow',
			'servername': 'ITEM_CH_BOW_08_B_RARE_HONOR',
			'model': 19712
		},
		5: {
			'name': 'Moon Bow',
			'servername': 'ITEM_CH_BOW_08_C_RARE_HONOR',
			'model': 19713
		},
		6: {
			'name': 'Iranggjingun Pike',
			'servername': 'ITEM_CH_SPEAR_08_A_RARE_HONOR',
			'model': 19699
		},
		7: {
			'name': 'Iranggjingun Pike',
			'servername': 'ITEM_CH_SPEAR_08_B_RARE_HONOR',
			'model': 19700
		},
		8: {
			'name': 'Iranggjingun Pike',
			'servername': 'ITEM_CH_SPEAR_08_C_RARE_HONOR',
			'model': 19701
		},
		9: {
			'name': 'Devil Sword',
			'servername': 'ITEM_CH_SWORD_08_A_RARE_HONOR',
			'model': 19687
		},
		10: {
			'name': 'Devil Sword',
			'servername': 'ITEM_CH_SWORD_08_B_RARE_HONOR',
			'model': 19688
		},
		11: {
			'name': 'Devil Sword',
			'servername': 'ITEM_CH_SWORD_08_C_RARE_HONOR',
			'model': 19689
		},
		12: {
			'name': 'Polearm',
			'servername': 'ITEM_CH_TBLADE_08_A_RARE_HONOR',
			'model': 19705
		},
		13: {
			'name': 'Polearm',
			'servername': 'ITEM_CH_TBLADE_08_B_RARE_HONOR',
			'model': 19706
		},
		14: {
			'name': 'Polearm',
			'servername': 'ITEM_CH_TBLADE_08_C_RARE_HONOR',
			'model': 19707
		}
	},
	1: {
		0: {
			'name': 'Honor Alchemy Stone (8th degree)',
			'servername': 'ITEM_ETC_ARCHEMY_MAGICSTONE_REPAIR_08',
			'model': 19717
		}
	}
}
```


# Character

## get\_character\_data()

This function returns stats of the current character.

#### Usage

`get_character_data()`

#### Returns

`None` or an object containing character data.

* The object can be empty.

```
{
	'server': '',
	'name': '',
	'model': 1907,
	'guild': '',
	'job_name': '',
	'region': 25000,
	'x': 6428.2373046875,
	'y': 1086.672607421875,
	'hp': 32207,
	'mp': 8744,
	'hp_max': 32207,
	'mp_max': 8744,
	'level': 110,
	'dead': False,
	'gold': 99920423940,
	'current_exp': 34360711,
	'max_exp': 4044607839,
	'sp': 997208910,
	'job_current_exp': 1698,
	'job_max_exp': 70875,
	'player_id': 33349,
	'account_id': 3,
	'locale': 22,
	'exp_ratio': 1.0
}
```

## get\_position()

This function returns the character's current position.

#### Usage

`get_position()`

#### Returns

`None` or an object containing position data.

```
{
    'region': 24744,
    'z': -52.93023681640625,
    'y': 828.7999877929688,
    'x': 6435.89990234375
}
```

## get\_active\_skills()

This function returns a dictionary of active skills.

#### Usage

`get_active_skills()`

#### Returns

`None` or a dictionary of active skills.

```
{
	5411: {
		'name': 'Increase Moving speed 100%',
		'servername': 'SKILL_MALL_MOVE_SPEED_UP_100_01'
	}
}
```

## get\_skills()

This function returns a dictionary of the players skills.

#### Usage

`get_skills()`

#### Returns

`None` or a dictionary of all the players skills.

```
{
	1414: {
		'name': 'Flame body - Extreme',
		'servername': 'SKILL_CH_FIRE_GONGUP_C_03',
		'level': 64,
		'mastery': 275,
		'cast_time': 1000,
		'cooldown': 5000,
		'duration': 617647,
		'active': False,
		'can_cast': True
	},
	1286: {
		'name': 'Grass Walk - Flow',
		'servername': 'SKILL_CH_LIGHTNING_GYEONGGONG_A_12',
		'level': 45,
		'mastery': 274,
		'cast_time': 0,
		'cooldown': 15000,
		'duration': 511849,
		'active': False,
		'can_cast': False
	},
	992: {
		'name': '4 Arrow Combo ',
		'servername': 'SKILL_CH_BOW_CHAIN_C_09',
		'level': 67,
		'mastery': 259,
		'cast_time': 561,
		'cooldown': 4000,
		'duration': 0,
		'active': False,
		'can_cast': True
	},
	7835: {
		'name': 'Anti Devil Bow - Annihilate',
		'servername': 'SKILL_CH_BOW_CRITICAL_E_06',
		'level': 100,
		'mastery': 259,
		'cast_time': 530,
		'cooldown': 4000,
		'duration': 0,
		'active': False,
		'can_cast': True
	},
	984: {
		'name': '3 Arrow Combo',
		'servername': 'SKILL_CH_BOW_CHAIN_B_09',
		'level': 45,
		'mastery': 259,
		'cast_time': 909,
		'cooldown': 4000,
		'duration': 0,
		'active': False,
		'can_cast': True
	},
	1398: {
		'name': 'Fire Shield - Phoenix',
		'servername': 'SKILL_CH_FIRE_SHIELD_A_06',
		'level': 23,
		'mastery': 275,
		'cast_time': 2000,
		'cooldown': 5000,
		'duration': 410924,
		'active': False,
		'can_cast': True
	},
	1053: {
		'name': 'Demon Soul Arrow',
		'servername': 'SKILL_CH_BOW_NORMAL_A_05',
		'level': 35,
		'mastery': 259,
		'cast_time': 0,
		'cooldown': 5000,
		'duration': 471429,
		'active': False,
		'can_cast': True
	},
	1: {
		'name': 'Normal Attack',
		'servername': 'SKILL_PUNCH_01',
		'level': 0,
		'mastery': 0,
		'cast_time': 1500,
		'cooldown': 1500,
		'duration': 0,
		'active': False,
		'can_cast': True
	}
etc...
```

## get\_mastery()

This function returns a dictionary of the players skill masteries.

#### Usage

`get_mastery()`

Returns

`None` or a dictionary of masteries.

```
{
	257: {
		'name': 'Bicheon',
		'level': 0,
		'sp': -1
	},
	258: {
		'name': 'Heuksal',
		'level': 0,
		'sp': -1
	},
	259: {
		'name': 'Pacheon',
		'level': 100,
		'sp': 13174
	},
	273: {
		'name': 'Cold',
		'level': 0,
		'sp': -1
	},
	274: {
		'name': 'Lightning',
		'level': 91,
		'sp': 4515
	},
	275: {
		'name': 'Fire',
		'level': 100,
		'sp': 13174
	},
	276: {
		'name': 'Force',
		'level': 0,
		'sp': -1
	}
}
```


# Academy

## get\_academy()

This function returns the academy members.

#### Usage

`get_academy()`

#### Returns

`None` or a list of academy members. `type` refers to the academy member type.

```
{
	6699: {
		'online': 1,
		'type': 0,
		'x': 0.0,
		'level': 110,
		'name': 'aaaaaa',
		'y': 0.0
	},
	'id': 237
}
```


# Inventory

## get\_inventory()

This function returns the current characters inventory items.

#### Usage

`get_inventory()`

#### Returns

`None` or an object containing the size of the inventory and a `list` of items. Empty slots in the `items` list will be set to `None`.

```
{
	'size': 109,
	'gold': 99920517441,
	'items': [{
		'model': 3888,
		'servername': 'ITEM_CH_M_HEAVY_07_HA_C_SUPER',
		'name': 'ITEM_CH_M_HEAVY_07_HA_C_SUPER',
		'quantity': 1,
		'plus': 64,
		'durability': 8953
	}, {
		'model': 3890,
		'servername': 'ITEM_CH_M_HEAVY_07_BA_C_SUPER',
		'name': 'ITEM_CH_M_HEAVY_07_BA_C_SUPER',
		'quantity': 1,
		'plus': 64,
		'durability': 8947
	}, {
		'model': 3889,
		'servername': 'ITEM_CH_M_HEAVY_07_SA_C_SUPER',
		'name': 'ITEM_CH_M_HEAVY_07_SA_C_SUPER',
		'quantity': 1,
		'plus': 64,
		'durability': 8959
	}, {
		'model': 3892,
		'servername': 'ITEM_CH_M_HEAVY_07_AA_C_SUPER',
		'name': 'ITEM_CH_M_HEAVY_07_AA_C_SUPER',
		'quantity': 1,
		'plus': 64,
		'durability': 8943
	}, {
		'model': 3891,
		'servername': 'ITEM_CH_M_HEAVY_07_LA_C_SUPER',
		'name': 'ITEM_CH_M_HEAVY_07_LA_C_SUPER',
		'quantity': 1,
		'plus': 64,
		'durability': 8953
	}, {
		'model': 3893,
		'servername': 'ITEM_CH_M_HEAVY_07_FA_C_SUPER',
		'name': 'ITEM_CH_M_HEAVY_07_FA_C_SUPER',
		'quantity': 1,
		'plus': 64,
		'durability': 8967
	}, {
		'model': 4188,
		'servername': 'ITEM_CH_BOW_11_A_RARE',
		'name': 'Mirage Illusion Bow',
		'quantity': 1,
		'plus': 8,
		'durability': 72
	}, {
		'model': 3823,
		'servername': 'ITEM_MALL_QUIVER',
		'name': 'Arrows',
		'quantity': 360,
		'plus': 0,
		'durability': 0
	}, None, {
		'model': 1856,
		'servername': 'ITEM_CH_EARRING_08_A',
		'name': 'Black Pearl Earring',
		'quantity': 1,
		'plus': 0,
		'durability': 0
	}, {
		'model': 1892,
		'servername': 'ITEM_CH_NECKLACE_08_A',
		'name': 'Black Pearl Necklace',
		'quantity': 1,
		'plus': 0,
		'durability': 0
	}, {
		'model': 1820,
		'servername': 'ITEM_CH_RING_08_A',
		'name': 'Black Pearl Ring',
		'quantity': 1,
		'plus': 0,
		'durability': 0
	}, {
		'model': 1820,
		'servername': 'ITEM_CH_RING_08_A',
		'name': 'Black Pearl Ring',
		'quantity': 1,
		'plus': 0,
		'durability': 0
	}, {
		'model': 4220,
		'servername': 'ITEM_CH_SHIELD_09_C_RARE',
		'name': 'Scale Shield',
		'quantity': 1,
		'plus': 8,
		'durability': 87
	}, {
		'model': 3851,
		'servername': 'ITEM_MALL_GLOBAL_CHATTING',
		'name': 'Global chatting',
		'quantity': 33,
		'plus': 0,
		'durability': 0
	}, None, {
		'model': 9279,
		'servername': 'ITEM_COS_P_FLUTE_WHITE',
		'name': 'White Wolf Summon Scroll',
		'quantity': 1,
		'plus': 0,
		'durability': 0
	}, {
		'model': 5913,
		'servername': 'ITEM_MALL_MP_SUPERSET_5_BAG',
		'name': 'MP Recovery potion (X-large)',
		'quantity': 1564,
		'plus': 0,
		'durability': 0
	}, {
		'model': 5912,
		'servername': 'ITEM_MALL_HP_SUPERSET_5_BAG',
		'name': 'HP Recovery potion (X-large)',
		'quantity': 9643,
		'plus': 0,
		'durability': 0
	}, {
		'model': 5912,
		'servername': 'ITEM_MALL_HP_SUPERSET_5_BAG',
		'name': 'HP Recovery potion (X-large)',
		'quantity': 10000,
		'plus': 0,
		'durability': 0
	}, {
		'model': 8,
		'servername': 'ITEM_ETC_HP_POTION_05',
		'name': 'HP Recovery Potion (X-Large)',
		'quantity': 91,
		'plus': 0,
		'durability': 0
	}, {
		'model': 5913,
		'servername': 'ITEM_MALL_MP_SUPERSET_5_BAG',
		'name': 'MP Recovery potion (X-large)',
		'quantity': 10000,
		'plus': 0,
		'durability': 0
	}, {
		'model': 5912,
		'servername': 'ITEM_MALL_HP_SUPERSET_5_BAG',
		'name': 'HP Recovery potion (X-large)',
		'quantity': 10000,
		'plus': 0,
		'durability': 0
	}, {
		'model': 5913,
		'servername': 'ITEM_MALL_MP_SUPERSET_5_BAG',
		'name': 'MP Recovery potion (X-large)',
		'quantity': 10000,
		'plus': 0,
		'durability': 0
	}, None, {
		'model': 5913,
		'servername': 'ITEM_MALL_MP_SUPERSET_5_BAG',
		'name': 'MP Recovery potion (X-large)',
		'quantity': 10000,
		'plus': 0,
		'durability': 0
	}, {
		'model': 28681,
		'servername': 'ITEM_ETC_E091216_SNOWFLAKE',
		'name': 'Snow flake',
		'quantity': 26,
		'plus': 0,
		'durability': 0
	}, None, None, None, {
		'model': 2198,
		'servername': 'ITEM_ETC_SCROLL_RETURN_02',
		'name': 'Special Return Scroll',
		'quantity': 44,
		'plus': 0,
		'durability': 0
	}, {
		'model': 24662,
		'servername': 'ITEM_EVENT_COS_P_MYOWON_SCROLL',
		'name': 'Monkey Summon Scroll',
		'quantity': 1,
		'plus': 0,
		'durability': 0
	}
	etc...
	]
}
```

## get\_storage()

This function returns the current characters storage items. If the character has not entered storage, this function will return no items.

#### Usage

`get_storage()`

#### Returns

`None` or an object containing the size of the storage and a `list` of items.

## get\_guild\_storage()

This function returns the current characters guild storage items. If the character has not entered guild storage, this function will return no items.

#### Usage

`get_guild_storage()`

#### Returns

`None` or an object containing the size of the guild storage and a `list` of items.

## get\_job\_pouch()

This function returns the current characters job pouch items.

#### Usage

`get_job_pouch()`

#### Returns

`None` or an object containing the size of the job pouch and a `list` of items.

## sort\_inventory()

This function sorts the player's inventory. Sorting is done in a separate thread and will *not* notify you when it completes.

#### Usage

sort\_inventory()

#### Returns

`True/False`

## use\_return\_scroll()

This function will use a return scroll from the player's inventory.

#### Usage

`use_return_scroll()`

#### **Returns**

`True/False`

## reverse\_return(type, name)

Uses a reverse return scroll.

#### **Type**

```
0 - Return to last return scroll
1 - Return to last death
2 - Move to party member
3 - Move to location
```

#### **Usage**

The name argument can either be a party member name or location name.

`reverse_return(0, '')`

#### **Returns**

`True` if a reverse return was used or `False` if one could not be found.


# Pets

## get\_pets()

This function returns the characters summoned pets.

#### Usage

`get_pets()`

#### Returns

`None` or an object containing all summoned pets.

* The object can be empty.
* The `key` in the object is the pet ID.

```
{
	43182: {
		'name': '',
		'servername': 'COS_P_MYOWON',
		'model': 7493,
		'type': 'pick',
		'hp': 0,
		'mounted': False,
		'items': [
			None,
			{
				'model': 3769,
				'servername': 'ITEM_MALL_RETURN_SCROLL_HIGH_SPEED',
				'name': 'Instant Return Scroll',
				'quantity': 50,
				'plus': 0,
				'durability': 0
			},
			None,
			None,
			{
				'model': 36777,
				'servername': 'ITEM_MALL_DAMAGE_ABS_10P_SCROLL',
				'name': '10% damage absorption scroll',
				'quantity': 9,
				'plus': 0,
				'durability': 0
			},
			None,
			None,
			None,
			None,
			None,
			{
				'model': 3769,
				'servername': 'ITEM_MALL_RETURN_SCROLL_HIGH_SPEED',
				'name': 'Instant Return Scroll',
				'quantity': 2,
				'plus': 0,
				'durability': 0
			},
			None,
			None,
			None,
			None,
			None,
			None,
			None,
			{
				'model': 3795,
				'servername': 'ITEM_MALL_REVERSE_RETURN_SCROLL',
				'name': 'Reverse Return Scroll',
				'quantity': 50,
				'plus': 0,
				'durability': 0
			},
			None,
			None,
			None,
			None,
			None,
			None,
			None,
			None,
			None
		]
	}
}
```

## Pet Types

* `none`
  * In this case, `none` is a string. It's returned when the pet cannot be identified due to an error.
* `fellow`
* `horse`
* `pick`
* `transport`
* `wolf`


# Monsters

## get\_monsters()

This function returns a dictionary of all nearby monsters.

#### Usage

`get_monsters()`

#### Returns

`None` or a dictionary of monsters.

* The object can be empty.
* The key in the object is the monster's ID.

```
{
	46296: {
		'name': 'Mangyang',
		'servername': 'MOB_CH_MANGNYANG',
		'model': 1933,
		'type': 0,
		'region': 24744,
		'x': 6400.048828125,
		'y': 813.6922607421875,
		'hp': 54,
		'max_hp': 54,
		'attacking': 0
	},
	51491: {
		'name': 'Mangyang',
		'servername': 'MOB_CH_MANGNYANG',
		'model': 1933,
		'type': 0,
		'region': 24744,
		'x': 6450.6328125,
		'y': 873.4962158203125,
		'hp': 54,
		'max_hp': 54,
		'attacking': 0
	},
	8075: {
		'name': 'Mangyang',
		'servername': 'MOB_CH_MANGNYANG',
		'model': 1933,
		'type': 0,
		'region': 24744,
		'x': 6429.68359375,
		'y': 815.7973022460938,
		'hp': 54,
		'max_hp': 54,
		'attacking': 0
	},
	24534: {
		'name': 'Mangyang',
		'servername': 'MOB_CH_MANGNYANG',
		'model': 1933,
		'type': 0,
		'region': 24744,
		'x': 6410.0791015625,
		'y': 830.5478515625,
		'hp': 54,
		'max_hp': 54,
		'attacking': 0
	},
	33437: {
		'name': 'Mangyang',
		'servername': 'MOB_CH_MANGNYANG',
		'model': 1933,
		'type': 0,
		'region': 24744,
		'x': 6433.02294921875,
		'y': 802.4546508789062,
		'hp': 54,
		'max_hp': 54,
		'attacking': 0
	},
	52222: {
		'name': 'Mangyang',
		'servername': 'MOB_CH_MANGNYANG',
		'model': 1933,
		'type': 0,
		'region': 24744,
		'x': 6459.87890625,
		'y': 820.3279418945312,
		'hp': 54,
		'max_hp': 54,
		'attacking': 0
	},
	1632: {
		'name': 'Mangyang',
		'servername': 'MOB_CH_MANGNYANG',
		'model': 1933,
		'type': 0,
		'region': 24744,
		'x': 6373.32666015625,
		'y': 851.5452880859375,
		'hp': 54,
		'max_hp': 54,
		'attacking': 0
	},
	17907: {
		'name': 'Mangyang',
		'servername': 'MOB_CH_MANGNYANG',
		'model': 1933,
		'type': 0,
		'region': 24744,
		'x': 6413.42822265625,
		'y': 856.0980834960938,
		'hp': 54,
		'max_hp': 54,
		'attacking': 0
	}
}
```


# Encoding

## get\_encoding()

This function returns the encoding used by the current Silkroad locale. For iSRO/SilkroadR/cSRO SilkroadR it's `utf-16le` and for vSRO it could be the same or `cp1251`. This is useful if you want to parse certain in game packets (e.g. chat) that could be Unicode.

#### Usage

`get_encoding()`

#### Returns

`string` or `None` if no locale has been selected yet.

* `gb18030`
* `cp1251`
* `big5`
* `sjis`
* `euc-kr`


# Locale

## get\_locale()

This function returns the current game locale.

#### Usage

`get_locale()`

#### Returns

`unsigned char`

* `2`
  * kSRO
* `18`
  * iSRO
* `65`
  * SilkroadR
* `22`
  * vSRO (includes all versions: official, 1.188, 1.193, 1.274, Black Rogue, and thSRO)
* `23`
  * Official vSRO 2 Job
* `34`
  * cSRO SilkroadR (private servers)
* `9`
  * ECSRO
* `46`
  * jSRO GameCom
* `52`
  * cSRO SilkroadR (official)
* `54`
  * DIGEAM
* `56`
  * TRSRO
* `59`
  * ruSRO


# Config

## get\_config\_path()

This function returns the player's JSON configuration path. Any changes you make will be overwritten by the bot at some point.

#### Usage

`get_config_path()`

#### Returns

`string` or `None` if the player is not in game.

## get\_config\_dir()

This function returns the phBot `Config` directory. It will include a trailing forward slash - you do not need to append one.

#### Usage

`get_config_dir()`

#### Returns

`string`

## get\_log\_dir()

This function returns the phBot `Log` directory. It will include a trailing forward slash - you do not need to append one.

#### Usage

`get_log_dir()`

#### Returns

`string`


# Botting

These functions listed below allow you to start/stop botting/trace/trade.

## start\_bot()

Starts botting.

#### Returns

`True` if bot has started, `False` if starting the bot failed.

## stop\_bot()

Stops botting.

#### Returns

`True` if bot has stopped, `False` if stopping the bot failed.

## start\_trace(name)

Starts tracing a player.

#### Returns

`True` if tracing has started, `False` if starting the trace failed.

#### Usage

`start_trace('player name')`

## stop\_trace()

Stops tracing.

#### Returns

`True` if trace has stopped, `False` if stopping the trace failed.

## start\_trade()

Starts auto trade.

#### Returns

`True` if trading has started, `False` if starting trade failed.

## stop\_trade()

Stops auto trade.

#### Returns

`True` if auto trade has stopped, `False` if stopping auto trade failed.


# Taxi

## get\_taxi()

This function allows you to retrieve the player's in your taxi party.

#### Usage

`get_taxi()`

#### Returns

`None` or a dictionary of players in the party taxi. Some values will not be present if the player is not in your party.

`remaining` is the time remaining in seconds.

`party` will be set to `True` or `False` depending on if they are in your party or not.

`player_id` can be `0` if you have not seen the player in game.

```
 {
 	'zzzzzzzz': {
 		'remaining': 3597,
 		'exchanging': False,
 		'party': True,
 		'party_id': 6,
 		'player_id': 38859,
 		'level': 90,
 		'dead': False,
 		'x': 6435.7001953125,
 		'y': 912.0999755859375
 	}
 }
```

```
{
	'zzzzzzzz': {
		'remaining': 3597,
		'exchanging': False,
		'party': False
	}
}
```


# Packet Injection

## inject\_joymax(opcode, data, encrypted)

Sends a packet to Joymax (the server).

## inject\_silkroad(opcode, data, encrypted)

Sends a packet to Silkroad (the game).

#### Example

`inject_joymax(0x704F, b'\x04', False)`

* `opcode`
  * unsigned short
* `data`
  * bytes
* `encrypted`
  * boolean

For complex packets you should use a packet building class. I have written one which can be found here: <https://github.com/ProjectHax/pySilkroadSecurity/blob/master/python/stream.py>


# Log

Logs text to the main bot log.

#### Usage

`log('Any string sent to this function will be appended to the bot log.')`

#### Returns

`None`


# Game Data

These functions return an object based on the game item ID or monster ID.

## get\_item(id)

#### Usage

`get_item(1)`

#### Returns

`None` or an object with the game data.

```
{
    'servername': 'ITEM_ETC_GOLD_01',
    'name': 'Gold',
    'tid1': 3,
    'tid2': 5,
    'tid3': 0,
    'cash_item': False,
    'max_stack': 0,
    'level': 0
}
```

## get\_item\_string(str)

#### Usage

`get_item_string('ITEM_ETC_GOLD_01')`

#### Returns

`None` or an object with the game data.

```
{
    'servername': 'ITEM_ETC_GOLD_01',
    'name': 'Gold',
    'tid1': 3,
    'tid2': 5,
    'tid3': 0,
    'cash_item': False,
    'max_stack': 0,
    'level': 0
}
```

## get\_monster(id)

#### Usage

`get_monster(1907)`

#### Returns

`None` or an object with the game data.

```
{
    'servername': 'CHAR_CH_MAN_ADVENTURER',
    'name': 'CHAR_CH_MAN_ADVENTURER',
    'level': 1,
    'hp': 0
}
```

## get\_monster\_string(str)

#### Usage

`get_monster_string('CHAR_CH_MAN_ADVENTURER')`

#### Returns

`None` or an object with the game data.

```
{
    'servername': 'CHAR_CH_MAN_ADVENTURER',
    'name': 'CHAR_CH_MAN_ADVENTURER',
    'level': 1,
    'hp': 0
}
```

## get\_skill(id)

#### Usage

`get_skill(3)`

#### Returns

`None` or an object with the game data.

```
{
    'servername': 'SKILL_CH_SWORD_SMASH_A_01',
    'duration': 0,
    'sp': 2,
    'cool_down': 3000,
    'mp': 19,
    'mastery': 257,
    'name': 'Strike Smash',
    'cast_time': 1022,
    'level': 5
}
```

## get\_zone\_name(region)

#### Usage

`get_zone_name(25000)`

#### Returns

Name of the in game region. In the example above it returns `Jangan`.


# Teleport

This function returns a `tuple` with the necessary data to use a teleporter.

#### Usage

`get_teleport_data('Jangan', 'Donwhang')`

Source or destination can be the NPC name, location name, or the server name.

#### Returns

`None` if the data could not be found or a `tuple` with the necessary data to use a teleporter.

```
(1, 2)
```

The second value in the `tuple` is all you need. You must select the NPC or teleporter and send the teleport code to the server. This command will not send any packets.


# Training Area

## set\_training\_position(region, x, y, z)

Sets the coordinates for the active training area. If no training area is active, this function does nothing.

#### Usage

`set_training_position(0, 6400.0, 800.0, 0.0)`

* The region will be calculated by the bot if it's set to `0`. This can only be done for non-cave areas. For cave areas, you will need to set the region yourself, or take it from `get_character_data()`.
* The X, Y, Z coordinates are floats.

#### Returns

`True` or `False` depending on if the training position has been set.

## set\_training\_script(path)

Sets the script path for the current training area.

#### **Usage**

`set_training_script('C:\path\to\script.txt')`

#### **Returns**

`True` if changed otherwise `None`

If the path is `''` (empty) it will reset the training area.

## set\_training\_radius(radius)

Changes the radius for the current training area.

#### **Usage**

`set_training_radius(50.0)`

#### **Returns**

`True` or `False` depending on if the training radius has been set.

## get\_training\_area()

Returns the training area info for the enabled training area.

#### **Usage**

`get_training_area()`

#### **Returns**

`None` or a dictionary containing the training area info.

```
{
	'x': 6428.2373046875,
	'y': 1086.672607421875,
	'z': -32.60887908935547,
	'region': 25000,
	'path': '',
	'radius': 50.0,
	'pick_radius': 50.0
}
```

## set\_training\_area(name)

Changes the training area based on its name.

#### **Usage**

`set_training_area('name')`

#### **Returns**

`True` if the training area was changed or `False` if it was not.


# Command Line Arguments

Returns a list of all command line arguments passed to the bot.

#### Usage

`get_command_line_args()`

#### Returns

A `list` of strings with the command line arguments, or `None` if there was a problem getting the arguments.

`['phBot.exe', '--skipupdates']`


# Movement

## move\_to(x, y, z)

Moves to the specified coordinates.

* `Z` coordinate can be 0.
* This function call will *not* wait for the character to reach the destination. This is so the threads do not block.
* This function supports moving on transports/pets.

#### Usage

`move_to(6400.0, 800.0, 0.0)`

#### Returns

`None`

## move\_to\_region(region, x, y, z)

#### Usage

`move_to_region(25000, 6400.0, 800.0, 0.0)`

#### Returns

`None`


# Quests

## get\_quests()

Returns a dictionary of all active quests or `None` if you are not in game.

```
{
	616: {
		'type': 24,
		'name': 'Proof of Strength 2 (Hunter)',
		'npc': [26827],
		'servername': 'QNO_SD_GU_013',
		'objectives_completed': False,
		'completed': False
	},
	228: {
		'type': 24,
		'name': 'Undercloth Thief 3',
		'npc': [7538],
		'servername': 'QNO_CA_THIEF_3',
		'objectives_completed': False,
		'completed': False
	},
	613: {
		'type': 24,
		'name': 'Hunting in the Middle of the Temple Dispute 1 (Hunter)',
		'npc': [26827],
		'servername': 'QNO_SD_GU_010',
		'objectives_completed': False,
		'completed': False
	},
	614: {
		'type': 24,
		'name': 'Hunting in the Middle of the Temple Dispute 2 (Hunter)',
		'npc': [26827],
		'servername': 'QNO_SD_GU_011',
		'objectives_completed': False,
		'completed': False
	},
	615: {
		'type': 24,
		'name': 'Proof of Strength 1 (Hunter)',
		'npc': [26827],
		'servername': 'QNO_SD_GU_012',
		'objectives_completed': False,
		'completed': False
	}
}
```


# Drops

## get\_drops()

Returns a dictionary of all pickable items nearby (based on pick filter settings) or `None` if you are not in game. The dictionary `key` is the pick ID used for picking up an item.

```
{
	56720: {
		'name': 'White Silk',
		'servername': 'ITEM_ETC_TRADE_CH_01',
		'model': 2147,
		'region': 25000,
		'x': 6491.26513671875,
		'y': 999.5965576171875,
		'z': -0.01856626383960247,
		'can_pick': True,
		'blue': False,
		'plus': 0
	}
}
```


# Paths

This API allows you to use path finding to create a path to a destination. These functions can only be called once every 5 seconds.

## generate\_path(x, y)

#### Usage

`generate_path(-1207, 2332)`

#### Returns

`None` if the path could not be found, `False` if 5s have not passed / the character is not in game, or a `list` of `tuples` containing the walk path. Cave paths will have an extra field at position `0` in the tuple for the region. Teleporting is not supported.

```
[(-1183, 2299), (-1193, 2309), (-1202, 2320), (-1205, 2328)]
```

### generate\_script(region, x, y, z)

**Usage**

`generate_script(25000, 6432, 1095, 0)`

**Returns**

`None` if the path could not be found, `False` if 5s have not passed / the character is not in game, or a `list` of `strings` with the walk path including teleports and wait commands.

`['walk,3548,2068,0', 'walk,3543,2064,0', 'walk,3535,2076,0', 'walk,3540,2085,0', 'wait,5000', 'teleport,GATE_WC,GATE_CH', 'wait,5000', 'walk,6432,1096,0', 'walk,6432,1077,0', 'walk,6444,1062,0', 'walk,6453,1045,0', 'walk,6453,1026,0', 'walk,6442,1011,0', 'walk,6440,992,0', 'walk,6440,973,0', 'walk,6439,969,0', 'walk,6435,965,0', 'walk,6435,915,0', 'walk,6435,914,0', 'walk,6435,895,0', 'walk,6431,876,0', 'walk,6424,858,0', 'walk,6413,842,0', 'walk,6405,827,0', 'walk,6403,808,0', 'walk,6400,800,0']`


# Script

Executes a script

## start\_script(str)

Starts executing a script in the background.

#### **Example**

```
script = '''walk,6434,1094,-32
walk,6435,1087,-32
walk,6435,1078,-32
walk,6441,1072,-32
walk,6448,1056,-32
walk,6450,1044,-32
walk,6449,1035,-32
walk,6442,1030,-32
walk,6434,1026,-32
walk,6431,1026,-32
'''

start_script(script)
```

## stop\_script()

Stops executing a script.


# Notifications

These APIs allow you to add notifications to the log.

## create\_notification(string)

#### **Usage**

`create_notification('my notification')`

#### **Returns**

`True` if the notification has been added or `False` if it failed.

## create\_notification\_item(string, id)

This function will allow you to have an icon for an item show up in the notification window. The ID is the model of the item.

#### **Usage**

`create_notification('my notification', 69)`

#### **Returns**

`True` if the notification has been added or `False` if it failed.


# Alchemy

Controls alchemy through Python

## start\_alchemy

Starts alchemy

**Usage**

`start_alchemy()`

**Returns**

`True` or `False` if the function succeeded or not

## stop\_alchemy

Stops alchemy

**Usage**

`stop_alchemy()`

**Returns**

`True` or `False` if the function succeeded or not

## reset\_alchemy

Clears the alchemy queue

**Usage**

`reset_alchemy()`

**Returns**

`True` or `False` if the function succeeded or not

## add\_alchemy(dict)

Adds an item to the alchemy queue

**Usage**

```
add_alchemy({
    'type': 'plus',
    'slot': 13,
    'stop': 5,
    'success': 2000,
    'failure': 5000,
    'powder': 0,
    'astral': -1,
    'steady': -1,
    'immortal': -1,
    'lucky': -1,
    'stop_attempt': 100,
    'stop_destroyed': 1,
    'skip_fail': 0
})
```

**Returns**

`True` or `False` if the function succeeded or not

## alchemy\_update(slot, success, plus)

This event is sent to all plugins after an elixir is used on an item.

**Example**

`def alchemy_update(slot, success, plus):`


# Misc

Miscellaneous functions

## get\_version()

#### **Usage**

`get_version()`

#### **Returns**

Bot version as a string.

```
21.1.9
```

## select\_character(name)

Selects a character by its name.

#### **Usage**

`select_character('Character_Name')`

#### **Returns**

`None`

## set\_profile(name)

Changes the profile for the character.

#### **Usage**

`set_profile('name')`

#### **Returns**

`True` if the profile was changed otherwise `False`.

## get\_profile()

#### **Returns**

`string` with the profile name (can be empty for the default profile) or `None` if you are not logged in.

## disconnect()

Disconnects from the server. Does not change relog settings.

#### **Usage**

`disconnect()`

#### **Returns**

`None`

## show\_notification(title, message)

Shows a tray notification if the bot is minimized.

#### **Usage**

`show_notification('title', 'message')`

#### **Returns**

`True` if the arguments are correct.

`False` if the arguments are incorrect.

## play\_wav(path)

Plays a WAV file.

#### **Usage**

`play_wav('C:/my_wav_file.wav')`

#### **Returns**

`None`

## minimize() / unminize()

Minimizes or unminimizes the bot.

#### Usage

`minimize()`

`unminimize()`

#### Returns

`None`


# Chat API

## Chat

You must import `phBotChat` to use the chat API.

### All(text)

Sends a message to general chat.

### Party(text)

Sends a message to the party.

### Guild(text)

Sends a message to the guild.

### Union(text)

Sends a message to the union.

### Stall(text)

Sends a message to the stall.

### Private(name, text)

Sends a private message to another player.

### Note(name, text)

Sends a note to another player.

### Global(text)

Sends a global message.

### Notice(text)

Sends a GM notice to the server. This function should only ever be used if you are the GM of your own server. It should never be used as a normal player.

### ClientNotice(text)

Sends a GM notice to the client. This function is client side only.

#### Returns

`True` if the message was sent, `False` if sending the message failed.

#### Example

```
from phBot import *
import phBotChat
import QtBind

gui = QtBind.init(__name__, 'Chat Example')

name = QtBind.createLineEdit(gui, '', 10, 10, 100, 20)
text = QtBind.createLineEdit(gui, '', 10, 40, 250, 20)
send = QtBind.createButton(gui, 'send_message', 'Send', 10, 70)

def send_message():

    player = QtBind.text(gui, name)
    message = QtBind.text(gui, text)

    if len(player) > 0 and len(message) > 0:

        phBotChat.Private(player, message)

log('[%s] Loaded' % __name__)
```


# Handling Script Commands

## Handling Script Commands

By adding a custom command to your script, you can do something when it reaches it, with Python. It's easy to do and adds more functionality to scripts.

## Example

1. Add `do_something_here` your walk script
2. Add a `do_something_here(arguments)` function to your Python script

```
def do_something_here(arguments):
    log('%s' % arguments)
    return 0
```

* When the bot reaches `do_something_here` in your walk script, it will pass it over to your Python script. All script commands are passed to Python whether you have a function for it or not.
* The `return 0` is for how many milliseconds to sleep. This is necessary because the bot must lock the Python interpreter in order to keep everything thread safe. If you slept manually and another thread attempted to call one of your functions, it would block until you returned from the function and the global interpreter lock was released.

## Example Arguments

Arguments that get passed to your function must be comma separated in the walk script. They are then parsed into a `list` and sent to your Python script.

```
['walk', '6434', '1099', '-32']
```


# GUI API

`QtBind` is what I have decided to call my small Python -> Qt wrapper. It creates a translation layer between Python and C++ for the GUI.

[Example](http://plugins.phbot.org/example-plugin.html)

## gui init(ModuleName, TabName)

Initializes the GUI. Only call this when the module first loads. You must save the return value in order to create widgets on the interface. You must keep the module name as `__name__`. This is so GUI events are passed to the script.

## widget createButton(QtBind, CallBack, Text, X, Y)

Creates a button on the UI. The callback parameter is a string containing your function name.

## widget createCheckBox(QtBind, CallBack, Text, X, Y)

Creates a check box on the UI. The callback parameter is a string containing your function name. The callback will be passed the check state. True/False.

## widget createLabel(QtBind, Text, X, Y)

Creates a label on the UI.

## widget createLineEdit(QtBind, Text, X, Y, W, H)

Creates a line edit on the UI. To get the text a user has typed in the box, use the `text()` function.

## widget createList(QtBind, X, Y, W, H)

Creates a list widget on the UI. To get the current selected item text, use the `text()` function.

## widget createCombobox(QtBind, X, Y, W, H)

Creates a combox on the UI. To get the current selected item text, use the `text()` function.

## setText(QtBind, Widget, Text)

Sets the text of a widget.

## setChecked(QtBind, Widget, State)

Sets the checked state of a check box.

## string text(QtBind, Widget)

Returns the text of a widget. Or returns the current selected item text in a list widget.

## destroy(QtBind, Widget)

Destroys a widget.

## move(QtBind, Widget, X, Y)

Moves a widget.

## boolean isChecked(QtBind, Widget)

Returns the checked state of a check box. Do **NOT** call this function on anything but a check box!

## clear(QtBind, Widget)

Erases the text in a widget or clears the entire widget if it is a list widget.

## append(QtBind, Widget, text)

Appends text to a list widget.

## int currentIndex(QtBind, Widget)

Returns the currently selected index of a list widget.

## remove(QtBind, Widget, text)

Removes all items with the value specified in a list widget.

## removeAt(QtBind, Widget, index)

Removes an item at a specified index in a list widget.

## getItems(QtBind, Widget)

Returns a list of all items in a list widget.


