Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 1 addition & 10 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,7 @@ on:
- master
paths:
- 'src/**'
- 'Dockerfile'
- '.github/workflows/deploy.yaml'
- 'poetry.lock'

pull_request:
types: [opened, reopened]
paths:
- 'src/**'
- '!src/_version.py'
- 'Dockerfile'
- '.github/workflows/deploy.yaml'
- 'poetry.lock'
Expand Down Expand Up @@ -61,8 +54,6 @@ jobs:
echo "branch=${{ inputs.branch-override }}" >> $GITHUB_OUTPUT
elif [[ "${GITHUB_EVENT_NAME}" == "push" ]]; then
echo "branch=${{ github.ref_name }}" >> $GITHUB_OUTPUT
elif [[ "${GITHUB_EVENT_NAME}" == "pull_request" ]]; then
echo "branch=${{ github.head_ref }}" >> $GITHUB_OUTPUT
elif [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then
echo "branch=${{ github.ref_name }}" >> $GITHUB_OUTPUT
else
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/increment-version-dev.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
name: Increment Version (develop)
on:
push:
paths: 'src/**'
paths: |
- 'src/**'
- '!src/_version.py'

branches:
- 'develop'

Expand Down
32 changes: 32 additions & 0 deletions .github/workflows/pr-open.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,35 @@ jobs:
_Parsed data in [deadlock-data PR](${{ steps.create_data_pr.outputs.pr_url }}) - Reopen deadbot PR or run deploy workflow for this branch [here](https://github.com/deadlock-wiki/deadbot/actions/workflows/deploy.yaml) to reparse the data_"

gh pr edit ${{ github.event.number }} --body "$new_body"

check-deploy-paths:
name: Check deploy paths
runs-on: ubuntu-latest
needs: open-data-pr
outputs:
should_deploy: ${{ steps.filter.outputs.should_deploy }}
steps:
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
should_deploy:
- 'src/!(_version.py)'
- 'src/!(_version.py)/**'
- 'Dockerfile'
- '.github/workflows/deploy.yaml'
- 'poetry.lock'

trigger-deploy:
name: Trigger Deploy
needs: [open-data-pr, check-deploy-paths]
if: ${{ github.head_ref != 'develop' && github.head_ref != 'master' && needs.check-deploy-paths.outputs.should_deploy == 'true' }}
uses: ./.github/workflows/deploy.yaml
with:
branch-override: ${{ github.head_ref }}
english-only: false
secrets:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
STEAM_USERNAME: ${{ secrets.STEAM_USERNAME }}
STEAM_PASSWORD: ${{ secrets.STEAM_PASSWORD }}
BOT_WIKI_PASS: ${{ secrets.BOT_WIKI_PASS }}
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "Deadbot"
version = "1.13.2"
version = "1.14.0"
description = "Bot that lives to serve deadlock.wiki"
readme = "README.md"
authors=[]
Expand Down
2 changes: 1 addition & 1 deletion src/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '1.13.2'
__version__ = '1.14.0'
21 changes: 21 additions & 0 deletions src/parser/maps.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,27 @@ def get_ability_activation(value):
return ABILITY_ACTIVATION_MAP.get(value)


def get_behaviour_bits(value):
"""Split a '|'-delimited behaviour bits string into a PascalCased list.

Each flag has its CITADEL_ABILITY_ prefix stripped, e.g.
"CITADEL_ABILITY_BEHAVIOR_MOVEMENT | CITADEL_ABILITY_BEHAVIOR_DEACTIVATE_CROUCH_TOGGLE_ON_CAST"
-> ['BehaviorMovement', 'BehaviorDeactivateCrouchToggleOnCast']
"""
if not value:
return None

bits = []
for token in value.split('|'):
token = token.strip()
if not token:
continue
if token.startswith('CITADEL_ABILITY_'):
token = token[len('CITADEL_ABILITY_') :]
bits.append(''.join(part.capitalize() for part in token.split('_') if part))
return bits


# i.e. ECitadelStat_Vitality -> Vitality
def get_attr_group(value):
return value.split('ECitadelStat_')[1]
Expand Down
9 changes: 9 additions & 0 deletions src/parser/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
npc_units,
game_map,
misc,
convars,
)
from utils import json_utils
from loguru import logger
Expand Down Expand Up @@ -148,6 +149,7 @@ def run(self):
self._parse_soul_unlocks()
self._parse_generics()
self._parse_misc()
self._parse_convars()
self._parse_map()
logger.trace('Done parsing')

Expand Down Expand Up @@ -313,3 +315,10 @@ def _parse_misc(self):
parsed_misc = misc.MiscParser(self.data['scripts']['misc']).run()

json_utils.write(self.OUTPUT_DIR + '/json/misc-data.json', json_utils.sort_dict(parsed_misc))

def _parse_convars(self):
logger.trace('Parsing Convars...')
convars_file = os.path.join(self.game_dir, 'DumpSource2', 'convars.txt')
parsed_convars = convars.ConvarsParser(convars_file).run()

json_utils.write(self.OUTPUT_DIR + '/json/convars.json', json_utils.sort_dict(parsed_convars))
1 change: 1 addition & 0 deletions src/parser/parsers/abilities/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ def _parse_ability(self, ability_key):
'Key': ability_key,
'Name': self.localizations.get(ability_key, None),
'IsDisabled': ability.get('m_bDisabled', False),
'BehaviourBits': maps.get_behaviour_bits(ability.get('m_AbilityBehaviorsBits')),
}

