Code Monkey home page Code Monkey logo

rpg-bonhomme's Introduction

A tabletop RPG character sheet editor & viewer.

build status Known Vulnerabilities

Features:

  • web-based : only require a web browser for end users
  • characters are read-only by default; editing is only allowed with a unique URL generated on character creation
  • can support character sheets from any game, simply by adding a new background image and matching CSS stylesheet
  • easily deployable on your own server, and also usable locally with no Internet connexion
  • locally load & save your character from JSON files, or save it on a remote server
  • technical: WSGI Python app implementing a JSONP key-value store backed by SQLite

Online website & examples

Homepage

Supported games:

Some character examples from home-made TTRPGs:

Usage

All the interactions are made using the 4 top right buttons and the 'name' input field.

To remote load an existing character, simply go to https://chezsoi.org/lucas/rpg-bonhomme?layout= and type a layout name at the end of URL, then enter your character name and press 'Load from remote server'. Alternatively you can directly enter an URL formatted like this: '?layout=&name='.

To edit and remote save a new character, simply go to https://chezsoi.org/lucas/rpg-bonhomme?layout= and type a layout name at the end of the URL, then enter your character name and press the 'Save to remote server' button.

The currently available layouts matches the list of file in the layout/ & background/ directories of this repository.

Internals & asumptions

  • a ?layout= URL parameter provided to index.html allows to select the character sheet.
  • this layout must match the name of a .css file in the layout/ directory, and a .png character sheet image in background/.
  • input (or textarea) form fields are defined once and only once by rules starting with input#<name> in the $layout.css files, and they must be the only selectors starting that way in the file. Non-textual form fields must be specified as input[type=.+]#<name>
  • the layout.css file ****MUST define a text input with id #name.
  • (up)loading a new character currently only replace inputs defined in the provided file, non-redefined caracteristics will keep their old value.

jsonp_db

This is a simple key-value store, written in Python and using a SQLite DB, developped to allow simple GET/PUT through JSONP.

If the key is not found, the returned value will be undefined. Else the API will returns the matching value or an error if anything wrong happens (a JS Error object if using JSONP, else an HTML error page).

There are some key/value length limitations currently hardcoded at the top of the Python file. uwsgi --buffer-size parameter also limits the URI length, and hence the value size. Beware of your server limitation on the request URI (between 2KB & 8KB usually), that can e.g. trigger a 414 error with Apache.

Finally, a word of warning: trusting a 3rd party JSONP API is a big confidence commitment / security risk. More details here.

That being said, this WSGI app won't do anything nasty.

Environment setup

Installing a Python virtualenv and the needed dependencies with pew :

pew new rpg-bonhomme -p python3
make install

Deployment

Initial configuration & file permissions:

echo modification_key_salt = $(strings /dev/urandom | grep -o '[[:alnum:]]' | head -n 30 | tr -d '\n') >> jsonp_db.ini
sqlite3 jsonp_db.db 'CREATE TABLE KVStore(Key TEXT PRIMARY KEY, Value TEXT);'
chmod ugo+rw jsonp_db.db

Installing the backup cron task:

sudo sed -e "s~\$USER~$USER~" -e "s~\$PWD~$PWD~g" jsonp_db-crons > /etc/cron.d/jsonp_db-crons
chmod u+x /etc/cron.d/jsonp_db-crons

Installing uwsgi:

pew-in rpg-bonhomme pip install -r prod-requirements.txt

For Apache

With mod_wsgi, simply:

sudo -u www-data bash -c "source /var/www/apache-python-venv/bin/activate && pip install configobj requests"

And the Apache httpd.conf:

WSGIScriptAlias /path/to/jsonp_db /path/to/jsonp_db.py

For Nginx

cat << EOF | sudo tee /etc/init/rpg-bonhomme.conf
start on startup
script
    set -o errexit -o nounset -o xtrace
    cd $PWD
    exec >> upstart-stdout.log
    exec 2>> upstart-stderr.log
    date
    pew-in rpg-bonhomme uwsgi --buffer-size 64000 --http :8088 --static-map /=. --manage-script-name --mount /jsonp_db=jsonp_db.py
