{ "info": { "author": "Ben", "author_email": "ben@solero.me", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 2.7" ], "description": "# Canon\r\n\r\n**This library is new and relatively untested, please be cautious when choosing to use this for your project.**\r\n\r\nCanon is a tool for emulating the compression found in two of the Club Penguin mini-games.\r\n\r\n- [Sound Studio](https://icer.ink/media1.clubpenguin.com/play/v2/games/mixmaster)\r\n- [Puffle Launch](https://icer.ink/media1.clubpenguin.com/play/v2/games/canon)\r\n\r\nCanon was written for the Club Penguin server emulator, [Houdini](https://github.com/solero/houdini), however it may be used for other emulators or perhaps generating your own game saves.\r\n\r\nThe compression algorithm was taken from the Club Penguin client (`com.clubpenguin.lib.data.compression.Compressor`).\r\n\r\nThe library currently only has utility functions for converting Puffle Launch game saves into objects, however it can convert any compressed string into a `Canon._DataSet`.\r\n\r\n## Installation\r\n\r\nCanon is now available on the PyPI, hurray!\r\n\r\n`pip install Canon`\r\n\r\n~~Canon is not available on PyPI. You have to clone the repository and import it manually.~~\r\n\r\n` $ git clone https://github.com/ketnipz/canon`\r\n\r\n## Usage\r\n\r\n### Decompressing a game save\r\nThis is the most common usage, and it how the library is used inside Houdini.\r\n\r\n```py\r\n#!/usr/bin/env python\r\n# -*- coding: utf-8 -*-\r\n\r\nfrom Canon import Compressor\r\nfrom Canon.Data.Launch import load_data_set_into_object\r\n\r\nif __name__ == \"__main__\":\r\n\tdecompressed = Compressor.decompress(u\"\u0210 \u0210 \u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0210\u3e80\u0210\u0011\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0220\u0003\u0211\u0001\u0211\u0001\u0140\")\r\n\tnew_data = load_data_set_into_object(decompressed, filtered=True)\r\n\tprint(new_data)\r\n\r\n\t# Result: {0: {'PuffleOs': 32, 'BestTime': 16000, 'TurboDone': True}, 1: {'PuffleOs': 32, 'BestTime': 17, 'TurboDone': True}}\r\n```\r\n\r\n### Generating a save game\r\nWhilst canon can be used to convert a unicode save game into an object, it can also be used to do the reverse!\r\n\r\n```py\r\n#!/usr/bin/env python\r\n# -*- coding: utf-8 -*-\r\n\r\nfrom Canon import Compressor\r\nfrom Canon.Data.Launch import load_data_set_from_object\r\n\r\nif __name__ == \"__main__\":\r\n data = {\r\n 0: {\r\n \"PuffleOs\": 32,\r\n \"BestTime\": 16000,\r\n \"TurboDone\": True\r\n },\r\n 1: {\r\n \"PuffleOs\": 32,\r\n \"BestTime\": 17,\r\n \"TurboDone\": True\r\n }\r\n }\r\n\r\n new_data_set = load_data_set_from_object(data)\r\n compressed = Compressor.compress(new_data_set)\r\n print(compressed)\r\n\r\n # Result: u\"\u0210 \u0210 \u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0211\u0001\u0210\u3e80\u0210\u0011\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0210\u0258\u0220\u0003\u0211\u0001\u0211\u0001\u0140\"\r\n```\r\n\r\n### Filter flag\r\n\r\n`load_data_set_into_object` has a parameter `filtered`. This can be used to filter level results which have not been completed yet. Since Puffle Launch game saves contain the data for every level, you may just want the ones which have been completed, if this is the case, pass `filter= True` into the function.\r\n\r\n```py\r\nnew_data = Compressor.load_data_set_into_object(decompressed)\r\nprint(new_data)\r\n# Result: {0: {'PuffleOs': 32, 'BestTime': 16000, 'TurboDone': True}, 1: {'PuffleOs': 32, 'BestTime': 17, 'TurboDone': True}, 2: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 3: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 4: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 5: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 6: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 7: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 8: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 9: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 10: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 11: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 12: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 13: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 14: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 15: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 16: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 17: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 18: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 19: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 20: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 21: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 22: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 23: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 24: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 25: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 26: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 27: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 28: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 29: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 30: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 31: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 32: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 33: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 34: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}, 35: {'PuffleOs': 0, 'BestTime': 600, 'TurboDone': False}}\r\n\r\n```\r\n\r\n\r\n```py\r\nnew_data = Compressor.load_data_set_into_object(decompressed, filtered=True)\r\nprint(new_data)\r\n# Result: {0: {'PuffleOs': 32, 'BestTime': 16000, 'TurboDone': True}, 1: {'PuffleOs': 32, 'BestTime': 17, 'TurboDone': True}}\r\n```\r\n\r\n\r\n\r\n\r\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/ketnipz/Canon", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "canon", "package_url": "https://pypi.org/project/canon/", "platform": "", "project_url": "https://pypi.org/project/canon/", "project_urls": { "Homepage": "https://github.com/ketnipz/Canon" }, "release_url": "https://pypi.org/project/canon/0.0.1/", "requires_dist": null, "requires_python": "", "summary": "Canon is a tool for emulating the compression found in two of the Club Penguin mini-games.", "version": "0.0.1" }, "last_serial": 4503501, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "aae7dc59685e6d976f44f1eef1ee28c6", "sha256": "e6e8f917b45900841bdcb531a42c8a3c8300a02814f7d0420e389e6335cd65f4" }, "downloads": -1, "filename": "canon-0.0.1-py2-none-any.whl", "has_sig": false, "md5_digest": "aae7dc59685e6d976f44f1eef1ee28c6", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 6994, "upload_time": "2018-11-19T15:51:53", "url": "https://files.pythonhosted.org/packages/ae/9e/0467e276d9797c89f9463dd3651c4c065694e5ee627bee98c3239f043ece/canon-0.0.1-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "bbd9bbfa8487a0749d46a43dd3c7d98d", "sha256": "a1d99bea0e114486f4f86a32aa75da12bd69855eedd2d56331e6c682a7612d80" }, "downloads": -1, "filename": "canon-0.0.1.tar.gz", "has_sig": false, "md5_digest": "bbd9bbfa8487a0749d46a43dd3c7d98d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5030, "upload_time": "2018-11-19T15:51:55", "url": "https://files.pythonhosted.org/packages/51/97/d83d00cb2bd599c22b29dd9e2eda01b7386fd563d9ada57f2d8c0776137e/canon-0.0.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "aae7dc59685e6d976f44f1eef1ee28c6", "sha256": "e6e8f917b45900841bdcb531a42c8a3c8300a02814f7d0420e389e6335cd65f4" }, "downloads": -1, "filename": "canon-0.0.1-py2-none-any.whl", "has_sig": false, "md5_digest": "aae7dc59685e6d976f44f1eef1ee28c6", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 6994, "upload_time": "2018-11-19T15:51:53", "url": "https://files.pythonhosted.org/packages/ae/9e/0467e276d9797c89f9463dd3651c4c065694e5ee627bee98c3239f043ece/canon-0.0.1-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "bbd9bbfa8487a0749d46a43dd3c7d98d", "sha256": "a1d99bea0e114486f4f86a32aa75da12bd69855eedd2d56331e6c682a7612d80" }, "downloads": -1, "filename": "canon-0.0.1.tar.gz", "has_sig": false, "md5_digest": "bbd9bbfa8487a0749d46a43dd3c7d98d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5030, "upload_time": "2018-11-19T15:51:55", "url": "https://files.pythonhosted.org/packages/51/97/d83d00cb2bd599c22b29dd9e2eda01b7386fd563d9ada57f2d8c0776137e/canon-0.0.1.tar.gz" } ] }