Skip to content

Commit

Permalink
Feature: Create parser and minimal dashboard (#1)
Browse files Browse the repository at this point in the history
* Add python workflows

* Add README.md

* Fix whitespacing

* Add existing memory files in yaml format

* Add Building class to manage building related tasks

* Read one memory chunk per cycle and add method to calculate building related stats

* Add minimal state machine to detect crusader gamestate

* Add functions to read single and bulk values from memory

* Add Stronghold images

* Add stat memory addresses of each lord

* Add a namelist for buildings and units

* Add memory addresses for entities

* Renaming module to parser

* Add tests folder

* Fix functions only reading first byte and add dtype parameter

* Setup module variables

* Setup logging for project

* Adjust data types for memory reading

* Create class to read all lord specific stats

* Create class to read all units and calculate basic unit statistics

* Add some css color definitions

* Create app for web dashboard

* Update pre-commit checks

* Add isort and gitleaks to pre-commit checks

* Add callbacks to read data from memory and store in app

* Add callbacks to plot graphs from stored data

* Add callbacks to handle UI changes

* Add main page

* Start app on module execution

* Add db folder
  • Loading branch information
joschrag authored Dec 20, 2024
1 parent 7b76403 commit 523c22f
Show file tree
Hide file tree
Showing 88 changed files with 2,127 additions and 19 deletions.
41 changes: 41 additions & 0 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python

name: Pytest and flake8 linting

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
build:

runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.12"]

steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install poetry
poetry lock
poetry install --with dev
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
poetry run python -m flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
poetry run python -m flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
run: |
poetry run python -m pytest
47 changes: 28 additions & 19 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/ambv/black
rev: 24.4.2
hooks:
- id: black
language_version: python3.12
- repo: https://github.com/PyCQA/flake8
rev: 7.1.0
hooks:
- id: flake8
language_version: python3.12
- repo: https://github.com/pre-commit/mirrors-mypy
rev: 'v1.10.0' # Use the sha / tag you want to point at
hooks:
- id: mypy
language_version: python3.12
additional_dependencies: [types-PyYAML==6.0.12.*]
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/ambv/black
rev: 24.10.0
hooks:
- id: black
language_version: python3.12
- repo: https://github.com/PyCQA/flake8
rev: 7.1.1
hooks:
- id: flake8
language_version: python3.12
- repo: https://github.com/pre-commit/mirrors-mypy
rev: "v1.13.0" # Use the sha / tag you want to point at
hooks:
- id: mypy
language_version: python3.12
additional_dependencies: [types-PyYAML==6.0.12.*]
- repo: https://github.com/pycqa/isort
rev: 5.13.2
hooks:
- id: isort
name: isort (python)
- repo: https://github.com/gitleaks/gitleaks
rev: v8.21.3
hooks:
- id: gitleaks
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Stronghold Crusader Dashboard

## What is this project about?

Stronghold Crusader Dashboard is a python based CLI and dashboard app designed to track and visualize Stronghold Crusader Extreme statistics.

[Stronghold Crusader Extreme](https://fireflyworlds.com/games/strongholdcrusader/) is a real time strategy game made by Firefly Studios.
While the game does feature a stats screen after each match, it does miss more modern features like a graph of stats over time and some deeper statistics. This project aims to provide easily explorable stat tracking for your Stronghold Crusader Extreme matches.

## Project Inspiration

This project is inspired by the constant work and videos from [Udwin](https://www.youtube.com/@Udwin), [Krarilotus](https://www.youtube.com/@Krarilotus), [Xander10alpha](https://www.youtube.com/@Xander10alpha) and many more.
Most of the work figuring out the memory adresses was already done in other [projects](https://github.com/patel-nikhil/SHCLiveStatReader) by [patel-nikhil](https://github.com/patel-nikhil) and others.

## Disclaimer

Stronghold Crusader is the legal property of Firefly Studios. This project has no affiliation and is not endorsed or supported by Firefly Studios. This content provided in this project does not modify the executable or other game files in any way.
4 changes: 4 additions & 0 deletions db/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# db folder

This folder will contain the db.sqlite file.
The db.sqlite file will be automatically be created at module initilization.
Binary file added img/Image253.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image254.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image255.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image264.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image570.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image620.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image622.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image624.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image628.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image632.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image634.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image636.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image638.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image640.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image642.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image644.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image646.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image648.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image650.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image652.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image654.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image656.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image658.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image660.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image662.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Image664.png
Binary file added img/Image730.png
Binary file added img/ST03_Woodcutters_Hut.png
Binary file added img/ST05_Iron_Mine.png
Binary file added img/ST06_Pitch_Digger.png
Binary file added img/ST20_Quarry.png
Binary file added img/ST26_Tradepost.png
Binary file added img/armys1.png
Binary file added img/armys10.png
Binary file added img/armys11.png
Binary file added img/armys12.png
Binary file added img/armys13.png
Binary file added img/armys14.png
Binary file added img/armys15.png
Binary file added img/armys16.png
Binary file added img/armys17.png
Binary file added img/armys18.png
Binary file added img/armys19.png
Binary file added img/armys2.png
Binary file added img/armys20.png
Binary file added img/armys21.png
Binary file added img/armys22.png
Binary file added img/armys23.png
Binary file added img/armys24.png
Binary file added img/armys25.png
Binary file added img/armys26.png
Binary file added img/armys3.png
Binary file added img/armys4.png
Binary file added img/armys5.png
Binary file added img/armys6.png
Binary file added img/armys7.png
Binary file added img/armys8.png
Binary file added img/armys9.png
Binary file added img/contents07_town_buildings.png
Binary file added img/null_sketch.png
11 changes: 11 additions & 0 deletions memory/building.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
address: 0x00F98DB2
type: integer
category: building
offsets:
owneroffset: 0x4
workersneededoffset: 0xC6
workersworkingoffset: 0xC8
workersmissingoffset: 0xCA
snoozedoffset: 0x1C4
offset: 0x32C
total: 0x00F989A0
90 changes: 90 additions & 0 deletions memory/greatestlord.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
Map:
MapName:
address: 0x24B649C
type: string
MapStartYear:
address: 0x24BA938
type: integer
MapStartMonth:
address: 0x24BA93C
type: byte
MapEndYear:
address: 0x24BA940
type: integer
MapEndMonth:
address: 0x24BA944
type: byte
AdvantageSetting:
address: 0x24B7F4C
type: byte
Player:
Active:
address: 0x24BA557
type: boolean
category: other
offset: 0x1
Name:
address: 0x24BA286
type: string
category: other
offset: 0x5A
Team:
address: 0x24BAAB6
type: byte
category: other
offset: 0x1
Gold:
address: 0x24BA564
type: integer
category: other
offset: 0x4
Units:
address: 0x24BA888
type: integer
category: military
offset: 0x4
WeightedTroopsKilled:
address: 0x24BA840
type: integer
category: military
offset: 0x4
WeightedBuildingsDestroyed:
address: 0x24BA864
type: integer
category: military
offset: 0x4
LordKills:
address: 0x24BA7EA
type: byte
category: military
offset: 0x1
Food:
address: 0x24BA730
type: integer
category: resource
offset: 0x4
Wood:
address: 0x24BA79C
type: integer
category: resource
offset: 0x4
Stone:
address: 0x24BA778
type: integer
category: resource
offset: 0x4
Weapons:
address: 0x24BA7F8
type: integer
category: resource
offset: 0x4
GoodsSent:
address: 0x24BA8D0
type: integer
category: resource
offset: 0x4
GoodsReceived:
address: 0x24BA8AC
type: integer
category: resource
offset: 0x4
178 changes: 178 additions & 0 deletions memory/lord.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
map_offsets:
offset: 0x0
memory:
- address: 0x24b649c
stat_offsets:
- name: map_name
offset: 0x0
type: string
lord_basic_offsets:
offset: 0x1
memory:
- address: 0x24ba557
stat_offsets:
- name: active
offset: 0x0
type: boolean
- name: team
offset: 0x55f
type: byte
lord_global_offsets:
offset: 0x4
memory:
- address: 0x11f5ab0
stat_offsets:
- name: num_eco_buildings
offset: 0x0
type: int
- name: num_total_buildings
offset: 0x9dccc
type: int
- address: 0x24ba564
stat_offsets:
- name: total_gold
offset: 0x0
type: int
- name: weighted_troops_killed
offset: 0x2dc
type: int
- name: weighted_buildings_destroyed
offset: 0x300
type: int
- name: goods_received
offset: 0x348
type: int
- name: goods_sent
offset: 0x36c
type: int
lord_name_offsets:
offset: 0x5a
memory:
- address: 0x24ba286
stat_offsets:
- name: name
offset: 0x0
type: string
lord_stat_offsets:
offset: 0x39f4
memory:
- address: 0x11f24a0
stat_offsets:
- name: housing
offset: 0x0
type: word
- name: units
offset: 0x344
type: int
- name: siege_engines
offset: 0x348
type: int
- name: popularity
offset: 0x3d0
type: word
- name: wood
offset: 0x464
type: int
- name: hops
offset: 0x468
type: int
- name: stone
offset: 0x46c
type: int
- name: iron
offset: 0x474
type: int
- name: pitch
offset: 0x478
type: int
- name: wheat
offset: 0x480
type: int
- name: bread
offset: 0x484
type: int
- name: cheese
offset: 0x488
type: int
- name: meat
offset: 0x48c
type: int
- name: apples
offset: 0x490
type: int
- name: ale
offset: 0x494
type: int
- name: gold
offset: 0x498
type: int
- name: flour
offset: 0x49c
type: int
- name: bows
offset: 0x4a0
type: int
- name: crossbows
offset: 0x4a4
type: int
- name: spears
offset: 0x4a8
type: int
- name: pikes
offset: 0x4ac
type: int
- name: maces
offset: 0x4b0
type: int
- name: swords
offset: 0x4b4
type: int
- name: leather_armor
offset: 0x4b8
type: int
- name: metal_armor
offset: 0x4bc
type: int
- address: 0x11f44c8
stat_offsets:
- name: total_food
offset: 0x0
type: int
- name: population
offset: 0xe4
type: word
- name: taxes
offset: 0xec
type: int
- name: weighted_losses
offset: 0x204
type: int
- name: ale_coverage
offset: 0x208
type: int
- name: num_inns
offset: 0x234
type: int
# - name: working_woodcutters
# offset: 0xa80
# type: int
- name: num_bakery
offset: 0xaf4
type: int
- address: 0x11f5d14
stat_offsets:
- name: weighted_units
offset: 0x0
type: int
- name: num_farms
offset: 0x40
type: int
- name: num_iron_mines
offset: 0xa4
type: int
- name: num_pitchrigs
offset: 0xa8
type: int
- name: num_quarries
offset: 0xac
type: int
Loading

0 comments on commit 523c22f

Please sign in to comment.