From a85aa0197afa63df8b216f9e66b2dd6c5ac43022 Mon Sep 17 00:00:00 2001 From: biqqles Date: Sun, 13 Sep 2020 19:51:06 +0100 Subject: [PATCH] Update README.md and setup.py for v0.3 --- README.md | 106 ++++++++++++++++++++++++++++++------------------------ setup.py | 2 +- 2 files changed, 61 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index e702a38..66dd1b7 100644 --- a/README.md +++ b/README.md @@ -4,16 +4,16 @@ flair achieves this through a combination of hooking user input, reading process memory and window interaction using the Win32 API, 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. ### Installation -flair is on PyPI: +flair is on [PyPI](https://pypi.org/project/fl-flair/): ``` -python -m pip install fl-flair +pip install fl-flair ``` Alternatively you can install straight from this repository: ```sh -python -m pip install https://github.com/biqqles/flair/archive/master.zip +pip install https://github.com/biqqles/flair/archive/master.zip -U ``` Built wheels are also available under [Releases](https://github.com/biqqles/flair/releases), as is a changelog. flair requires Python 3.6 or higher. @@ -23,20 +23,23 @@ flair must be run with administrator privileges. This is required for it to be a flair includes a testing mode. To access it run `python -m flair `. 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. -To use flair in your own programs, simply create an instance of `flair.FreelancerState`. This will begin polling the game (by default every 1 second). The polling frequency only affects when events are emitted - in most cases accesses to FreelancerState will cause the immediate state of the game to be read. - +### State and events Basic usage of flair relies on two main principles: - - a state object, which allows access to the game's state in real time - - a simple events system inspired by Qt's signals and slots mechanism + - a [state object](#freelancerstate), which allows access to the game's state in real time (`flair.state`) + - a simple [events system](#events) inspired by Qt's signals and slots mechanism (`flair.events`) + +To 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). -The API for the hook itself is also of course available for cases not covered by the builtin `FreelancerState`, like creating [augmentations](#augmentations). +If 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). All these concepts are discussed in detail below. ## API -### FreelancerState -As mentioned earlier, simply create an instance of `flair.FreelancerState` to get access to the game state. Its constructor takes one argument, the path to the game's folder. This object has the following methods and properties: +### `FreelancerState` +> Source: [flair/inspect/state.py](flair/inspect/state.py) + +As 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: |Methods |Type |Notes | |:-------------------|:----------------|:----------------------------------------------------------------------------------------| @@ -57,34 +60,38 @@ As mentioned earlier, simply create an instance of `flair.FreelancerState` to ge |**`pos`** |`Optional[PosVector]`|The position vector of the active character if there is one, otherwise None | |**`docked`** |`Optional[bool]` |Whether the active character is presently docked at a base if there is one, otherwise None| -Source: [flair/inspect/state.py](flair/inspect/state.py) +A `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. + ### Events +> Source: [flair/inspect/events.py](flair/inspect/events.py) + Events 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. + +The connected function should take a keyword argument with the name specified in the schema column. -|Event |Emitted when | Parameter(s) | +|Event |Emitted when | Parameter schema | |:---------------------------|:----------------------------------|:--------------------------------------------------------------| -|**`character_changed`** |New character loaded |`name`=new character name | -|**`account_changed`** |Active (registry) account changed |`account`=new account code | -|**`system_changed`** |New system entered |`system`=New system display name | -|**`docked`** |Docked base (respawn point) changed|`base`=new base display name | +|**`character_changed`** |New character loaded |`name`: new character name | +|**`account_changed`** |Active (registry) account changed |`account`: new account code | +|**`system_changed`** |New system entered |`system`: New system display name | +|**`docked`** |Docked base (respawn point) changed|`base`: new base display name | |**`undocked`** |Undocked from base |N/A | -|**`credits_changed`** |Credit balance changed |`balance`=new credit balance | -|**`message_sent`** |New message sent by player |`message`=message text | -|**`chat_box_opened`** |Chat box opened |`message`=message text | -|**`chat_box_closed`** |Chat box closed |`message_sent`=whether message sent | +|**`credits_changed`** |Credit balance changed |`balance`: new credit balance | +|**`message_sent`** |New message sent by player |`message`: message text | +|**`chat_box_opened`** |Chat box opened |`message`: message text | +|**`chat_box_closed`** |Chat box closed |`message_sent`: whether message sent | |**`freelancer_started`** |Freelancer process launched |N/A | |**`freelancer_stopped`** |Freelancer process closed |N/A | |**`switched_to_foreground`**|Freelancer switched to foreground |N/A | |**`switched_to_background`**|Freelancer switched to background |N/A | -Source: [flair/inspect/events.py](flair/inspect/events.py) ### Hook -[`flair/hook`](flair/hook) contains the lower-level code for hooking into the game. You will likely only need to use this directly if you wish to go beyond simply using `FreelancerState` and the events system. It is separated into the following modules: +[`flair/hook`](flair/hook) contains the hook itself. It is separated into the following modules: #### Input -Source: [flair/hook/input](flair/hook/input) +> Source: [flair/hook/input](flair/hook/input) ##### `bind_hotkey(combination, function)` Adds a hotkey which is only active when Freelancer is in the foreground. @@ -121,7 +128,7 @@ Handle the user closing the chat box. Emits the `chat_box_closed` signal. ##### `collect_chat_box_events(event)` Handle a keyboard event while the chat box is open. -# Todo: handle arrow keys, copy and paste +Todo: handle arrow keys, copy and paste ##### `get_chat_box_contents()` Return (our best guess at) the current contents of the chat box. If it is closed, returns a blank string. @@ -129,8 +136,11 @@ Return (our best guess at) the current contents of the chat box. If it is closed ##### `get_chat_box_open_hotkey()` Return the hotkey configured to open the chat box. + #### Process -Source: [flair/hook/process](flair/hook/process)##### `get_process() -> ` +> Source: [flair/hook/process](flair/hook/process) + +##### `get_process() -> ` Return a handle to Freelancer's process. ##### `read_memory(process, address, datatype, buffer_size=128)` @@ -177,8 +187,11 @@ Read whether a character is loaded (whether in SP or MP). ##### `get_docked(process) -> bool` Read whether the active character is docked. + #### Window -Source: [flair/hook/window](flair/hook/window)##### `get_hwnd() -> int` +> Source: [flair/hook/window](flair/hook/window) + +##### `get_hwnd() -> int` Returns a non-zero window handle to Freelancer if a window exists, otherwise, returns zero. ##### `is_present() -> bool` @@ -191,11 +204,16 @@ Reports whether Freelancer is in the foreground and accepting input. Return the screen coordinates for the contents ("client"; excludes window decorations) of a Freelancer window. ##### `make_borderless()` -Remove the borders and titlebar from the game running in windowed mode. -Todo: Windowed mode seems to cut off the bottom of the game. This is something that will need worked around. +Remove the borders and titlebar from the game while running in windowed mode. + +##### `make_foreground()` +Bring Freelancer's window into the foreground and make it the active window. + #### Storage -Source: [flair/hook/storage](flair/hook/storage)##### `get_active_account_name() -> str` +> Source: [flair/hook/storage](flair/hook/storage) + +##### `get_active_account_name() -> str` Returns the currently active account's code ("name") from the registry. Note that Freelancer reads the account from the registry at the time of server connect. @@ -206,36 +224,32 @@ Get the name of a key from its VK (virtual key) code. Get Freelancer's current key map as defined in UserKeyMap.ini, in a format understood by the `keyboard` module. -##### `tail_chat_log()` -(Discovery only) -Get the last message recorded in DSAce.log - -##### `get_launcher_accounts() -> Dict[str, Tuple[str, str]]` -(Discovery only) -Parse launcheraccounts.xml to a dictionary of tuples of the form {code: (name, description)}. ### Augmentations -"Augmentations" are modules that augment the game client. flair includes several such built-in example modules. +> Source: [flair/augment](flair/augment) -To 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 here. +"Augmentations" are modules that augment the game client. flair includes several such examples built-in. -Source: [flair/augment](flair/augment) +To 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. #### Clipboard Adds 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. #### CLI Adds a basic command-line interface to the game. -If you are on a vanilla server you will need to type commands into the console (press ↑ in the chat box). This is not necessary on a server running FLHook as it will recognise them as commands and not send them to other players. Output is returned in chat, again through the console. -- `date`: print the local date and time -- `sector`: print the current sector and system -- `eval`: evaluate the given expression with Python -- `quit`: quit the game -- `help`: show this help message +The following commands are implemented: + +- `..date`: print the local date and time +- `..sector`: print the current sector and system +- `..eval`: evaluate the given expression with Python +- `..quit`: quit the game +- `..help`: show this help message + +: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. #### Screenshot -Adds 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. +Adds 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`. ### To do - Reimplementing Wizou's multiplayer code diff --git a/setup.py b/setup.py index e54acb9..810b05b 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ setup( name='fl-flair', - version='0.2', + version='0.3', author='biqqles', author_email='biqqles@protonmail.com', description='A novel client-side hook for Freelancer',