{"id":35048431,"url":"https://github.com/biqqles/flair","last_synced_at":"2025-12-27T09:03:58.864Z","repository":{"id":54599445,"uuid":"248972060","full_name":"biqqles/flair","owner":"biqqles","description":"A novel client-side hook for Freelancer","archived":false,"fork":false,"pushed_at":"2021-05-28T12:23:43.000Z","size":94,"stargazers_count":3,"open_issues_count":1,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-24T14:58:42.743Z","etag":null,"topics":["freelancer","library"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/fl-flair/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/biqqles.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-21T12:32:00.000Z","updated_at":"2022-03-12T23:37:34.000Z","dependencies_parsed_at":"2022-08-13T21:00:16.855Z","dependency_job_id":null,"html_url":"https://github.com/biqqles/flair","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/biqqles/flair","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/biqqles%2Fflair","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/biqqles%2Fflair/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/biqqles%2Fflair/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/biqqles%2Fflair/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/biqqles","download_url":"https://codeload.github.com/biqqles/flair/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/biqqles%2Fflair/sbom","scorecard":{"id":239546,"data":{"date":"2025-08-11","repo":{"name":"github.com/biqqles/flair","commit":"892437ce92d770ecbd4c8594cace68dbc1c25d52"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.5,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/15 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.md:0","Info: FSF or OSI recognized license: Mozilla Public License 2.0: LICENSE.md:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.5.2 not signed: https://api.github.com/repos/biqqles/flair/releases/43762715","Warn: release artifact v0.5.1 not signed: https://api.github.com/repos/biqqles/flair/releases/43757806","Warn: release artifact v0.5 not signed: https://api.github.com/repos/biqqles/flair/releases/37990020","Warn: release artifact v0.4 not signed: https://api.github.com/repos/biqqles/flair/releases/31498471","Warn: release artifact v0.3 not signed: https://api.github.com/repos/biqqles/flair/releases/31220003","Warn: release artifact v0.5.2 does not have provenance: https://api.github.com/repos/biqqles/flair/releases/43762715","Warn: release artifact v0.5.1 does not have provenance: https://api.github.com/repos/biqqles/flair/releases/43757806","Warn: release artifact v0.5 does not have provenance: https://api.github.com/repos/biqqles/flair/releases/37990020","Warn: release artifact v0.4 does not have provenance: https://api.github.com/repos/biqqles/flair/releases/31498471","Warn: release artifact v0.3 does not have provenance: https://api.github.com/repos/biqqles/flair/releases/31220003"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 16 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"53 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-3c5c-7235-994j","Warn: Project is vulnerable to: GHSA-3f63-hfp8-52jq","Warn: Project is vulnerable to: PYSEC-2021-41 / GHSA-3wvg-mj6g-m9cv","Warn: Project is vulnerable to: PYSEC-2020-77 / GHSA-3xv8-3j54-hgrp","Warn: Project is vulnerable to: PYSEC-2020-80 / GHSA-43fq-w8qq-v88h","Warn: Project is vulnerable to: GHSA-44wm-f244-xhp3","Warn: Project is vulnerable to: GHSA-4fx9-vc88-q2xc","Warn: Project is vulnerable to: PYSEC-2021-35 / GHSA-57h3-9rgr-c24m","Warn: Project is vulnerable to: PYSEC-2020-172 / GHSA-5gm3-px64-rw72","Warn: Project is vulnerable to: PYSEC-2021-331 / GHSA-7534-mm45-c74v","Warn: Project is vulnerable to: PYSEC-2021-92 / GHSA-7r7m-5h27-29hp","Warn: Project is vulnerable to: PYSEC-2020-78 / GHSA-8843-m7mw-mxqm","Warn: Project is vulnerable to: PYSEC-2023-227 / GHSA-8ghj-p4vj-mr35","Warn: Project is vulnerable to: PYSEC-2014-87 / GHSA-8m9x-pxwq-j236","Warn: Project is vulnerable to: PYSEC-2022-10 / GHSA-8vj2-vxx3-667w","Warn: Project is vulnerable to: PYSEC-2021-36 / GHSA-8xjq-8fcg-g5hw","Warn: Project is vulnerable to: PYSEC-2016-6 / GHSA-8xjv-v9xq-m5h9","Warn: Project is vulnerable to: PYSEC-2021-42 / GHSA-95q3-8gr9-gm8w","Warn: Project is vulnerable to: PYSEC-2022-168 / GHSA-9j59-75qj-795w","Warn: Project is vulnerable to: PYSEC-2014-10 / GHSA-cfmr-38g9-f2h7","Warn: Project is vulnerable to: PYSEC-2020-76 / GHSA-cqhg-xjhh-p8hf","Warn: Project is vulnerable to: PYSEC-2021-40 / GHSA-f4w8-cv6p-x6r5","Warn: Project is vulnerable to: PYSEC-2021-69 / GHSA-f5g8-5qq7-938w","Warn: Project is vulnerable to: PYSEC-2021-139 / GHSA-g6rj-rv7j-xwp4","Warn: Project is vulnerable to: PYSEC-2015-16 / GHSA-h5rf-vgqx-wjv2","Warn: Project is vulnerable to: PYSEC-2016-5 / GHSA-hggx-3h72-49ww","Warn: Project is vulnerable to: PYSEC-2020-84 / GHSA-hj69-c76v-86wr","Warn: Project is vulnerable to: PYSEC-2016-7 / GHSA-hvr8-466p-75rh","Warn: Project is vulnerable to: PYSEC-2015-15 / GHSA-j6f7-g425-4gmx","Warn: Project is vulnerable to: GHSA-j7hp-h8jx-5ppr","Warn: Project is vulnerable to: PYSEC-2019-110 / GHSA-j7mj-748x-7p78","Warn: Project is vulnerable to: GHSA-jgpv-4h4c-xhw3","Warn: Project is vulnerable to: PYSEC-2022-42979 / GHSA-m2vv-5vj5-2hm7","Warn: Project is vulnerable to: PYSEC-2021-37 / GHSA-mvg9-xffr-p774","Warn: Project is vulnerable to: PYSEC-2020-83 / GHSA-p49h-hjvm-jg3h","Warn: Project is vulnerable to: PYSEC-2022-8 / GHSA-pw3c-h7wp-cvhx","Warn: Project is vulnerable to: PYSEC-2021-93 / GHSA-q5hq-fp76-qmrc","Warn: Project is vulnerable to: PYSEC-2020-82 / GHSA-r7rm-8j6h-r933","Warn: Project is vulnerable to: PYSEC-2014-23 / GHSA-r854-96gq-rfg3","Warn: Project is vulnerable to: PYSEC-2016-8 / GHSA-rwr3-c2q8-gm56","Warn: Project is vulnerable to: PYSEC-2020-81 / GHSA-vcqg-3p29-xw73","Warn: Project is vulnerable to: PYSEC-2020-79 / GHSA-vj42-xq3r-hr3r","Warn: Project is vulnerable to: PYSEC-2021-70 / GHSA-vqcj-wrf2-7v73","Warn: Project is vulnerable to: PYSEC-2016-9 / GHSA-w4vg-rf63-f3j3","Warn: Project is vulnerable to: PYSEC-2014-22 / GHSA-x895-2wrm-hvp7","Warn: Project is vulnerable to: PYSEC-2022-9 / GHSA-xrcv-f9gm-v42c","Warn: Project is vulnerable to: PYSEC-2021-137","Warn: Project is vulnerable to: PYSEC-2021-138","Warn: Project is vulnerable to: PYSEC-2021-317","Warn: Project is vulnerable to: PYSEC-2021-38","Warn: Project is vulnerable to: PYSEC-2021-39","Warn: Project is vulnerable to: PYSEC-2021-94","Warn: Project is vulnerable to: PYSEC-2023-175"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-17T06:26:17.096Z","repository_id":54599445,"created_at":"2025-08-17T06:26:17.096Z","updated_at":"2025-08-17T06:26:17.096Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28076542,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-27T02:00:05.897Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["freelancer","library"],"created_at":"2025-12-27T09:03:25.543Z","updated_at":"2025-12-27T09:03:58.858Z","avatar_url":"https://github.com/biqqles.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# flair\n**flair** (*FreeLancer Augmentation and Inspection at Runtime*) is a client-side hook for the 2003 space sim [*Freelancer*](https://en.wikipedia.org/wiki/Freelancer_%28video_game%29) which requires no changes to the game files and no code to be injected into the game's process. It supports Freelancer running natively on Windows and also on Linux under WINE.\n\nflair achieves this through a combination of hooking user input, reading process memory and window interaction using the Win32 API or Linux syscalls, and an understanding of Freelancer's static data provided by [flint](https://github.com/biqqles/flint). Through these means flair allows the game's state to be inspected in real-time. It also allows the game client to be augmented, for example adding clipboard access to the game's chat box or implementing a custom command line interface.\n\n### Installation\nflair is on [PyPI](https://pypi.org/project/fl-flair/):\n\n```\npip install fl-flair\n```\n\nAlternatively you can install straight from this repository:\n\n```sh\npip install https://github.com/biqqles/flair/archive/master.zip -U\n```\n\nBuilt wheels are also available under [Releases](https://github.com/biqqles/flair/releases), as is a changelog. flair requires Python 3.6 or higher.\n\n### Basic usage\nflair includes a testing mode. To access it run `python -m flair \u003cpath_to_freelancer\u003e`. In this mode flair will load all built-in augmentations, print all events, and begin polling and printing the state of the game to the terminal. More on all of those later.\n\n### State and events\nBasic usage of flair relies on two main principles:\n\n - a [state object](#freelancerstate), which allows access to the game's state in real time (`flair.state`)\n - a simple [events system](#events) inspired by Qt's signals and slots mechanism (`flair.events`)\n \nTo use flair in your own programs, first call `flair.set_install_dir` to bind flair to the Freelancer installation it is to hook. This creates a `FreelancerState` instance at `flair.state`. This will automatically begin polling the game (by default every 1 second). The polling frequency only affects when events are emitted - accesses to `FreelancerState` will cause the immediate state of the game to be read (in most cases).\n\nIf you want to do more than read the state of the game and receive events, you should use the hook directly. An example of this situation is creating augmentations [augmentations](#augmentations).\n\nAll these concepts are discussed in detail below.\n\n## API\n### `FreelancerState`\n\u003e Source: [flair/inspect/state.py](flair/inspect/state.py)\n\nAs mentioned earlier, `flair.FreelancerState` allows various parameters of the game's state to be accessed. Instances of this class have the following methods and properties:\n\n|Methods             |Type             |Notes                                                                                    |\n|:-------------------|:----------------|:----------------------------------------------------------------------------------------|\n|`begin_polling(period)`|              |Begin polling the game's state and emitting events. Called upon instantiation by default.|\n|`stop_polling()`    |                 |Stop polling the game's state and emitting events.                                       |\n|`refresh()`         |                 |Cause state variables to refresh themselves                                              |\n|**Properties**      |**Type**         |**Notes**                                                                                |\n|**`running`**       |`bool`           |Whether an instance of the game is running                                               |\n|**`foreground`**    |`bool`           |Whether an instance of the game is in the foreground and accepting input                 |\n|**`chat_box`**      |`bool`           |Whether the chat box is open                                                             |\n|**`account`**       |`str`            |The \"name\" (hash) of the currently active account, taken from the registry               |\n|**`mouseover`**     |`str`            |See documentation in hook/process.                                                       |\n|**`character_loaded`**|`bool`         |Whether a character is currently loaded (i.e. the player is logged in), either in SP or MP|\n|**`name`**          |`Optional[str]`  |The name of the currently active character if there is one, otherwise None               |\n|**`credits`**       |`Optional[int]`  |The number of credits the active character has if there is one, otherwise None           |\n|**`system`**        |`Optional[str]`  |The display name (e.g. \"New London\") of the system the active character is in if there is one, otherwise None|\n|**`base`**          |`Optional[str]`  |The display name (e.g. \"The Ring\") of the base the active character last docked at if there is one, otherwise None|\n|**`pos`**           |`Optional[PosVector]`|The position vector of the active character if there is one, otherwise None          |\n|**`docked`**        |`Optional[bool]` |Whether the active character is presently docked at a base if there is one, otherwise None|\n\nA `FreelancerState` instance at `flair.state` will be created when you call `flair.set_install_dir`. You should not normally need to initialise `FreelancerState` yourself. If for some reason you wanted to hook two instances of Freelancer running simultaneously, you should use two different Python processes.\n\n\n### Events\n\u003e Source: [flair/inspect/events.py](flair/inspect/events.py)\n\nEvents are used by \"connecting\" them to functions (or vice-versa). flair automatically \"emits\" these events when necessary. For example `flair.events.message_sent.connect(lambda message: print(message))` causes that lambda to be called every time flair emits the `message_sent` signal, thereby printing the contents of the message to the terminal.\n\nThe connected function should take a keyword argument with the name specified in the schema column.\n \n|Event                       |Emitted when                       | Parameter schema                                              |\n|:---------------------------|:----------------------------------|:--------------------------------------------------------------|\n|**`character_changed`**     |New character loaded               |`name`: new character name                                     |\n|**`account_changed`**       |Active (registry) account changed  |`account`: new account code                                    |\n|**`system_changed`**        |New system entered                 |`system`: New system display name                              |\n|**`docked`**                |Docked base (respawn point) changed|`base`: new base display name                                  |\n|**`undocked`**              |Undocked from base                 |N/A                                                            |\n|**`credits_changed`**       |Credit balance changed             |`balance`: new credit balance                                  |\n|**`message_sent`**          |New message sent by player         |`message`: message text                                        |\n|**`chat_box_opened`**       |Chat box opened                    |`message`: message text                                        |\n|**`chat_box_closed`**       |Chat box closed                    |`message_sent`: whether message sent                           |\n|**`freelancer_started`**    |Freelancer process launched        |N/A                                                            |\n|**`freelancer_stopped`**    |Freelancer process closed          |N/A                                                            |\n|**`switched_to_foreground`**|Freelancer switched to foreground  |N/A                                                            |\n|**`switched_to_background`**|Freelancer switched to background  |N/A                                                            |\n\n\n### Hook\n[`flair/hook`](flair/hook) contains the hook itself. It is separated into the following modules:\n\n#### Input\n\u003e Source: [flair/hook/input](flair/hook/input)\n\n##### `bind_hotkey(combination, function)`\nAdds a hotkey which is only active when Freelancer is in the foreground.\n\n##### `unbind_hotkey(combination, function)`\nRemoves a hotkey that has been bound in the Freelancer window.\n\n##### `queue_display_text(text: str)`\nQueue text to be displayed to the user. If Freelancer is in the foreground and the chat box is closed,\nthis will be shown immediately. Otherwise, the text will be shown as soon as both these conditions are true.\n\n##### `send_message(message: str, private=True)`\nInserts `message` into the chat box and sends it. If `private` is true, send to the Console.\n\n##### `inject_keys(key: str, after_delay=0.0)`\nInject a key combination into the Freelancer window.\n\n##### `inject_text(text: str)`\nInject text into the chat box.\n\n##### `initialise_hotkey_hooks()`\nInitialise hotkey hooks for Freelancer. Should be run when, and only when, the Freelancer window is brought into\nthe foreground.\n\n##### `terminate_hotkey_hooks()`\nRelease hotkey hooks for Freelancer. Should be run when, and only when, the Freelancer window is put into the\nbackground.\n\n##### `on_chat_box_opened()`\nHandle the user opening the chat box. Emits the `chat_box_opened` signal.\n\n##### `on_chat_box_closed(cancelled=False)`\nHandle the user closing the chat box. Emits the `chat_box_closed` signal.\n\n##### `collect_chat_box_events(event)`\nHandle a keyboard event while the chat box is open.\nTodo: handle arrow keys, copy and paste\n\n##### `get_chat_box_contents()`\nReturn (our best guess at) the current contents of the chat box. If it is closed, returns a blank string.\n\n##### `get_chat_box_open_hotkey()`\nReturn the hotkey configured to open the chat box.\n\n\n#### Process\n\u003e Source: [flair/hook/process](flair/hook/process)\n\n##### `get_process() -\u003e \u003cbuilt-in function HANDLE\u003e`\nReturn a handle to Freelancer's process.\n\n##### `read_memory(process, address, datatype, buffer_size=128)`\nReads Freelancer's process memory.\n\nJust as with string resources, strings are stored as UTF-16 meaning that the end of a string is marked by two\nconsecutive null bytes. However, other bytes will be present in the buffer after these two nulls since it is of\narbitrary size, and these confuse Python's builtin .decode and result in UnicodeDecodeError. So we can't use it.\n\n##### `get_value(process, key, size=None)`\nRead a value from memory. `key` refers to the key of an address in `READ_ADDRESSES`\n\n##### `get_string(process, key, length)`\nRead a UTF-16 string from memory.\n\n##### `get_name(process) -\u003e str`\nRead the name of the active character from memory.\n\n##### `get_credits(process) -\u003e int`\nRead the credit balance of the active character from memory.\n\n##### `get_position(process) -\u003e Tuple[float, float, float]`\nRead the position of the active character from memory.\n\n##### `get_mouseover(process) -\u003e str`\nThis is a really interesting address. It seems to store random, unconnected pieces of text that have been\nrecently displayed or interacted with in the game. These range from console outputs to the names of bases\nand planets immediately upon jumping in or docking, to the prices of commodities in the trader screen, to\nmission \"popups\" messages, to the name of some solars and NPCs that are moused over while in space.\nWith some imagination this can probably be put to some use...\n\n##### `get_rollover(process) -\u003e str`\nSimilar to mouseover, but usually contains tooltip text.\n\n##### `get_last_message(process) -\u003e str`\nRead the last message sent by the player from memory\n\n##### `get_chat_box_state(process) -\u003e bool`\nRead the state of the chat box from memory.\n\n##### `get_character_loaded(process) -\u003e bool`\nRead whether a character is loaded (whether in SP or MP).\n\n##### `get_docked(process) -\u003e bool`\nRead whether the active character is docked.\n\n\n#### Window\n\u003e Source: [flair/hook/window](flair/hook/window)\n\n##### `get_hwnd() -\u003e int`\nReturns a non-zero window handle to Freelancer if a window exists, otherwise, returns zero.\n\n##### `is_present() -\u003e bool`\nReports whether Freelancer is running.\n\n##### `is_foreground() -\u003e bool`\nReports whether Freelancer is in the foreground and accepting input.\n\n##### `get_screen_coordinates()`\nReturn the screen coordinates for the contents (\"client\"; excludes window decorations) of a Freelancer window.\n\n##### `make_borderless()`\nRemove the borders and titlebar from the game while running in windowed mode.\n\n##### `make_foreground()`\nBring Freelancer's window into the foreground and make it the active window.\n  \n\n#### Storage\n\u003e Source: [flair/hook/storage](flair/hook/storage)\n\n##### `get_active_account_name() -\u003e str`\nReturns the currently active account's code (\"name\") from the registry.\nNote that Freelancer reads the account from the registry at the time of server connect.\n\n##### `virtual_key_to_name(vk) -\u003e str`\nGet the name of a key from its VK (virtual key) code.\n\n##### `get_user_keymap() -\u003e Dict[str, str]`\nGet Freelancer's current key map as defined in UserKeyMap.ini, in a format understood by the `keyboard`\nmodule.\n\n\n### Augmentations\n\u003e Source: [flair/augment](flair/augment)\n\n\"Augmentations\" are modules that augment the game client. flair includes several such examples built-in.\n\nTo create an augmentation, subclass `flair.augment.Augmentation`. Simply override the methods `load()` and `unload()`. These are run when augmentations are \"loaded\" into the game client and \"unloaded\" respectively. Connect up the events you need to use and add any other setup in these methods.\n\n#### Clipboard\nAdds clipboard access to the chat box. Use Ctrl+Shift+C to copy the contents of the chat box and Ctrl+Shift+V to paste text to it.\n\n#### CLI\nAdds a basic command-line interface to the game.\n\nThe following commands are implemented:\n\n- `..date`: print the local date and time\n- `..sector`: print the current sector and system\n- `..eval`: evaluate the given expression with Python\n- `..quit`: quit the game\n- `..help`: show this help message\n\n:warning: This augmentation is of limited use on servers without FLHook. If you are on a vanilla server you will need to type commands into the console (press ↑ in the chat box), otherwise they will be sent to other players. Additionally, running commands while a channel other than local (e.g. a group or PM) is selected as the default will result in messages being sent to a random player. FLHook's presence allows both of these issues to be mitigated.\n\n#### Screenshot\nAdds proper screenshot functionality to the game, similar to that found in games like *World of Warcraft*. Screenshots are automatically named with a timestamp and the system name and saved to `My Games/Freelancer/Screenshots` with the character name as the directory. Screenshots are taken using `Ctrl+PrintScreen`.\n\n### To do\n- Reimplementing Wizou's multiplayer code\n- Increasing the robustness of determining the chat box contents - currently it does not handle arrow keys\n- Getting system and base is currently pretty hacky, and it often requires a dock and undock to set both after loading a character\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbiqqles%2Fflair","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbiqqles%2Fflair","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbiqqles%2Fflair/lists"}