You've already forked obsidian-visualiser
Beginning campaign UI and WS to get player state.
This commit is contained in:
@@ -3,6 +3,13 @@ import { z } from "zod/v4";
|
||||
export const CampaignValidation = z.object({
|
||||
id: z.number(),
|
||||
name: z.string().nonempty(),
|
||||
description: z.string(),
|
||||
joinby: z.enum([ 'link', 'invite' ]),
|
||||
});
|
||||
description: z.string()
|
||||
});
|
||||
|
||||
class CampaignSheet
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,7 @@ export const defaultCharacter: Character = {
|
||||
exhaustion: 0,
|
||||
sickness: [],
|
||||
poisons: [],
|
||||
money: 0,
|
||||
},
|
||||
|
||||
owner: -1,
|
||||
@@ -563,6 +564,8 @@ export class CharacterBuilder extends CharacterCompiler
|
||||
{
|
||||
document.title = `d[any] - Edition de nouveau personnage`;
|
||||
|
||||
this.id = 'new';
|
||||
this._character.id = -1;
|
||||
this.render();
|
||||
this.display(0);
|
||||
}
|
||||
@@ -628,14 +631,21 @@ export class CharacterBuilder extends CharacterCompiler
|
||||
{
|
||||
if(this.id === 'new' || this.id === '-1')
|
||||
{
|
||||
//@ts-ignore
|
||||
this.id = this._character.id = this._result.id = await useRequestFetch()(`/api/character`, {
|
||||
const result = await useRequestFetch()(`/api/character`, {
|
||||
method: 'post',
|
||||
body: this._character,
|
||||
onResponseError: (e) => {
|
||||
Toaster.add({ title: 'Erreur d\'enregistrement', content: e.response.status === 401 ? "Vous n'êtes pas autorisé à effectué cette opération" : e.response.statusText, type: 'error', closeable: true, duration: 25000, timer: true });
|
||||
this.id = 'new';
|
||||
}
|
||||
});
|
||||
|
||||
if(result !== undefined)
|
||||
{
|
||||
this._character.id = this._result.id = result as number;
|
||||
this.id = result.toString();
|
||||
}
|
||||
|
||||
Toaster.add({ content: 'Personnage créé', type: 'success', duration: 25000, timer: true });
|
||||
useRouter().replace({ name: 'character-id-edit', params: { id: this.id } })
|
||||
if(leave) useRouter().push({ name: 'character-id', params: { id: this.id } });
|
||||
|
||||
@@ -139,6 +139,7 @@ export class Content
|
||||
try
|
||||
{
|
||||
Content._overview = parse<Record<string, Omit<LocalContent, 'content'>>>(overview);
|
||||
Content._reverseMapping = Object.values(Content._overview).reduce((p, v) => { p[v.path] = v.id; return p; }, {} as Record<string, string>);
|
||||
await Content.pull();
|
||||
}
|
||||
catch(e)
|
||||
@@ -245,16 +246,14 @@ export class Content
|
||||
if(force || !_overview || new Date(_overview.timestamp) < new Date(file.timestamp))
|
||||
{
|
||||
Content._overview[file.id] = file;
|
||||
Content._reverseMapping[file.path] = file.id;
|
||||
|
||||
Content.queue.queue(() => {
|
||||
return useRequestFetch()(`/api/file/content/${file.id}`, { cache: 'no-cache' }).then(async (content: string | undefined | null) => {
|
||||
if(content)
|
||||
{
|
||||
if(file.type !== 'folder')
|
||||
{
|
||||
Content.queue.queue(() => Content.write(file.id, content, { create: true }));
|
||||
//Content.queue.queue(() => Content.write('storage/' + file.path + (file.type === 'canvas' ? '.canvas' : '.md'), Content.toString({ ...file, content: Content.fromString(file, content) }), { create: true }));
|
||||
}
|
||||
}
|
||||
else
|
||||
Content._overview[file.id]!.error = true;
|
||||
|
||||
@@ -68,4 +68,36 @@ export function clamp(x: number, min: number, max: number): number
|
||||
export function lerp(x: number, a: number, b: number): number
|
||||
{
|
||||
return (1-x)*a+x*b;
|
||||
}
|
||||
// The value position is randomized
|
||||
// The metadata separator is randomized as a letter (to avoid collision with numbers)
|
||||
// The URI is (| == picked separator) |v_length|first part of the hash + seed + second part of the hash|v_pos|seed as hex.
|
||||
// Every number are converted to string as hexadecimal values
|
||||
export function cryptURI(key: string, value: number, seed?: number): string
|
||||
{
|
||||
const _seed = seed ?? Date.now();
|
||||
const hash = Bun.hash(key + value.toString(), _seed).toString(16);
|
||||
const pos = Math.floor(Math.random() * hash.length);
|
||||
const separator = String.fromCharCode(Math.floor(Math.random() * 26 + 96));
|
||||
|
||||
return Bun.zstdCompressSync(separator + value.toString(16).length + separator + hash.substring(0, pos) + value + hash.substring(pos) + separator + pos + separator + _seed.toString(16), { level: 1 }).toString('base64');
|
||||
}
|
||||
export function decryptURI(uri: string, key: string): number | undefined
|
||||
{
|
||||
const decoder = new TextDecoder();
|
||||
const _uri = decoder.decode(Bun.zstdDecompressSync(Buffer.from(uri, 'base64')));
|
||||
|
||||
const separator = _uri.charAt(0);
|
||||
const length = parseInt(_uri.substring(1, _uri.indexOf(separator, 1)), 10);
|
||||
const seed = parseInt(_uri.substring(_uri.lastIndexOf(separator) + 1), 16);
|
||||
const pos = parseInt(_uri.substring(_uri.lastIndexOf(separator, _uri.length - seed.toString(16).length - 2) + 1, _uri.lastIndexOf(separator)), 10);
|
||||
const _hash = _uri.substring(2 + length.toString(10).length, _uri.length - (2 + seed.toString(16).length + pos.toString(10).length));
|
||||
|
||||
const value = _hash.substring(pos, pos + length);
|
||||
const hash = _hash.substring(0, pos) + _hash.substring(pos + length);
|
||||
|
||||
if(Bun.hash(key + value, seed).toString(16) === hash)
|
||||
return parseInt(value, 10);
|
||||
else
|
||||
return undefined;
|
||||
}
|
||||
Reference in New Issue
Block a user