4 Commits
0.1.3 ... 0.1.4

Author SHA1 Message Date
9a21e6d20b fixed bugs 2026-02-23 19:31:40 +01:00
639aac68ca added version number to build 2026-02-23 16:11:23 +01:00
4d00936719 Fixed first issue, added release script 2026-02-23 15:19:15 +01:00
b03d9bf998 updated include to be more scoped 2026-02-23 14:08:18 +01:00
30 changed files with 220 additions and 82 deletions

View File

@@ -87,8 +87,13 @@ target_link_options(${TARGET_NAME} PRIVATE
$<$<CONFIG:Release>:-flto=auto> $<$<CONFIG:Release>:-flto=auto>
) )
if(NOT DEFINED APP_VERSION)
set(APP_VERSION "0.0.0")
endif()
target_compile_definitions(${TARGET_NAME} PRIVATE target_compile_definitions(${TARGET_NAME} PRIVATE
APPLICATION_NAME="${TARGET_NAME}" APPLICATION_NAME="${TARGET_NAME}"
APP_VERSION="${APP_VERSION}"
SQLITE_THREADSAFE=1 # build sqlite with thread safty SQLITE_THREADSAFE=1 # build sqlite with thread safty
ASIO_STANDALONE # use asio without boost ASIO_STANDALONE # use asio without boost
CROW_ENABLE_COMPRESSION # enable compression part of crow CROW_ENABLE_COMPRESSION # enable compression part of crow

View File

@@ -1,7 +1,7 @@
# Maintainer: Lukas Forsberg lukas96.forsberg@gmail.com # Maintainer: Lukas Forsberg lukas96.forsberg@gmail.com
pkgname=shadowrun-server pkgname=shadowrun-server
pkgver=0.1.3 pkgver=0.1.4
pkgrel=1 pkgrel=1
arch=('x86_64') arch=('x86_64')
depends=() depends=()
@@ -18,7 +18,8 @@ build() {
cmake -S "${srcdir}" \ cmake -S "${srcdir}" \
-B build \ -B build \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_PREFIX=/usr \
-DAPP_VERSION=${pkgver}
cmake --build build cmake --build build
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
import{l as o,a as r}from"../chunks/D_WAtfM3.js";export{o as load_css,r as start};

View File

@@ -1 +0,0 @@
import{l as o,a as r}from"../chunks/niSfElle.js";export{o as load_css,r as start};

View File

@@ -1 +1 @@
import{f as u,a as h}from"../chunks/K5GTgIDA.js";import{i as g}from"../chunks/DgU0EQmz.js";import{z as l,a8 as v,K as d,B as _,D as s,F as e,C as x}from"../chunks/DxMC-E2z.js";import{s as o}from"../chunks/V6M2jInR.js";import{s as $,p}from"../chunks/niSfElle.js";const k={get error(){return p.error},get status(){return p.status}};$.updated.check;const m=k;var b=u("<h1> </h1> <p> </p>",1);function F(i,f){l(f,!1),g();var t=b(),r=v(t),n=s(r,!0);e(r);var a=x(r,2),c=s(a,!0);e(a),d(()=>{o(n,m.status),o(c,m.error?.message)}),h(i,t),_()}export{F as component}; import{f as u,a as h}from"../chunks/K5GTgIDA.js";import{i as g}from"../chunks/DgU0EQmz.js";import{z as l,a8 as v,K as d,B as _,D as s,F as e,C as x}from"../chunks/DxMC-E2z.js";import{s as o}from"../chunks/V6M2jInR.js";import{s as $,p}from"../chunks/D_WAtfM3.js";const k={get error(){return p.error},get status(){return p.status}};$.updated.check;const m=k;var b=u("<h1> </h1> <p> </p>",1);function F(i,f){l(f,!1),g();var t=b(),r=v(t),n=s(r,!0);e(r);var a=x(r,2),c=s(a,!0);e(a),d(()=>{o(n,m.status),o(c,m.error?.message)}),h(i,t),_()}export{F as component};

View File

@@ -1 +1 @@
import{f as w,a as d}from"../chunks/K5GTgIDA.js";import{i as J}from"../chunks/DgU0EQmz.js";import{z as O,A as t,B as P,C as r,D as o,F as i,G as v,I as g,J as b,K as S}from"../chunks/DxMC-E2z.js";import{e as T,s as j}from"../chunks/V6M2jInR.js";import{i as z}from"../chunks/BJWcdj5l.js";import{r as h}from"../chunks/HgGInnYf.js";import{b as _}from"../chunks/Cp1RMksV.js";import{g as A}from"../chunks/niSfElle.js";var B=w('<p class="error svelte-1uha8ag"> </p>'),D=w('<form class="login svelte-1uha8ag"><h2>Login</h2> <label class="svelte-1uha8ag">User <input type="text" required/></label> <label class="svelte-1uha8ag">Password <input type="password" required/></label> <button>Login</button> <!></form>');function M(y,x){O(x,!1);let s=v(""),e=v({username:"",password:""});async function k(){try{const a=await fetch("/login",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify(t(e))});if(!a.ok){b(s,await a.text());return}A("/shadowrun")}catch(a){b(s,a.message)}}J();var n=D(),l=r(o(n),2),u=r(o(l));h(u),i(l);var p=r(l,2),f=r(o(p));h(f),i(p);var c=r(p,2),C=r(c,2);{var L=a=>{var m=B(),q=o(m,!0);i(m),S(()=>j(q,t(s))),d(a,m)};z(C,a=>{t(s)&&a(L)})}i(n),_(u,()=>t(e).username,a=>g(e,t(e).username=a)),_(f,()=>t(e).password,a=>g(e,t(e).password=a)),T("click",c,k),d(y,n),P()}export{M as component}; import{f as w,a as d}from"../chunks/K5GTgIDA.js";import{i as J}from"../chunks/DgU0EQmz.js";import{z as O,A as t,B as P,C as r,D as o,F as i,G as v,I as g,J as b,K as S}from"../chunks/DxMC-E2z.js";import{e as T,s as j}from"../chunks/V6M2jInR.js";import{i as z}from"../chunks/BJWcdj5l.js";import{r as h}from"../chunks/HgGInnYf.js";import{b as _}from"../chunks/Cp1RMksV.js";import{g as A}from"../chunks/D_WAtfM3.js";var B=w('<p class="error svelte-1uha8ag"> </p>'),D=w('<form class="login svelte-1uha8ag"><h2>Login</h2> <label class="svelte-1uha8ag">User <input type="text" required/></label> <label class="svelte-1uha8ag">Password <input type="password" required/></label> <button>Login</button> <!></form>');function M(y,x){O(x,!1);let s=v(""),e=v({username:"",password:""});async function k(){try{const a=await fetch("/login",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify(t(e))});if(!a.ok){b(s,await a.text());return}A("/shadowrun")}catch(a){b(s,a.message)}}J();var n=D(),l=r(o(n),2),u=r(o(l));h(u),i(l);var p=r(l,2),f=r(o(p));h(f),i(p);var c=r(p,2),C=r(c,2);{var L=a=>{var m=B(),q=o(m,!0);i(m),S(()=>j(q,t(s))),d(a,m)};z(C,a=>{t(s)&&a(L)})}i(n),_(u,()=>t(e).username,a=>g(e,t(e).username=a)),_(f,()=>t(e).password,a=>g(e,t(e).password=a)),T("click",c,k),d(y,n),P()}export{M as component};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"version":"1771789536194"} {"version":"1771871349245"}

