Git Product home page Git Product logo

pob_wrapper's Introduction

Path of Building Wrapper

Allows use of an existing Path of Building installation from a Python application. If you don't know Path of Building is then you don't play Path of Exile and can safely ignore this.

This is simple initial implementation with limited functionality, but provides a base to build on.

Features

  • Launch PoB in headless mode as a controllable sub-processes
  • Load builds
  • Read basic build information
  • Updates builds (from pathofexile.com) and attempts to maintain chosen skill
  • Test the effect of items (output as HTML)
  • Test the effect of individual mod lines (output as diffs to all output stats)

Example

(taken from example.py)

Fire up Path of Building as a headless sub-process:

pob_install = r'D:\Programs\PathOfBuilding'
pob_path = r'D:\Programs\PathOfBuilding' # or `%ProgramData%\Path of Building` for installed version
pob = PathOfBuilding(pob_path, pob_install)

Ask where the builds are stored:

builds_path = pob.get_builds_dir()

...returns C:\Users\<username>\Documents\My Games\Path of Exile\Builds/

Load a build and get its basic info:

pob.load_build(rf'{builds_path}\Experiment\ZioniclesExperiment.xml')
build_info = pob.get_build_info()

Returns:

{'buildName': 'ZioniclesExperiment',
 'char': {'ascendClassName': 'Ascendant', 'className': 'Scion', 'level': 89},
 'file': {'path': 'C:\\Users\\<username>\\Documents\\My Games\\Path of '
                  'Exile\\Builds/\\Experiment\\ZioniclesExperiment.xml',
          'subpath': '\\Experiment\\'}}

Test the effect of a single mod line:

mod = "10% increased Intelligence"
effects = pob.test_mod_effect(mod)

Returns:

