pysspm-rhythia


Namepysspm-rhythia JSON
Version 0.2.2 PyPI version JSON
download
home_pagehttps://github.com/David-Jed/pysspm
SummaryA Python library dedicated to reading, writing, and modifying the Rhythia SSPM file format
upload_time2024-12-12 07:22:36
maintainerNone
docs_urlNone
authorDavid Jedlovsky
requires_python>=3.7
licenseNone
keywords rhythia sound space sspm rhythm game pysspm-rhythia pysspm
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # pysspm-rhythia

The official python library dedicated to reading, writing, and modifying the SSPM file format from the video game "Rhythia".

> ***Note: Any version before 0.1.5 does not work in python.***

## SSPM libray information

The main library includes these features:

> 1. Reading .SSPM files
> 2. Modifying SSPM data
> 3. Writing .SSPM files

Extras:

> 1. Difficulty Calculation (W.I.P)
> 2. Note Classification (semi-stable)

## How to install/use

To install the library, run:

```bash
pip install pysspm-rythia
```

to start using the library, create a python script and load up pysspm.

```python
from pysspm_rhythia import SSPMParser


parser = SSPMParser()

# Example of loading a SSPMfile
parser.ReadSSPM("*.sspm")

# Example of turning it into a roblox sound space file

with open("output.txt", "w") as f:
    f.write(parser.NOTES2TEXT())

```

> *Functionality does not end there. When reading files, you have full access to all the metadata, and other information stored in the variables.*

**Some common variables you will find are:**

1. `coverBytes` the byteform of the image if cover was found
2. `audioBytes` the byteform of the audio in `.mp3` form if audio was found
3. `Header`: {"Signature": ..., "Version": ...}
4. `Hash`: a SHA-1 hash of the markers (notes) in the map
5. `mapID`: A unique combination using the mappers and map name*
6. `mappers`: a list containing each mapper.
7. `mapName`: The name given to the map.
8. `songName`: The original name of the audio before imported. Usually left as artist name - song name
9. `customValues`: NOT IMPLEMENTED | will return a dictionary of found custom blocks.
10. `isQuantum`: Determins if the level contains ANY float value notes.
11. `Notes`: A list of tuples containing all notes. | Example of what it Notes is: `[(x, y, ms), (x, y, ms), (x, y, ms) . . .]`

```python
from pysspm_rhythia import SSPMParser


parser = SSPMParser()

# Example of loading a SSPMfile
parser.ReadSSPM("*.sspm")

# changing the decal to be a different image
if parser.hasCover[0] == 0: # hasCover is originally in byteform | Can be 0x00 or 0x01
    with open("cover.png", 'rb') as f:
        parser.coverBytes = f.read() # reading the BYTES of the image

# Finally save the sspm file with the newly configured settings
sspmFileBytes = parser.WriteSSPM()

with open('sspmfile.sspm', "wb") as f:
    f.write(sspmFileBytes)

```

Alternativly, you can pass in arguments into WriteSSPM function directly

```py
from pysspm_rhythia import SSPMParser

parser = SSPMParser()
parser.ReadSSPM("*.sspm")

mappers = parser.Mappers.extend('DigitalDemon') # adding another mapper to the mapper list
parser.WriteSSPM('./SSPMFile.sspm', mappers=mappers)
```

## Advanced guide

This shows the more advanced things you can do by giving examples of custom written code.

```python
from pysspm_rhythia import SSPMParser
from random import randint

parser = SSPMParser()

parser.ReadSSPM("*.sspm") # reading the sspm file

sigHeader = parser.Header.get("Signature") # 4 byte header | should always be: b"\x53\x53\x2b\x6d"
ver = parser.Header.get("Version") # stored as 2 or 1
sspmHash = parser.Hash # Storing the hash

if randint(0, 5) == 5:
    parser.Notes = parser.Notes.extend((1, 1, (parser.Notes[-1][2]+200))) # adding a center note (1,1), with ms of last note + 200

newSSPM = parser.WriteSSPM(mappers=["DigitalDemon", "Someone else"], mapName="Possibly modified map haha")

# comparing the note hashes
newSSPMHash = parser.Hash
if newSSPMHash == sspmhash:
    with open("UnmodifiedMap.sspm", 'wb') as f:
        f.write(newSSPM)
else:
    raise Warning("Map does not match original hash. Map notes were modified from the original!!!")


```