end script
EOF
service rpg-bonhomme start

And the Nginx configuration:

# Required to handle very long query parameters:
http2_max_field_size 64k;
large_client_header_buffers 4 64k;

location /jsonp_db {
    include uwsgi_params;
    rewrite ^/jsonp_db(.*)$ $1 break;
    proxy_pass http://127.0.0.1:8088;
}
location /jsonp_db-tests.ini {
    deny all;
}

Note that nginx has built-in limits on the HTTP headers length, that may cause rpg-bonhomme to malfunction. Hence we configure higher values for http2_max_field_size and large_client_header_buffers.

Validating

make check
make test

Developping

Require a jsonp_db.db:

make
make run-server

Useful shell functions

Retrieving a modification key

function get_mod_key () {
    local layout="${1?}"
    local char_name="${2?}"
    python -c "from jsonp_db import get_modification_key;print('&modification-key='+get_modification_key('${layout}_'+'${char_name}'.lower()))"
}

Changing an avatar

function avatar_chg () {
    local key="${1?}"
    local img="${2?}"
    python -c "import json;from jsonp_db import db_get,db_put;k='$key';v=json.loads(db_get(k));v['avatar']='$img';db_put(k, json.dumps(v))"
}

License

Adaptive Public License 1.0 (APL-1.0)

Tl;dr plain English version: https://tldrlegal.com/license/adaptive-public-license-1.0-%28apl-1.0%29

Resources

Notes

  • why this project name ? It's a reference to the line "T'as tué mon bonhomme !" from the video "Tom et ses chums! Farador D&D" : http://youtu.be/T9FMURHhgzc?t=4m40s
  • in case you want to add a character sheet in PDF format, you can use pdftoppm then ImageMagick convert to get a PNG image file.

rpg-bonhomme's People

Contributors

anaguiros avatar lucas-c avatar renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

anaguiros

rpg-bonhomme's Issues

Unknown name provided

Message d'erreur poppant lors du rensignement d'un name="xxx" avec xxx n'existant pas en base de données.
C'est pas très joli tout ça ...
rpg_fail

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/ci.yml
  • actions/checkout v3
  • actions/setup-python v3
  • actions/cache v3
pip_requirements
dev-requirements.txt
prod-requirements.txt
requirements.txt

  • Check this box to trigger a request for Renovate to run again on this repository

UX/UI improvements

  • public / private character ? -> listed or not in index
  • checkbox for search engine referencement (meta noindex)
  • header msg for character not found error
  • header msg for readonly URLs
  • help header to create new character in layouts
  • better visual clues that operations are successful / failed

Providinging read-only URLs for character-sheets

Proposal:

  • on a successful PUT request to the WSGI DB, it will return a read-write secret key to the browser. This read-write secret-key is generated by HMAC-ing the base key (layout name + character sheet name) with a server-constant SALT.
  • a read-only URL is provideded to the user by simply appending this secret key as a modification-key parameter to the base URL.
  • for keys already present in the DB, the WSGI will only allow PUT modification if a secret-key parameter is provided and matches HMAC(base_key ^ SALT).

issue5_modification-key

I prefer this approach over using two non-readable IDs, one for read-only access and one for read-write.

Cons:

  • it adds a bit of API complexity : one more parameter for the JS & WSGI codes to handle.
  • we still need a mandatory CSS #name input field

Moreover the WSGI now needs to handle to flavours of PUT requests : CREATE NEW (without secret key) & UPDATE (with secret key). But I cannot imagine a solution that wouldn't increase the WSGI API complexity.

Pros:

  • it's relatively simple to understand for the end user : the concept of the secret key is easier to grasp and less confusing than using two opaque IDs
  • this lets the character name be visible in the URL, which is very handy. The risk to stumble on a character by creating a character with the same name will still exists, but one will only access the read-only version by doing so.
  • it's straightforward to implement (and doesn't require altering the DB schema for what it's worth)

Ajout de règles métier

Il pourrait être cool d'ajouter un système de vérification des valeurs rentrées dans la fiche de perso.