{'AverageDamage': 4114.275,
 'AverageHit': 4114.275,
 'Duration': 0.2175,
 'EnergyShield': 311.0,
...

Test the effects of a new item, outputting as HTML:

item = '''
Rarity: Rare
Hypnotic Circle
Opal Ring
--------
24% increased Elemental Damage (implicit)
--------
+48 to Intelligence
--------
Note: ~price 40 exa
'''
Path('test-item1.html').write_text(pob.test_item_as_html(item))

...produces something like the page below, although any item copied from a trade website will be handled.

Item test output

Things to improve

  • Detect where PoB was installed and/or where its data is (ProgramData).
  • Provide access to more build & skill data

pob_wrapper's People

Contributors

coldino avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

pob_wrapper's Issues

Not working with PoB Community 1.4.170.12

Hi! Looks like the latest PoBC has broken something :-(
The first thing I noticed is that get_builds_dir() seems to be getting a relative path to the builds dir now:

C:\Users\Nighty\Downloads\pob_wrapper-master>python example.py
LUA: Started

POB Builds: ./Path of Building/Builds/

Loading build:
{'buildName': 'ED 03',
 'char': {'ascendClassName': 'Scion', 'className': 'Scion', 'level': 1},
 'file': {'path': './Path of Building/Builds/\\ED 03.xml', 'subpath': '\\'}}

Updating build:
Traceback (most recent call last):
  File "example.py", line 63, in <module>
    pob = run()
  File "example.py", line 44, in run
    pob.update_build()
  File "C:\Users\Nighty\Downloads\pob_wrapper-master\pob_wrapper\pob.py", line 96, in update_build
    result = self._send(f'updateBuild()')
  File "C:\Users\Nighty\Downloads\pob_wrapper-master\pob_wrapper\pob.py", line 148, in _send
    raise ExternalError(result)
pob_wrapper.process_wrapper.ExternalError: {'status': 'run_fail', 'error': "...ty\\Downloads\\pob_wrapper-master\\pob_wrapper\\data\\cli.lua:59: attempt to index local 'socketGroup' (a nil value)"}

Feeding it the correct path does this:

C:\Users\Nighty\Downloads\pob_wrapper-master>python example.py
LUA: Started

POB Builds: ./Path of Building/Builds/

Loading build:
{'buildName': 'ED 03',
 'char': {'ascendClassName': 'Trickster', 'className': 'Shadow', 'level': 83},
 'file': {'path': 'C:\\Users\\Nighty\\Documents\\Path of Building\\Builds\\ED '
                  '03.xml',
          'subpath': 'Path of Building\\Builds\\'}}

Updating build:
Traceback (most recent call last):
  File "example.py", line 63, in <module>
    pob = run()
  File "example.py", line 44, in run
    pob.update_build()
  File "C:\Users\Nighty\Downloads\pob_wrapper-master\pob_wrapper\pob.py", line 96, in update_build
    result = self._send(f'updateBuild()')
  File "C:\Users\Nighty\Downloads\pob_wrapper-master\pob_wrapper\pob.py", line 148, in _send
    raise ExternalError(result)
pob_wrapper.process_wrapper.ExternalError: {'status': 'run_fail', 'error': '...ty\\Downloads\\pob_wrapper-master\\pob_wrapper\\data\\cli.lua:72: Account name not configured'}

For completeness, these are the lines I changed in example.py to make it work on my system:

    ...
    pob_install = r'C:\Program Files (x86)\Path of Building Community'
    pob_path = r'C:\Program Files (x86)\Path of Building Community'
    ...
    pob.load_build(r'C:\Users\Nighty\Documents\Path of Building\Builds\ED 03.xml')
    ...

ModuleNotFoundError: No module named 'pob_wrapper'

When I try to run the example, I get the above error. Any idea how to solve this? The following functions throws the error:

def get_provider(moduleOrReq):
                """Return an IResourceProvider for the named module or requirement"""
                if isinstance(moduleOrReq, Requirement):
                    return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0]
                try:
                    module = sys.modules[moduleOrReq]
                except KeyError:
                    __import__(moduleOrReq)
                    module = sys.modules[moduleOrReq]
                loader = getattr(module, '__loader__', None)
                return _find_adapter(_provider_factories, loader)(module) 

Modules/DataLegionLookUpTableHelper.lua:287: Error occurred loading Glorious Vanity data

Hi, trying to run PathOfBuilding(path, path) gives me this error

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\aria\projects\pythtest\pob_wrapper\pob_wrapper\pob.py", line 108, in __init__
    raise ChildProcessError((stdin or '') + (stderr or ''))
ChildProcessError:
^0In 'OnFrame': Modules/DataLegionLookUpTableHelper.lua:287: Error occurred loading Glorious Vanity data
^8v2.37.0 master
^0Press Enter/Escape to dismiss, or F5 to restart the application.
stack traceback:
        [C]: in function 'error'
        ...rojects\pythtest\pob_wrapper\pob_wrapper\data\mockui.lua:233: in main chunk
        [C]: in function 'require'
        ...a\projects\pythtest\pob_wrapper\pob_wrapper\data\cli.lua:11: in main chunk
        [C]: at 0x004020f0

path = C:\Users\aria\AppData\Roaming\Path of Building Community

POB version 2.37.0

Several functions in example.py return errors with null value.

Platform: Win10

IDE: Visual Code
POB: Community-Portable-1.4.170.26 (released at 9th Feb,2021)
Python: 3.9.4

Issues:
Example functions trigger fatal errors.

Here's order in example.py :

  • get_builds_dir()--------(√)
  • load_build(rf'{builds_path}\AnalysisBuilder.xml')--------(√)
  • get_build_info()--------(√)
  • update_build()--------(√)
  • pob.fetch('build.spec.curAscendClassName')--------(√)
  • mod = "10% increased Intelligence"--------(√)
  • print('\nTesting single mod effects:', mod)--------(√)
  • pprint(pob.test_mod_effect(mod)) --------(×)
  • Path('test-item1.html').write_text(pob.test_item_as_html(TEST_ITEM_1)) --------(×)

Screen shot:
screenshot

looks like "modlist" is a nil value

Full output:

POB Builds: C:\Users\kwang\Desktop\PathOfBuildingCommunity-Portable-1.4.170.26/Builds/

Loading build:
{'buildName': 'PathOfBuildingCommunity-Portable-1.4.170.26/Builds/\\AnalysisBuilder',
 'char': {'ascendClassName': 'Chieftain',          'className': 'Marauder',       
          'level': 100},
 'file': {'path': 'C:\\Users\\kwang\\Desktop\\PathOfBuildingCommunity-Portable-1.4.170.26/Builds/\\AnalysisBuilder.xml',   
          'subpath': ''},
 'skill': {'group': 'Vaal Ancestral Warchief', 'name': 'Ancestral Warchief'}}     

Updating build:
Lua: Skill group/gem/part: Vaal Ancestral Warchief / Ancestral Warchief / -       
Lua: Pre-update checks...

Fetch data directly from Lua:
  build.spec.curAscendClassName = 'Chieftain'

Testing single mod effects: 10% increased Intelligence
Lua: Testing mod: 10% increased Intelligence
Traceback (most recent call last):
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.1264.0_x64__qbz5n2kfra8p0\lib\runpy.py", line 
197, in _run_module_as_main
    return _run_code(code, main_globals, 
None,
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.1264.0_x64__qbz5n2kfra8p0\lib\runpy.py", line 
87, in _run_code
    exec(code, run_globals)
  File "c:\Users\kwang\.vscode\extensions\ms-python.python-2021.3.680753044\pythonFiles\lib\python\debugpy\__main__.py", line 45, in <module>
    cli.main()
  File "c:\Users\kwang\.vscode\extensions\ms-python.python-2021.3.680753044\pythonFiles\lib\python\debugpy/..\debugpy\server\cli.py", line 444, in main
    run()
  File "c:\Users\kwang\.vscode\extensions\ms-python.python-2021.3.680753044\pythonFiles\lib\python\debugpy/..\debugpy\server\cli.py", line 285, in run_file
    runpy.run_path(target_as_str, run_name=compat.force_str("__main__"))
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.1264.0_x64__qbz5n2kfra8p0\lib\runpy.py", line 
268, in run_path
    return _run_module_code(code, init_globals, run_name,
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.1264.0_x64__qbz5n2kfra8p0\lib\runpy.py", line 
97, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.1264.0_x64__qbz5n2kfra8p0\lib\runpy.py", line 
87, in _run_code
    exec(code, run_globals)
  File "c:\Users\kwang\Desktop\pob_wrapper\example.py", line 62, in <module>      
    pob = run()
  File "c:\Users\kwang\Desktop\pob_wrapper\example.py", line 51, in run
    pprint(pob.test_mod_effect(mod))     
  File "c:\Users\kwang\Desktop\pob_wrapper\pob_wrapper\pob.py", line 139, in test_mod_effect
    result = self._send(f'findModEffect("{mod_line}")')
  File "c:\Users\kwang\Desktop\pob_wrapper\pob_wrapper\pob.py", line 161, in _send    raise ExternalError(result)
pob_wrapper.pob.ExternalError

if you need more info, plz let me know :)

Program does not execute due to process_wrapper.py

Hey,

I can start the program now, but it gets stuck in file process_wrapper.py in this line:

class ProcessWrapper:
    '''Starts a sub-process that can be used in a simple question/response pattern.'''
    process: Popen

    receive_msg_fn = lambda self, msg: print("Lua: " + msg if msg else '', end='')

    def __init__(self, debug=False):
        self.debug = debug and True

    def start(self, args: List[str], cwd=None):
        cwd = cwd or os.getcwd()
        self.process = Popen(args, stdin=PIPE, stdout=PIPE, stderr=sys.stderr, universal_newlines=True, cwd=cwd, bufsize=1)
        firstline = self.process.stdout.readline() <<<<<<< 
        if firstline == '': raise EOFError("Unable to start subprocess")
        if self.debug: print('===', firstline)

It doesn't throw any error, but the program simply does not continue. Do have any ideas why this might happen?

Problems on Linux

When deploying my app with this wrapper on Linux, the app would get stuck forever. After a lot of digging I've came to a conclusion that the problem is with lcurl - it won't load on Linux.

All I had to do was to uncomment this:

-- l_require = require
-- function require(name)
-- 	-- Hack to stop it looking for lcurl, which we don't really need
-- 	if name == "lcurl.safe" then
-- 		return
-- 	end
--     return l_require(name)
-- end

I've also removed functions that were doing some web stuff (DownloadPage and CheckForUpdate). In my use case I don't need those anyway.

Also, make sure that the PoB installation doesn't contain Settings.xml file - it might contain a file path. If its Windows path - it would break as well.

Just dropping those notes in here just in case someone would have similar issues.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.