> Code shows off how hashes are calculated to prevent changes between levels. Could be used for security and integrity of the notes.

*More advanced documentation will be added in the near future...*

## Function Documentation

A in-depth list of things you can do with this library

```py
SSPMParser()
```

> Initializes the sspm library parser

```py
def WriteSSPM(self, filename: str = None, debug: bool = False, **kwargs) -> bytearray | None:
```

> Creates a SSPM v2 file based on variables passed in, or already set.

*If no filepath is passed in, it will return file as bytes* <br>
*Note: current version of pysspm-rhythia requires audio as a parameter for v2 filetype*

**Variables that need to be covered:**

1. `coverImage`: Cover image in bytes form, or None
2. `audioBytes`: Audio in bytes form, or None
3. `Difficulty`: one of Difficulties dictionary options, or 0x00 - 05 OR "N/A", "Easy", "Medium", "Hard", "Logic", "Tasukete"
4. `mapName`: The name of the map. Rhythia guidelines suggests `artist name - song name`
5. `mappers`: a list of strings containing the mapper(s)
6. `notes`: a list of tuples as shown below

<br>

```python
# (x, y, ms)
self.notes = [
 (1, 2, 1685), # X, Y, MS
 (1.22521, 0.156781, 2000)
]#...
```

***Notes can sometimes be unordered***

<br>

`**kwargs`: pass in any of the variables shown above.

Example usage:

```python
    from pysspm_rhythia import SSPMParser
        
    sspm = SSPMParser()
    sspm.ReadSSPM("*.sspm") # reads
    sspm.Difficulty = 5 # changes difficulty to Tasukete
        
    with open(output_path+".sspm", "wb") as f:
        f.write(sspm.WriteSSPM())
```

**ReadSSPM**

```py
def ReadSSPM(self, file: str | BinaryIO, debug: bool = False):
```

> Reads and processes any SSPM file. <br>

`File:` Takes in directory of sspm, or BinaryIO object stored in memory.
`debug:` Useful for getting readable outputs of steps taken.

#### Warning

***SSPM (Sound space plus map file) version 1 is not supported at this time. loading this file may raise errors***

#### Returns

1. `coverBytes` if cover was found
2. `audioBytes` if audio was found
3. `Header`: {"Signature": ..., "Version": ...}
4. `Hash`: a SHA-1 hash of the markers in the map
5. `mapID`: A unique combination using the mappers and map name*
6. `mappers`: a list containing each mapper.
7. `mapName`: The name given to the map.
8. `songName`: The original name of the audio before imported. Usually left as artist name - song name
9. `customValues`: NOT IMPLEMENTED | will return a dictionary of found custom blocks.
10. `isQuantum`: Determins if the level contains ANY float value notes.
11. `Notes`: A list of tuples containing all notes.

Example of what it Notes is: `[(x, y, ms), (x, y, ms), (x, y, ms) . . .]`

> ***Returns itself***

## Roadmap (May get completed)

TODO: (In order of priority)

- Add typing support for library ✔️
- add proper documentation on github
- add proper documentation in code ✔️
- add loading of sspmV2  ✔️
- add support for creating sspmV2 ✔️
- clean up unused variables from @self ✔️
- add support for sspmv1 loading ✔️ (Thank you fogsaturate)
- support multiple versions of sspm
- add custom block support in loading
- Drop numpy dependency
- Implement Extras difficulty calc
- Implement simple note ordering function
- Support for Pheonix Filetype (When I get my hands on the data structure)