View File

@@ -5,11 +5,11 @@
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="/favicon.ico" /> <link rel="icon" type="image/x-icon" href="/favicon.ico" />
<link rel="modulepreload" href="./_app/immutable/entry/start.BnAWgAKt.js"> <link rel="modulepreload" href="./_app/immutable/entry/start.BWyMcWXp.js">
<link rel="modulepreload" href="./_app/immutable/chunks/niSfElle.js"> <link rel="modulepreload" href="./_app/immutable/chunks/D_WAtfM3.js">
<link rel="modulepreload" href="./_app/immutable/chunks/DxMC-E2z.js"> <link rel="modulepreload" href="./_app/immutable/chunks/DxMC-E2z.js">
<link rel="modulepreload" href="./_app/immutable/chunks/CgHyU30y.js"> <link rel="modulepreload" href="./_app/immutable/chunks/CgHyU30y.js">
<link rel="modulepreload" href="./_app/immutable/entry/app.CJZl1xEf.js"> <link rel="modulepreload" href="./_app/immutable/entry/app.DShWGRS5.js">
<link rel="modulepreload" href="./_app/immutable/chunks/V6M2jInR.js"> <link rel="modulepreload" href="./_app/immutable/chunks/V6M2jInR.js">
<link rel="modulepreload" href="./_app/immutable/chunks/K5GTgIDA.js"> <link rel="modulepreload" href="./_app/immutable/chunks/K5GTgIDA.js">
<link rel="modulepreload" href="./_app/immutable/chunks/BJWcdj5l.js"> <link rel="modulepreload" href="./_app/immutable/chunks/BJWcdj5l.js">
@@ -20,15 +20,15 @@
<div style="display: contents"> <div style="display: contents">
<script> <script>
{ {
__sveltekit_q0ydb3 = { __sveltekit_1wppsc6 = {
base: new URL(".", location).pathname.slice(0, -1) base: new URL(".", location).pathname.slice(0, -1)
}; };
const element = document.currentScript.parentElement; const element = document.currentScript.parentElement;
Promise.all([ Promise.all([
import("./_app/immutable/entry/start.BnAWgAKt.js"), import("./_app/immutable/entry/start.BWyMcWXp.js"),
import("./_app/immutable/entry/app.CJZl1xEf.js") import("./_app/immutable/entry/app.DShWGRS5.js")
]).then(([kit, app]) => { ]).then(([kit, app]) => {
kit.start(app, element); kit.start(app, element);
}); });

View File

@@ -1,5 +0,0 @@
{
"http_port" : 3011,
"db_path": "shadowrun.db",
"domain": "http://192.168.1.101:3011"
}

View File

@@ -5,11 +5,11 @@
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="/favicon.ico" /> <link rel="icon" type="image/x-icon" href="/favicon.ico" />
<link rel="modulepreload" href="./_app/immutable/entry/start.BnAWgAKt.js"> <link rel="modulepreload" href="./_app/immutable/entry/start.BWyMcWXp.js">
<link rel="modulepreload" href="./_app/immutable/chunks/niSfElle.js"> <link rel="modulepreload" href="./_app/immutable/chunks/D_WAtfM3.js">
<link rel="modulepreload" href="./_app/immutable/chunks/DxMC-E2z.js"> <link rel="modulepreload" href="./_app/immutable/chunks/DxMC-E2z.js">
<link rel="modulepreload" href="./_app/immutable/chunks/CgHyU30y.js"> <link rel="modulepreload" href="./_app/immutable/chunks/CgHyU30y.js">
<link rel="modulepreload" href="./_app/immutable/entry/app.CJZl1xEf.js"> <link rel="modulepreload" href="./_app/immutable/entry/app.DShWGRS5.js">
<link rel="modulepreload" href="./_app/immutable/chunks/V6M2jInR.js"> <link rel="modulepreload" href="./_app/immutable/chunks/V6M2jInR.js">
<link rel="modulepreload" href="./_app/immutable/chunks/K5GTgIDA.js"> <link rel="modulepreload" href="./_app/immutable/chunks/K5GTgIDA.js">
<link rel="modulepreload" href="./_app/immutable/chunks/BJWcdj5l.js"> <link rel="modulepreload" href="./_app/immutable/chunks/BJWcdj5l.js">
@@ -20,15 +20,15 @@
<div style="display: contents"> <div style="display: contents">
<script> <script>
{ {
__sveltekit_q0ydb3 = { __sveltekit_1wppsc6 = {
base: new URL(".", location).pathname.slice(0, -1) base: new URL(".", location).pathname.slice(0, -1)
}; };
const element = document.currentScript.parentElement; const element = document.currentScript.parentElement;
Promise.all([ Promise.all([
import("./_app/immutable/entry/start.BnAWgAKt.js"), import("./_app/immutable/entry/start.BWyMcWXp.js"),
import("./_app/immutable/entry/app.CJZl1xEf.js") import("./_app/immutable/entry/app.DShWGRS5.js")
]).then(([kit, app]) => { ]).then(([kit, app]) => {
kit.start(app, element); kit.start(app, element);
}); });

View File

@@ -1,6 +1,5 @@
<script lang="ts"> <script lang="ts">
import { onMount } from 'svelte'; import { onMount } from 'svelte';
//import { API_BASE } from '$lib/config';
import { Defaults } from './defaults.svelte'; import { Defaults } from './defaults.svelte';
import type { Skill, Connection} from './types.svelte'; import type { Skill, Connection} from './types.svelte';
import { autoGrow } from '$lib/common/autogrow'; import { autoGrow } from '$lib/common/autogrow';
@@ -24,8 +23,10 @@
characterData.NegativeQualities ??= []; characterData.NegativeQualities ??= [];
characterData.PysicalCondition ??= Defaults.PysicalCondition characterData.PysicalCondition ??= Defaults.PysicalCondition
characterData.StunCondition ??= Defaults.StunCondition characterData.StunCondition ??= Defaults.StunCondition
characterData.Inventory ??= {}; characterData.Inventory ??= [];
characterData.Notes ??= {}; characterData.Notes ??= {};
characterData.KnowledgeSkills ??= [];
characterData.Specializations ??= [];
let selectedDate : any = null // YYYY-MM-DD format let selectedDate : any = null // YYYY-MM-DD format
const characterInfoTypes = { const characterInfoTypes = {
@@ -211,6 +212,65 @@
</table> </table>
<button on:click={() => add("Skills")}>+</button> <button on:click={() => add("Skills")}>+</button>
<h2>Specialization</h2>
<table>
<thead>
<tr>
<th>Name</th>
<th>Page</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{#each characterData.Specializations as proficiency, i}
<tr>
<td><textarea use:autoGrow class="input-height" rows="1" bind:value={characterData.Specializations[i].Name}></textarea></td>
<td><input type="number" min=1 max=354 bind:value={characterData.Specializations[i].Page} /></td>
<td><button on:click={() => viewPage(characterData.Specializations[i].Page)}>View</button></td>
<td><button class="red-button" on:click={() => remove("Specializations", i)}>X</button></td>
</tr>
{/each}
</tbody>
</table>
<button on:click={() => add("Specializations")}>+</button>
<h2>Knowledge Skills</h2>
<table>
<thead>
<tr>
<th>Name</th>
<th>Rating</th>
<th>Attribute</th>
<th>Dice</th>
<th>Page</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{#each characterData.KnowledgeSkills as skill, i}
<tr>
<td><textarea use:autoGrow class="input-height" rows="1" bind:value={characterData.KnowledgeSkills[i].Name}></textarea></td>
<td><input type="number" min=0 max=100 bind:value={characterData.KnowledgeSkills[i].Rating} /></td>
<td><select bind:value={characterData.KnowledgeSkills[i].Attribute}>
{#each Object.keys(Defaults.Attributes) as attr}
<option value={attr}>{attr}</option>
{/each}
</select></td>
<td><span>{skill.Rating + characterData.Attributes[skill.Attribute]}</span></td>
<td><input type="number" min=1 max=354 bind:value={characterData.KnowledgeSkills[i].Page} /></td>
<td><button on:click={() => viewPage(characterData.KnowledgeSkills[i].Page)}>View</button></td>
<td><button class="red-button" on:click={() => remove("KnowledgeSkills", i)}>X</button></td>
</tr>
{/each}
</tbody>
</table>
<button on:click={() => add("KnowledgeSkills")}>+</button>
<h2>Contacts</h2> <h2>Contacts</h2>
<table> <table>
<thead> <thead>
@@ -262,8 +322,8 @@
<td><input type="number" min=0 max=100 bind:value={characterData.RangedWeapons[i].RC} /></td> <td><input type="number" min=0 max=100 bind:value={characterData.RangedWeapons[i].RC} /></td>
<td><input type="number" min=0 max=9999 bind:value={characterData.RangedWeapons[i].Ammo} /></td> <td><input type="number" min=0 max=9999 bind:value={characterData.RangedWeapons[i].Ammo} /></td>
<td><textarea use:autoGrow class="input-height" style="width: 3em;" rows="1" bind:value={characterData.RangedWeapons[i].Availabiliy}></textarea></td> <td><textarea use:autoGrow class="input-height" style="width: 3em;" rows="1" bind:value={characterData.RangedWeapons[i].Availabiliy}></textarea></td>
<td><input type="number" min=1 max=354 bind:value={characterData.Connections[i].Page} /></td> <td><input type="number" min=1 max=354 bind:value={characterData.RangedWeapons[i].Page} /></td>
<td><button on:click={() => viewPage(characterData.Connections[i].Page)}>View</button></td> <td><button on:click={() => viewPage(characterData.RangedWeapons[i].Page)}>View</button></td>
<td><button class="red-button" on:click={() => remove("RangedWeapons", i)}>X</button></td> <td><button class="red-button" on:click={() => remove("RangedWeapons", i)}>X</button></td>
</tr> </tr>
{/each} {/each}
@@ -297,8 +357,8 @@
<td><input type="number" min=0 max=999 bind:value={characterData.MeleeWeapons[i]["Strength Multiplier"]} /></td> <td><input type="number" min=0 max=999 bind:value={characterData.MeleeWeapons[i]["Strength Multiplier"]} /></td>
<td><span> {(weapon["Strength Multiplier"] * characterData.Attributes.Strength) + weapon.Damage }</span></td> <td><span> {(weapon["Strength Multiplier"] * characterData.Attributes.Strength) + weapon.Damage }</span></td>
<td><input type="number" min=0 max=100 bind:value={characterData.MeleeWeapons[i].AP} /></td> <td><input type="number" min=0 max=100 bind:value={characterData.MeleeWeapons[i].AP} /></td>
<td><input type="number" min=1 max=354 bind:value={characterData.Connections[i].Page} /></td> <td><input type="number" min=1 max=354 bind:value={characterData.MeleeWeapons[i].Page} /></td>
<td><button on:click={() => viewPage(characterData.Connections[i].Page)}>View</button></td> <td><button on:click={() => viewPage(characterData.MeleeWeapons[i].Page)}>View</button></td>
<td><button class="red-button" on:click={() => remove("MeleeWeapons", i)}>X</button></td> <td><button class="red-button" on:click={() => remove("MeleeWeapons", i)}>X</button></td>
</tr> </tr>
{/each} {/each}
@@ -339,11 +399,12 @@
<tr> <tr>
<th>Cyberware</th> <th>Cyberware</th>
<th>Rating</th> <th>Rating</th>
<th>Capacity</th>
<th>Essence</th> <th>Essence</th>
<th>Notes</th> <th>Notes</th>
<th>Page</th> <th>Page</th>
<th></th> <th></th>
<th></th> <!-- for remove button --> <th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -351,10 +412,11 @@
<tr> <tr>
<td><input placeholder="Cyberware" bind:value={characterData.Cyberware[i].Implant} /></td> <td><input placeholder="Cyberware" bind:value={characterData.Cyberware[i].Implant} /></td>
<td><input type="number" min=0 max=100 bind:value={characterData.Cyberware[i].Rating} /></td> <td><input type="number" min=0 max=100 bind:value={characterData.Cyberware[i].Rating} /></td>
<td><input type="number" min=0 max=100 bind:value={characterData.Cyberware[i].Capacity} /></td>
<td><input type="number" min=0 max=100 bind:value={characterData.Cyberware[i].Essence} /></td> <td><input type="number" min=0 max=100 bind:value={characterData.Cyberware[i].Essence} /></td>
<td><input placeholder="Notes" bind:value={characterData.Cyberware[i].Notes} /></td> <td><input placeholder="Notes" bind:value={characterData.Cyberware[i].Notes} /></td>
<td><input type="number" min=1 max=354 bind:value={characterData.Connections[i].Page} /></td> <td><input type="number" min=1 max=354 bind:value={characterData.Cyberware[i].Page} /></td>
<td><button on:click={() => viewPage(characterData.Connections[i].Page)}>View</button></td> <td><button on:click={() => viewPage(characterData.Cyberware[i].Page)}>View</button></td>
<td><button class="red-button" on:click={() => remove("Cyberware", i)}>X</button></td> <td><button class="red-button" on:click={() => remove("Cyberware", i)}>X</button></td>
</tr> </tr>
{/each} {/each}
@@ -368,6 +430,7 @@
<tr> <tr>
<th>Bioware</th> <th>Bioware</th>
<th>Rating</th> <th>Rating</th>
<th>Capacity</th>
<th>Essence</th> <th>Essence</th>
<th>Notes</th> <th>Notes</th>
<th>Page</th> <th>Page</th>
@@ -379,11 +442,12 @@
{#each characterData.Bioware as Bioware, i} {#each characterData.Bioware as Bioware, i}
<tr> <tr>
<td><input placeholder="Bioware" bind:value={characterData.Bioware[i].Implant} /></td> <td><input placeholder="Bioware" bind:value={characterData.Bioware[i].Implant} /></td>
<td><input type="number" min="0" bind:value={characterData.Bioware[i].Rating} /></td> <td><input type="number" min=0 max=100 bind:value={characterData.Bioware[i].Rating} /></td>
<td><input type="number" min="0" bind:value={characterData.Bioware[i].Essence} /></td> <td><input type="number" min=0 max=100 bind:value={characterData.Bioware[i].Capacity} /></td>
<td><input type="number" min=0 max=100 bind:value={characterData.Bioware[i].Essence} /></td>
<td><input placeholder="Notes" bind:value={characterData.Bioware[i].Notes} /></td> <td><input placeholder="Notes" bind:value={characterData.Bioware[i].Notes} /></td>
<td><input type="number" min=1 max=354 bind:value={characterData.Connections[i].Page} /></td> <td><input type="number" min=1 max=354 bind:value={characterData.Bioware[i].Page} /></td>
<td><button on:click={() => viewPage(characterData.Connections[i].Page)}>View</button></td> <td><button on:click={() => viewPage(characterData.Bioware[i].Page)}>View</button></td>
<td><button class="red-button" on:click={() => remove("Bioware", i)}>X</button></td> <td><button class="red-button" on:click={() => remove("Bioware", i)}>X</button></td>
</tr> </tr>
{/each} {/each}
@@ -423,7 +487,7 @@
<th>Quality</th> <th>Quality</th>
<th>Page</th> <th>Page</th>
<th></th> <th></th>
<th></th> <!-- for remove button --> <th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -491,8 +555,8 @@
{#each characterData.Inventory as inventory, i} {#each characterData.Inventory as inventory, i}
<tr> <tr>
<td><input placeholder="Item" bind:value={characterData.Inventory[i].Item} /></td> <td><input placeholder="Item" bind:value={characterData.Inventory[i].Item} /></td>
<td><input type="number" min=1 max=354 bind:value={characterData.NegativeQualities[i].Quantity} /></td> <td><input type="number" min=1 max=354 bind:value={characterData.Inventory[i].Quantity} /></td>
<td><input placeholder="Notes" bind:value={characterData.NegativeQualities[i].Notes} /></td> <td><input placeholder="Notes" bind:value={characterData.Inventory[i].Notes} /></td>
<td><input type="number" min=1 max=354 bind:value={characterData.Inventory[i].Page} /></td> <td><input type="number" min=1 max=354 bind:value={characterData.Inventory[i].Page} /></td>
<td><button on:click={() => viewPage(characterData.Inventory[i].Page)}>View</button></td> <td><button on:click={() => viewPage(characterData.Inventory[i].Page)}>View</button></td>
<td><button class="red-button" on:click={() => remove("Inventory", i)}>X</button></td> <td><button class="red-button" on:click={() => remove("Inventory", i)}>X</button></td>

View File

@@ -30,7 +30,13 @@ const Attributes = {
const Skill = { const Skill = {
Name: "", Name: "",
Rating: 0, Rating: 0,
Attribute: Object.keys(Attributes)[0] Attribute: Object.keys(Attributes)[0],
Page: 1,
}
const Specialization = {
Name: "",
Page: 1,
} }
const Connection = { const Connection = {
@@ -48,6 +54,7 @@ const RangedWeapon = {
RC: 0, RC: 0,
Ammo: 0, Ammo: 0,
Availabiliy: "", Availabiliy: "",
Page: 1,
} }
const MeleeWeapon = { const MeleeWeapon = {
@@ -56,17 +63,21 @@ const MeleeWeapon = {
Damage: 1, Damage: 1,
"Strength Multiplier" : 0.5, "Strength Multiplier" : 0.5,
AP: 0, AP: 0,
Page: 1,
}; };
const Implant = { const Implant = {
Implant: "", Implant: "",
Rating: 0, Rating: 0,
Capacity: 0,
Essence: 0, Essence: 0,
Notes: "", Notes: "",
Page: 1,
} }
const Qualitiy = { const Qualitiy = {
Qualitiy : "" Qualitiy : "",
Page: 1,
} }
const PysicalCondition = Array.from({ length: 6 }, () => const PysicalCondition = Array.from({ length: 6 }, () =>
@@ -78,20 +89,23 @@ const StunCondition = Array.from({ length: 4 }, () =>
const Armor = { const Armor = {
Armor: "", Armor: "",
Ballistic: 0, Ballistic: 0,
Impact: 0 Impact: 0,
Page: 1,
} }
const Inventory = { const Inventory = {
Item: "", Item: "",
Quantity: 1, Quantity: 1,
Notes: "", Notes: "",
Page: 1 Page: 1,
} }
export const Defaults = { export const Defaults = {
Info: Info, Info: Info,
Attributes: Attributes, Attributes: Attributes,
Skills: Skill, Skills: Skill,
Specializations: Specialization,
KnowledgeSkills: Skill,
Connections: Connection, Connections: Connection,
RangedWeapons : RangedWeapon, RangedWeapons : RangedWeapon,
MeleeWeapons : MeleeWeapon, MeleeWeapons : MeleeWeapon,

29
release.sh Executable file
View File

@@ -0,0 +1,29 @@
# get the varaibles from PKGBUILD
source ./PKGBUILD
# assets to pack in the tar ball
ASSETS=(
"source/"
"modules/"
"assets/"
"frontend/build/"
"shadowrun-server.service"
"CMakeLists.txt"
"shadowrun-server.install"
)
# create the tar ball
tar czf ${pkgname}-${pkgver}.tar.gz "${ASSETS[@]}"
# create the package
makepkg -f
# create the release directory and store all files there
RELEASE_DIR="release-${pkgver}/"
mkdir -p ${RELEASE_DIR}
mv ${pkgname}-${pkgver}.tar.gz ${RELEASE_DIR}
mv ${pkgname}-${pkgver}-1-x86_64.pkg.tar.zst ${RELEASE_DIR}
mv ${pkgname}-debug-${pkgver}-1-x86_64.pkg.tar.zst ${RELEASE_DIR}
mv src/ ${RELEASE_DIR}
#scp ${RELEASE_DIR}${pkgname}-${pkgver}-1-x86_64.pkg.tar.zst lukas@192.168.1.101:/home/lukas/Drive/archrepo/x86_64/

26
source/Application.hpp Normal file
View File

@@ -0,0 +1,26 @@
#ifndef __APPVERSION_H__
#define __APPVERSION_H__
#include <string>
namespace Application {
#ifndef APP_VERSION
#define APP_VERSION "0.0.0"
#endif
#ifndef APPLICATION_NAME
#define APPLICATION_NAME "app"
#endif
inline std::string version(){
return std::string(APP_VERSION);
}
inline std::string name(){
return std::string(APPLICATION_NAME);
}
}
#endif // __APPVERSION_H__

View File

@@ -1,8 +1,8 @@
#include <fstream> #include <fstream>
#include "json.hpp" #include "json.hpp"
#include "json_settings.h" #include "json_settings.h"
#include "crow/logging.h"
#include "utils.hpp" #include "utils.hpp"
#include <iostream>
using namespace std; using namespace std;
using json = nlohmann::json; using json = nlohmann::json;
@@ -19,7 +19,7 @@ Settings AppSettings::deafult(){
Settings AppSettings::load() { Settings AppSettings::load() {
ifstream file(settingsFile); ifstream file(settingsFile);
if (!file.is_open()) { if (!file.is_open()) {
CROW_LOG_ERROR << "Failed to load settings file" << settingsFile << " Loading default settings"; std::cerr << "Failed to load settings file" << settingsFile << " Loading default settings" << std::endl;
return AppSettings::deafult(); return AppSettings::deafult();
} }
@@ -29,14 +29,14 @@ Settings AppSettings::load() {
auto result = utils::parseJson(fileContents); auto result = utils::parseJson(fileContents);
if(!result){ if(!result){
CROW_LOG_ERROR << "failed to parse settings file, Loading default settings"; std::cerr << "failed to parse settings file, Loading default settings" << std::endl;
return AppSettings::deafult(); return AppSettings::deafult();
} }
try { try {
return result.value().get<Settings>(); return result.value().get<Settings>();
} catch (...) { } catch (...) {
CROW_LOG_ERROR << "failed to parse settings file, Loading default settings"; std::cerr << "failed to parse settings file, Loading default settings";
return AppSettings::deafult(); return AppSettings::deafult();
} }
} }

View File

@@ -3,7 +3,6 @@
#include "json.hpp" #include "json.hpp"
#include <string> #include <string>
namespace AppSettings { namespace AppSettings {
static constexpr char settingsFile[] = "assets/settings.json"; static constexpr char settingsFile[] = "assets/settings.json";

View File

@@ -1,15 +1,13 @@
#include "login.hpp" #include "login.hpp"
#include "crow/http_response.h"
#include "databasepool.h" #include "databasepool.h"
#include "SessionHandler.hpp" #include "SessionHandler.hpp"
#include <optional>
namespace login namespace login
{ {
SessionHandler sessionHandler; SessionHandler sessionHandler;
std::string getSessionId(const crow::request& req) { static std::string getSessionId(const crow::request& req) {
auto cookie_header = req.get_header_value("Cookie"); auto cookie_header = req.get_header_value("Cookie");
std::string prefix = "session_id="; std::string prefix = "session_id=";
auto pos = cookie_header.find(prefix); auto pos = cookie_header.find(prefix);
@@ -24,6 +22,15 @@ static crow::response redirectToLogin(){
return res; return res;
} }
static std::optional<std::string> loginUser(const std::string& username, const std::string& password)
{
auto user = getVerifiedUser(username, password);
if (user) {
return sessionHandler.createSession(user->id);
}
return {};
}
std::optional<crow::response> isLoggedIn(const crow::request& req) { std::optional<crow::response> isLoggedIn(const crow::request& req) {
std::string sessionId = getSessionId(req); std::string sessionId = getSessionId(req);
if (sessionId.empty()) if (sessionId.empty())
@@ -36,15 +43,6 @@ std::optional<crow::response> isLoggedIn(const crow::request& req) {
return {}; return {};
} }
std::optional<std::string> loginUser(const std::string& username, const std::string& password)
{
auto user = getVerifiedUser(username, password);
if (user) {
return sessionHandler.createSession(user->id);
}
return {};
}
void initLogin(crow::App<crow::CORSHandler>& app){ void initLogin(crow::App<crow::CORSHandler>& app){
createUser("lukas", "Trollar4928"); createUser("lukas", "Trollar4928");

View File

@@ -3,7 +3,8 @@
#pragma once #pragma once
#include <crow.h> #include <crow/http_response.h>
#include <crow/app.h>
#include "crow/middlewares/cors.h" #include "crow/middlewares/cors.h"
namespace login { namespace login {

View File

@@ -5,6 +5,7 @@
#include <vector> #include <vector>
#include "json.hpp" #include "json.hpp"
#include "utils.hpp" #include "utils.hpp"
namespace login namespace login
{ {

View File

@@ -7,10 +7,13 @@
#include "ShadowrunApi.hpp" #include "ShadowrunApi.hpp"
#include "databasepool.h" #include "databasepool.h"
#include "crow/compression.h" #include "crow/compression.h"
#include "Application.hpp"
using namespace std; using namespace std;
int main() { int main() {
std::cout << "Launching " << Application::name() << " version: " << Application::version() << std::endl;
AppSettings::Settings settings = AppSettings::load(); AppSettings::Settings settings = AppSettings::load();
crow::App<crow::CORSHandler> app; crow::App<crow::CORSHandler> app;
@@ -26,20 +29,20 @@ int main() {
// create global database // create global database
dbpool = std::make_unique<DatabasePool>(settings.db_path); dbpool = std::make_unique<DatabasePool>(settings.db_path);
if (!dbpool->init(std::thread::hardware_concurrency())){ if (!dbpool->init(std::thread::hardware_concurrency())){
CROW_LOG_ERROR << "Failed to create database at : " << settings.db_path; std::cerr << "Failed to create database at : " << settings.db_path << std::endl;
return 1; std::exit(1);
} }
auto opt_isPortOpen = utils::isLocalPortOpen(settings.http_port); auto opt_isPortOpen = utils::isLocalPortOpen(settings.http_port);
if (opt_isPortOpen.has_value()){ if (opt_isPortOpen.has_value()){
if (opt_isPortOpen.value()){ if (opt_isPortOpen.value()){
CROW_LOG_ERROR << "Local port : " << settings.http_port << " is already open"; std::cerr << "Local port : " << settings.http_port << " is already open" << std::endl;
return 1; std::exit(1);
} }
} }
else { else {
CROW_LOG_ERROR << "failed to check if local port is open : " << opt_isPortOpen.error(); std::cerr << "failed to check if local port is open : " << opt_isPortOpen.error() << std::endl;
return 1; std::exit(1);
} }
// Root route // Root route

View File

@@ -3,6 +3,7 @@
#include "ShadowrunApi.hpp" #include "ShadowrunApi.hpp"
#include "ShadowrunDb.hpp" #include "ShadowrunDb.hpp"
#include "login.hpp" #include "login.hpp"
#include "magic_enum.hpp"
#include <vector> #include <vector>
using namespace std; using namespace std;

View File

@@ -1,7 +1,7 @@
#ifndef __SHADOWRUNAPI_H__ #ifndef __SHADOWRUNAPI_H__
#define __SHADOWRUNAPI_H__ #define __SHADOWRUNAPI_H__
#include "crow.h" #include "crow/app.h"
#include "crow/middlewares/cors.h" #include "crow/middlewares/cors.h"
namespace shadowrun { namespace shadowrun {

View File

@@ -1,6 +1,7 @@
#include "ShadowrunDb.hpp" #include "ShadowrunDb.hpp"
#include <optional> #include <optional>
#include "databasepool.h" #include "databasepool.h"
#include "magic_enum.hpp"
#include "utils.hpp" #include "utils.hpp"
#include "crow/logging.h" #include "crow/logging.h"

View File

@@ -7,8 +7,6 @@
#include <optional> #include <optional>
#include "json.hpp" #include "json.hpp"
#include "utils.hpp" #include "utils.hpp"
#include "sqlite_orm.h"
#include "magic_enum.hpp"
namespace shadowrun { namespace shadowrun {
enum class Type { enum class Type {
@@ -25,6 +23,8 @@ namespace shadowrun {
NegativeQualities = 10, NegativeQualities = 10,
Notes = 11, Notes = 11,
Inventory = 12, Inventory = 12,
KnowledgeSkills = 13,
Specializations = 14,
}; };
struct ShadowrunCharacter { struct ShadowrunCharacter {

View File

@@ -7,7 +7,7 @@
#include <filesystem> #include <filesystem>
#include <expected> #include <expected>
#include "json.hpp" #include "json.hpp"
#include "crow.h" #include "crow/http_response.h"
namespace utils { namespace utils {
// Svelte genereated files // Svelte genereated files