Add files via upload

This commit is contained in:
Rekushi authored and GitHub committed 2026-10-29 03:55:40 +00:00
commit 558a387b6e
35 files changed
+14482

No files matched your search

+24
View File
@@ -0,0 +1,24 @@
#pragma once
#include <string>
class AudioUploadServer {
public:
AudioUploadServer();
~AudioUploadServer();
AudioUploadServer(const AudioUploadServer&) = delete;
AudioUploadServer& operator=(const AudioUploadServer&) = delete;
bool start(const std::string& bindAddress, const std::string& uploadDirectory,
const std::string& assetsRoot, const std::string& sessionCode,
std::string& error, bool photoTransfer = false,
const std::string& noteSingular = "Switchnote");
void stop();
bool isRunning() const;
bool isConnected() const;
bool takeCompletedUpload(int& track);
void finishCompletedUpload(bool success);
private:
void* impl_ = nullptr;
};
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include <string>
#include <vector>
namespace branding {
struct Bundle {
std::string app;
std::string singular;
std::string plural;
std::vector<unsigned char> logo;
};
bool writeConfig(const std::string& path, const Bundle& bundle, std::string& error);
bool readConfig(const std::string& path, Bundle& bundle, std::string& error);
} // namespace branding
+23
View File
@@ -0,0 +1,23 @@
#pragma once
#include <string>
class BrandingConfigServer {
public:
BrandingConfigServer();
~BrandingConfigServer();
BrandingConfigServer(const BrandingConfigServer&) = delete;
BrandingConfigServer& operator=(const BrandingConfigServer&) = delete;
bool start(const std::string& bindAddress, const std::string& dataDirectory,
const std::string& assetsRoot, const std::string& sessionCode,
std::string& error, const std::string& appName,
const std::string& noteSingular, const std::string& notePlural);
void stop();
bool isRunning() const;
bool isConnected() const;
bool takeConfigUpdate();
private:
void* impl_ = nullptr;
};
+23
View File
@@ -0,0 +1,23 @@
#pragma once
#include "sppm.hpp"
#include <string>
namespace sppm {
// Exports a looping GIF89a animation. The GIF uses the document palette and
// composites layers A through D for each frame. GIF has no audio channel.
bool exportGif(const Document& document, const std::string& path,
std::string& error);
// Exports the selected cover frame as a lossless RGBA PNG.
bool exportPngCover(const Document& document, const std::string& path,
std::string& error);
// Exports a Motion-JPEG MP4 animation. Frames are composited over white at
// native Switchnote resolution; audio tracks are not muxed.
bool exportMp4(const Document& document, const std::string& path,
std::string& error);
} // namespace sppm
+162
View File
@@ -0,0 +1,162 @@
#pragma once
#include <array>
#include <cstddef>
#include <cstdint>
#include <string>
#include <string_view>
#include <vector>
namespace sppm {
constexpr std::uint16_t kWidth = 640;
constexpr std::uint16_t kHeight = 360;
constexpr std::size_t kPixelsPerLayer = static_cast<std::size_t>(kWidth) * kHeight;
constexpr std::size_t kLayerCount = 4;
constexpr std::size_t kPaletteSize = 256;
constexpr std::size_t kMaxFrames = 9999;
constexpr std::size_t kMaxAudioTracks = 4;
struct Color {
std::uint8_t r = 0;
std::uint8_t g = 0;
std::uint8_t b = 0;
std::uint8_t a = 255;
};
using Palette = std::array<Color, kPaletteSize>;
// Palette index 0 is transparent. Other entries can be changed by the editor.
Palette defaultPalette();
struct Frame {
// A, B, C, D from front to back; one palette index per 640x360 pixel.
std::array<std::vector<std::uint8_t>, kLayerCount> layers;
Frame();
};
struct AudioTrack {
std::string name; // e.g. BGM, SE1, SE2, SE3
std::uint32_t sampleRate = 0; // 8000..48000 Hz
std::uint8_t channels = 1; // 1 or 2
std::uint8_t referenceFps = 0; // BGM's native animation speed; 0 means use the note's speed
std::uint8_t referenceSpeed = 0; // SPPM v3 BGM speed index (1..8); 0 means legacy fps
std::vector<std::uint16_t> frameTriggers; // SE cues; BGM always starts at frame 0
std::vector<std::int16_t> pcm; // interleaved signed 16-bit samples
};
// A public identity is safe to put in an .sppm file. It contains an Ed25519
// verification key and a one-way, app-specific device tag; neither field
// exposes a raw console identifier.
struct PublicIdentity {
std::array<std::uint8_t, 32> key{};
std::array<std::uint8_t, 16> deviceTag{};
};
struct SigningIdentity {
PublicIdentity publicIdentity;
std::array<std::uint8_t, 64> secretKey{};
// Present only to keep validating pre-v3 console-HMAC files after migration.
std::array<std::uint8_t, 32> legacyHmacKey{};
};
struct Metadata {
std::string title;
std::string description;
std::string authorName;
std::string originalAuthorName;
std::string lastEditorName;
// Creator identities, not file IDs. Exactly 16 uppercase hexadecimal chars.
std::string authorFsid;
std::string originalAuthorFsid;
std::string lastEditorFsid;
// Present for v3 public-key-signed files. Zero values indicate a legacy
// author record which cannot be retrospectively cryptographically bound.
PublicIdentity authorIdentity;
PublicIdentity originalAuthorIdentity;
PublicIdentity lastEditorIdentity;
// File lineage IDs. parentId is empty only for an original Switchnote.
std::string currentId;
std::string rootId;
std::string parentId;
std::uint64_t createdUnixSeconds = 0;
std::uint64_t modifiedUnixSeconds = 0;
std::uint32_t coverFrame = 0;
std::uint8_t fps = 12;
std::uint8_t speed = 0; // SPPM v3 DSi speed index (1..8); 0 means legacy fps
bool locked = false;
bool allowSpinoffs = true;
bool bgmFollowsSpeed = true;
bool loopPlayback = true;
};
struct Document {
Metadata metadata;
Palette palette = defaultPalette();
std::vector<Frame> frames;
std::vector<AudioTrack> audioTracks;
};
bool isValidFsid(std::string_view fsid);
bool hasPublicIdentity(const PublicIdentity& identity);
std::string deriveFsid(const PublicIdentity& identity);
std::string identityFingerprint(const PublicIdentity& identity);
std::array<std::uint8_t, 16> deriveDeviceTag(const std::vector<std::uint8_t>& deviceMaterial);
std::array<std::uint8_t, 32> deriveDeviceWrapKey(const std::vector<std::uint8_t>& deviceMaterial,
const std::array<std::uint8_t, 16>& salt);
bool createSigningIdentity(const std::array<std::uint8_t, 16>& deviceTag,
SigningIdentity& identity, std::string& error);
bool sealSigningSecret(const SigningIdentity& identity,
const std::array<std::uint8_t, 32>& wrapKey,
const std::array<std::uint8_t, 24>& nonce,
std::array<std::uint8_t, 128>& sealed, std::string& error);
bool unsealSigningSecret(const std::array<std::uint8_t, 128>& sealed,
const std::array<std::uint8_t, 32>& wrapKey,
const std::array<std::uint8_t, 24>& nonce,
SigningIdentity& identity, std::string& error);
// Domain-separated 64-bit ID helper used for non-identity note and lineage IDs.
// Creator FSIDs are instead derived from PublicIdentity.
std::string deriveFsid(const std::array<std::uint8_t, 32>& secret,
const std::array<std::uint8_t, 16>& nonce,
std::string_view domain);
bool validate(const Document& document, std::string& error);
double frameRate(const Metadata& metadata);
bool serialize(const Document& document, std::vector<std::uint8_t>& bytes,
std::string& error);
bool deserialize(const std::vector<std::uint8_t>& bytes, Document& document,
std::string& error);
bool loadFile(const std::string& path, Document& document, std::string& error);
bool saveFile(const std::string& path, const Document& document, std::string& error);
// Console-local authenticated .sppm envelopes. Legacy v1 notes remain readable;
// new saves include a 256-bit HMAC-SHA-256 footer verified with the local key.
bool deserializeSigned(const std::vector<std::uint8_t>& bytes, Document& document,
const std::array<std::uint8_t, 32>& signingKey,
std::string& error);
bool loadSignedFile(const std::string& path, Document& document,
const std::array<std::uint8_t, 32>& signingKey,
std::string& error);
bool saveSignedFile(const std::string& path, const Document& document,
const std::array<std::uint8_t, 32>& signingKey,
std::string& error);
// v3 is publicly verifiable: no console-local secret is needed to validate a
// received file. It signs a domain-separated SHA-256 digest with Ed25519.
bool savePublicSignedFile(const std::string& path, const Document& document,
const SigningIdentity& identity, std::string& error);
bool signMessage(const SigningIdentity& identity, const std::uint8_t* message,
std::size_t messageSize, std::array<std::uint8_t, 64>& signature,
std::string& error);
// Preserves the original author and root ID, while giving the fork a new
// current ID, parent ID, author, creation time and editable state.
bool createSpinoff(const Document& parent, std::string_view newAuthorName,
std::string_view newAuthorFsid, std::string_view newCurrentId,
std::uint64_t nowUnixSeconds, Document& child,
std::string& error);
} // namespace sppm