Made with 💖 by DigitalDemon (David Jed)

> Documentation last updated: `2024-12-12` | `V0.2.2`

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/David-Jed/pysspm",
    "name": "pysspm-rhythia",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "Rhythia, Sound space, SSPM, Rhythm game, pysspm-rhythia, pysspm",
    "author": "David Jedlovsky",
    "author_email": "Dev.DavidJed@gmail.com",
    "download_url": null,
    "platform": null,
    "description": "# pysspm-rhythia\r\n\r\nThe official python library dedicated to reading, writing, and modifying the SSPM file format from the video game \"Rhythia\".\r\n\r\n> ***Note: Any version before 0.1.5 does not work in python.***\r\n\r\n## SSPM libray information\r\n\r\nThe main library includes these features:\r\n\r\n> 1. Reading .SSPM files\r\n> 2. Modifying SSPM data\r\n> 3. Writing .SSPM files\r\n\r\nExtras:\r\n\r\n> 1. Difficulty Calculation (W.I.P)\r\n> 2. Note Classification (semi-stable)\r\n\r\n## How to install/use\r\n\r\nTo install the library, run:\r\n\r\n```bash\r\npip install pysspm-rythia\r\n```\r\n\r\nto start using the library, create a python script and load up pysspm.\r\n\r\n```python\r\nfrom pysspm_rhythia import SSPMParser\r\n\r\n\r\nparser = SSPMParser()\r\n\r\n# Example of loading a SSPMfile\r\nparser.ReadSSPM(\"*.sspm\")\r\n\r\n# Example of turning it into a roblox sound space file\r\n\r\nwith open(\"output.txt\", \"w\") as f:\r\n    f.write(parser.NOTES2TEXT())\r\n\r\n```\r\n\r\n> *Functionality does not end there. When reading files, you have full access to all the metadata, and other information stored in the variables.*\r\n\r\n**Some common variables you will find are:**\r\n\r\n1. `coverBytes` the byteform of the image if cover was found\r\n2. `audioBytes` the byteform of the audio in `.mp3` form if audio was found\r\n3. `Header`: {\"Signature\": ..., \"Version\": ...}\r\n4. `Hash`: a SHA-1 hash of the markers (notes) in the map\r\n5. `mapID`: A unique combination using the mappers and map name*\r\n6. `mappers`: a list containing each mapper.\r\n7. `mapName`: The name given to the map.\r\n8. `songName`: The original name of the audio before imported. Usually left as artist name - song name\r\n9. `customValues`: NOT IMPLEMENTED | will return a dictionary of found custom blocks.\r\n10. `isQuantum`: Determins if the level contains ANY float value notes.\r\n11. `Notes`: A list of tuples containing all notes. | Example of what it Notes is: `[(x, y, ms), (x, y, ms), (x, y, ms) . . .]`\r\n\r\n```python\r\nfrom pysspm_rhythia import SSPMParser\r\n\r\n\r\nparser = SSPMParser()\r\n\r\n# Example of loading a SSPMfile\r\nparser.ReadSSPM(\"*.sspm\")\r\n\r\n# changing the decal to be a different image\r\nif parser.hasCover[0] == 0: # hasCover is originally in byteform | Can be 0x00 or 0x01\r\n    with open(\"cover.png\", 'rb') as f:\r\n        parser.coverBytes = f.read() # reading the BYTES of the image\r\n\r\n# Finally save the sspm file with the newly configured settings\r\nsspmFileBytes = parser.WriteSSPM()\r\n\r\nwith open('sspmfile.sspm', \"wb\") as f:\r\n    f.write(sspmFileBytes)\r\n\r\n```\r\n\r\nAlternativly, you can pass in arguments into WriteSSPM function directly\r\n\r\n```py\r\nfrom pysspm_rhythia import SSPMParser\r\n\r\nparser = SSPMParser()\r\nparser.ReadSSPM(\"*.sspm\")\r\n\r\nmappers = parser.Mappers.extend('DigitalDemon') # adding another mapper to the mapper list\r\nparser.WriteSSPM('./SSPMFile.sspm', mappers=mappers)\r\n```\r\n\r\n## Advanced guide\r\n\r\nThis shows the more advanced things you can do by giving examples of custom written code.\r\n\r\n```python\r\nfrom pysspm_rhythia import SSPMParser\r\nfrom random import randint\r\n\r\nparser = SSPMParser()\r\n\r\nparser.ReadSSPM(\"*.sspm\") # reading the sspm file\r\n\r\nsigHeader = parser.Header.get(\"Signature\") # 4 byte header | should always be: b\"\\x53\\x53\\x2b\\x6d\"\r\nver = parser.Header.get(\"Version\") # stored as 2 or 1\r\nsspmHash = parser.Hash # Storing the hash\r\n\r\nif randint(0, 5) == 5:\r\n    parser.Notes = parser.Notes.extend((1, 1, (parser.Notes[-1][2]+200))) # adding a center note (1,1), with ms of last note + 200\r\n\r\nnewSSPM = parser.WriteSSPM(mappers=[\"DigitalDemon\", \"Someone else\"], mapName=\"Possibly modified map haha\")\r\n\r\n# comparing the note hashes\r\nnewSSPMHash = parser.Hash\r\nif newSSPMHash == sspmhash:\r\n    with open(\"UnmodifiedMap.sspm\", 'wb') as f:\r\n        f.write(newSSPM)\r\nelse:\r\n    raise Warning(\"Map does not match original hash. Map notes were modified from the original!!!\")\r\n\r\n\r\n```\r\n\r\n> Code shows off how hashes are calculated to prevent changes between levels. Could be used for security and integrity of the notes.\r\n\r\n*More advanced documentation will be added in the near future...*\r\n\r\n## Function Documentation\r\n\r\nA in-depth list of things you can do with this library\r\n\r\n```py\r\nSSPMParser()\r\n```\r\n\r\n> Initializes the sspm library parser\r\n\r\n```py\r\ndef WriteSSPM(self, filename: str = None, debug: bool = False, **kwargs) -> bytearray | None:\r\n```\r\n\r\n> Creates a SSPM v2 file based on variables passed in, or already set.\r\n\r\n*If no filepath is passed in, it will return file as bytes* <br>\r\n*Note: current version of pysspm-rhythia requires audio as a parameter for v2 filetype*\r\n\r\n**Variables that need to be covered:**\r\n\r\n1. `coverImage`: Cover image in bytes form, or None\r\n2. `audioBytes`: Audio in bytes form, or None\r\n3. `Difficulty`: one of Difficulties dictionary options, or 0x00 - 05 OR \"N/A\", \"Easy\", \"Medium\", \"Hard\", \"Logic\", \"Tasukete\"\r\n4. `mapName`: The name of the map. Rhythia guidelines suggests `artist name - song name`\r\n5. `mappers`: a list of strings containing the mapper(s)\r\n6. `notes`: a list of tuples as shown below\r\n\r\n<br>\r\n\r\n```python\r\n# (x, y, ms)\r\nself.notes = [\r\n (1, 2, 1685), # X, Y, MS\r\n (1.22521, 0.156781, 2000)\r\n]#...\r\n```\r\n\r\n***Notes can sometimes be unordered***\r\n\r\n<br>\r\n\r\n`**kwargs`: pass in any of the variables shown above.\r\n\r\nExample usage:\r\n\r\n```python\r\n    from pysspm_rhythia import SSPMParser\r\n        \r\n    sspm = SSPMParser()\r\n    sspm.ReadSSPM(\"*.sspm\") # reads\r\n    sspm.Difficulty = 5 # changes difficulty to Tasukete\r\n        \r\n    with open(output_path+\".sspm\", \"wb\") as f:\r\n        f.write(sspm.WriteSSPM())\r\n```\r\n\r\n**ReadSSPM**\r\n\r\n```py\r\ndef ReadSSPM(self, file: str | BinaryIO, debug: bool = False):\r\n```\r\n\r\n> Reads and processes any SSPM file. <br>\r\n\r\n`File:` Takes in directory of sspm, or BinaryIO object stored in memory.\r\n`debug:` Useful for getting readable outputs of steps taken.\r\n\r\n#### Warning\r\n\r\n***SSPM (Sound space plus map file) version 1 is not supported at this time. loading this file may raise errors***\r\n\r\n#### Returns\r\n\r\n1. `coverBytes` if cover was found\r\n2. `audioBytes` if audio was found\r\n3. `Header`: {\"Signature\": ..., \"Version\": ...}\r\n4. `Hash`: a SHA-1 hash of the markers in the map\r\n5. `mapID`: A unique combination using the mappers and map name*\r\n6. `mappers`: a list containing each mapper.\r\n7. `mapName`: The name given to the map.\r\n8. `songName`: The original name of the audio before imported. Usually left as artist name - song name\r\n9. `customValues`: NOT IMPLEMENTED | will return a dictionary of found custom blocks.\r\n10. `isQuantum`: Determins if the level contains ANY float value notes.\r\n11. `Notes`: A list of tuples containing all notes.\r\n\r\nExample of what it Notes is: `[(x, y, ms), (x, y, ms), (x, y, ms) . . .]`\r\n\r\n> ***Returns itself***\r\n\r\n## Roadmap (May get completed)\r\n\r\nTODO: (In order of priority)\r\n\r\n- Add typing support for library \u2714\ufe0f\r\n- add proper documentation on github\r\n- add proper documentation in code \u2714\ufe0f\r\n- add loading of sspmV2  \u2714\ufe0f\r\n- add support for creating sspmV2 \u2714\ufe0f\r\n- clean up unused variables from @self \u2714\ufe0f\r\n- add support for sspmv1 loading \u2714\ufe0f (Thank you fogsaturate)\r\n- support multiple versions of sspm\r\n- add custom block support in loading\r\n- Drop numpy dependency\r\n- Implement Extras difficulty calc\r\n- Implement simple note ordering function\r\n- Support for Pheonix Filetype (When I get my hands on the data structure)\r\n\r\nMade with \ud83d\udc96 by DigitalDemon (David Jed)\r\n\r\n> Documentation last updated: `2024-12-12` | `V0.2.2`\r\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A Python library dedicated to reading, writing, and modifying the Rhythia SSPM file format",
    "version": "0.2.2",
    "project_urls": {
        "Homepage": "https://github.com/David-Jed/pysspm"
    },
    "split_keywords": [
        "rhythia",
        " sound space",
        " sspm",
        " rhythm game",
        " pysspm-rhythia",
        " pysspm"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "336ed867d0f914009d0d84510e3041042e1edeeb41f7ec7af0f5adfa0a0a3858",
                "md5": "b5335eb0b28b2cb8495474604991b13b",
                "sha256": "551d510450378a7f6a1fe05cb44ee9e76c267370ec231cca6b7f131d3e373855"
            },
            "downloads": -1,
            "filename": "pysspm_rhythia-0.2.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "b5335eb0b28b2cb8495474604991b13b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 17681,
            "upload_time": "2024-12-12T07:22:36",
            "upload_time_iso_8601": "2024-12-12T07:22:36.538937Z",
            "url": "https://files.pythonhosted.org/packages/33/6e/d867d0f914009d0d84510e3041042e1edeeb41f7ec7af0f5adfa0a0a3858/pysspm_rhythia-0.2.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-12-12 07:22:36",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "David-Jed",
    "github_project": "pysspm",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "pysspm-rhythia"
}
        
Elapsed time: 0.47956s