stats = ability.get('m_mapAbilityProperties', {})
Expand Down
101 changes: 101 additions & 0 deletions src/parser/parsers/convars.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
class ConvarsParser:
"""
Parses the game-wide convars dump (DumpSource2/convars.txt) into a dict
keyed by convar name. Each entry is either the bare type-coerced value, or
a {"value", "description"} object when the convar has a description.

Each record in the source file spans:
<name> <value> (<flags>)
<description> # tab-indented, may span multiple lines
<blank line>

The literal "<no description>" is normalised to an empty string, and the
trailing "(<flags>)" group is dropped. Values that are quoted in the source
are kept as strings; unquoted values are coerced to bool/int/float when
possible, otherwise left as strings.
"""

NO_DESCRIPTION = '<no description>'

def __init__(self, convars_file):
self.convars_file = convars_file

def run(self):
with open(self.convars_file, 'r', encoding='utf-8') as f:
lines = f.read().splitlines()

convars = {}
i = 0
total = len(lines)
while i < total:
line = lines[i]

if line == '' or line[0] in (' ', '\t'):
i += 1
continue

name, value = self._parse_definition(line)

i += 1
description_lines = []
while i < total and lines[i].startswith('\t'):
description_lines.append(lines[i].strip())
i += 1

# Skip debug convars - not useful for the wiki
if 'debug' in name.lower():
continue

# Skip convars with an empty string value (but keep falsy
# values like 0 and false, which are meaningful)
if isinstance(value, str) and value == '':
continue

description = ' '.join(description_lines).strip()
if description == self.NO_DESCRIPTION:
description = ''

# Only wrap in an object when there's a description to carry;
# otherwise store the bare value directly under the convar name
if description:
convars[name] = {'value': value, 'description': description}
else:
convars[name] = value

return convars

def _parse_definition(self, line):
"""Split a definition line into (name, coerced_value), dropping flags."""
name, _, rest = line.partition(' ')

# Flags are the trailing "(...)" group; drop everything from the last
# opening paren onward. Descriptions can contain parens, but they live
# on separate indented lines, so this only ever sees the flags group.
paren_index = rest.rfind('(')
if paren_index != -1:
rest = rest[:paren_index]

return name, self._coerce(rest.strip())

def _coerce(self, raw):
"""Coerce an unquoted value to bool/int/float; keep quoted as string."""
# Explicitly quoted in the dump -> treat as a string (e.g. "value")
if len(raw) >= 2 and raw[0] == '"' and raw[-1] == '"':
return raw[1:-1]

if raw == 'true':
return True
if raw == 'false':
return False

try:
return int(raw)
except ValueError:
pass

try:
return float(raw)
except ValueError:
pass

return raw
1 change: 1 addition & 0 deletions src/wiki/pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
'ResourceLookup.json': 'json/resource-lookup.json',
'MidtownMetadata.json': 'json/midtown-metadata.json',
'MiscData.json': 'json/misc-data.json',
'Convars.json': 'json/convars.json',
}

# Ignore these pages as they are not automated
Expand Down