Je pensais à l'ajout d'un fichier JS par jeu (un fichier CSS par jeu pour les champs, et un fichier JS comportant une méthode appellée à la validation pour checker nos totaux), regroupant les règles métiers de la génération de nouveaux persos low-level.
Etant donné que les règles sur les nouveaux peros lvl1 sont souvent les mêmes, On évitera bien sûr l'application d'un contrôle de champs sur des persos expérimentés ayant mis à niveau leurs compétences

Rendre compatible avec le format de fdp de rolisteam

Extrait d'un échange email avec Renaud Guezennec:

En gros, le fichier json de rolisteam est une base de données de personnages.
Il y a élements:

-La structure de la fiche de personnage: la liste des champs,(id, label, position, font, couleur de texte, type d'éléments (textfield, textarea, bouton, combobox) et d'autres. Le positionnement ne sert qu'à la génération du QML.

-Il y a le code QML (qui est la fiche de personnage visuelle), c'est un langague déclaratif proche du css (dans sa syntaxe). C'est bien pour créer une interface assez rapidement (qui est stocké dans le Json comme une valeur texte.

-Il y a la liste des personnages avec la valeur pour chaque champs. Genre si la structure définit le champs intelligence, à 3% en hauteur et 4% en partant de la gauche.
Chaque personnage à une clé intelligence, avec une valeur associé.

-Une liste d'images qui sert de fond aux fiches de personnages [facultatif aussi], les images sont un array de chaine de charactere, l'image est codé en base64 dans le fichier. Je prévois de gérer un lien hyper text en plus.

Le processus de création d'une fiche est assez simple:

L'utilisateur ouvre rcse (un programme appart de rolisteam: Rcse = Rolisteam character sheet editor), il drag/drop l'image de fond de sa fiche de personnage. Il positionne les différents champs sur l'image, quand c'est terminé, l'outil génère le QML (l'utilisateur est capable de le modifier s'il le souhaite). A cette étape le fichier ne contient que la structure.
Toujours dans RCSE (ou dans rolisteam), l'utilisateur (le mj dans rolisteam) peut ajouter des personnages et saisir les valeurs de champs.

Dans rolisteam, on charge le fichier json, on peut éventuellement ajouter des personnages.
Rolisteam ne lit que l'id du champs, le label. Il ignore tout l'aspect présentation.

Il récupère les images et le code QML et la structure. Il ouvre ainsi une sous-fenetre avec un onglet. Cet onglet affiche une tableview avec les différents champs et un personnage par colonne.

              Perso 1     Perso 2

Nom personnage: Dornthal Archaëlle.
Intelligence 8 14
...

Ensuite, le MJ peut affecter le personnage 1 au joueur Paul, et le perso 2 à Marie.

              Paul       Marie

Nom personnage: Dornthal Archaëlle.
Intelligence 8 14
....

Quand cette étape est faite, chez le joueur qui vient d'etre affecter à une fiche, s'ouvre une fenetre avec dans le premier onglet la tableview avec les noms des champs et la liste des valeurs pour son perso.
Dans un deuxieme onglet, s'ouvre la vue jolie de la fiche perso. Avec en fond, l'ilmage et les champs textes editables. Modifier une valeur dans la fiche provoque le changement sur le tableau et vis-versa.

Du coup dans cette organisation je ne sais pas si vous trouvez un endroit ou rpg-bonhomme peut aider. J'avais dans un premier temps pensait à proposer la génération de la structure de données, ou éventuellement la possibilité d'importer facilement des structures/styles.
Mais si je comprends bien, la partie visuelle est définie dans des styles qui ne sont pas générés par le systeme. Ils sont fournis par l'auteur de la fiche.

Ajout d'une homepage, UI ?

Ca pourrait être une idée de rajouter une homepage permettant un affichage globalisé des différents perso hébergé sur le serveur, avant une redirection vers la fiche en elle-même.

Ca permettrait de rendre tout ça un peu plus noob-proof, faire des tris (genre liste de perso par jeu), et rendre tout ça un peu plus propre (j'aime bien coller des URL forger avec mes mimines, mais bon ...).

Après ça dépends bien sur du niveau de finition souhaité sur l'ensemble.

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.