padrelay 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. padrelay-1.0.0/CHANGELOG.md +17 -0
  2. padrelay-1.0.0/LICENSE +21 -0
  3. padrelay-1.0.0/MANIFEST.in +11 -0
  4. padrelay-1.0.0/PKG-INFO +169 -0
  5. padrelay-1.0.0/README.md +144 -0
  6. padrelay-1.0.0/config/client_config.ini +11 -0
  7. padrelay-1.0.0/config/server_config.ini +42 -0
  8. padrelay-1.0.0/pyproject.toml +42 -0
  9. padrelay-1.0.0/requirements.txt +10 -0
  10. padrelay-1.0.0/setup.cfg +4 -0
  11. padrelay-1.0.0/src/padrelay/__init__.py +3 -0
  12. padrelay-1.0.0/src/padrelay/client/__init__.py +1 -0
  13. padrelay-1.0.0/src/padrelay/client/client_app.py +406 -0
  14. padrelay-1.0.0/src/padrelay/client/constants.py +10 -0
  15. padrelay-1.0.0/src/padrelay/client/input.py +95 -0
  16. padrelay-1.0.0/src/padrelay/core/__init__.py +1 -0
  17. padrelay-1.0.0/src/padrelay/core/config.py +214 -0
  18. padrelay-1.0.0/src/padrelay/core/exceptions.py +107 -0
  19. padrelay-1.0.0/src/padrelay/core/logging_utils.py +61 -0
  20. padrelay-1.0.0/src/padrelay/protocol/__init__.py +1 -0
  21. padrelay-1.0.0/src/padrelay/protocol/constants.py +13 -0
  22. padrelay-1.0.0/src/padrelay/protocol/messages.py +261 -0
  23. padrelay-1.0.0/src/padrelay/protocol/tcp.py +82 -0
  24. padrelay-1.0.0/src/padrelay/protocol/udp.py +137 -0
  25. padrelay-1.0.0/src/padrelay/scripts/__init__.py +3 -0
  26. padrelay-1.0.0/src/padrelay/scripts/client.py +65 -0
  27. padrelay-1.0.0/src/padrelay/scripts/key_mapper.py +699 -0
  28. padrelay-1.0.0/src/padrelay/scripts/server.py +86 -0
  29. padrelay-1.0.0/src/padrelay/security/__init__.py +3 -0
  30. padrelay-1.0.0/src/padrelay/security/auth.py +204 -0
  31. padrelay-1.0.0/src/padrelay/security/rate_limiting.py +133 -0
  32. padrelay-1.0.0/src/padrelay/server/__init__.py +1 -0
  33. padrelay-1.0.0/src/padrelay/server/constants.py +19 -0
  34. padrelay-1.0.0/src/padrelay/server/input_processor.py +152 -0
  35. padrelay-1.0.0/src/padrelay/server/server_app.py +427 -0
  36. padrelay-1.0.0/src/padrelay/server/virtual_gamepad.py +155 -0
  37. padrelay-1.0.0/src/padrelay.egg-info/PKG-INFO +169 -0
  38. padrelay-1.0.0/src/padrelay.egg-info/SOURCES.txt +54 -0
  39. padrelay-1.0.0/src/padrelay.egg-info/dependency_links.txt +1 -0
  40. padrelay-1.0.0/src/padrelay.egg-info/entry_points.txt +3 -0
  41. padrelay-1.0.0/src/padrelay.egg-info/requires.txt +4 -0
  42. padrelay-1.0.0/src/padrelay.egg-info/top_level.txt +1 -0
  43. padrelay-1.0.0/tests/__init__.py +26 -0
  44. padrelay-1.0.0/tests/conftest.py +29 -0
  45. padrelay-1.0.0/tests/test_auth.py +64 -0
  46. padrelay-1.0.0/tests/test_cli_entrypoints.py +38 -0
  47. padrelay-1.0.0/tests/test_config.py +218 -0
  48. padrelay-1.0.0/tests/test_gamepad_handler.py +80 -0
  49. padrelay-1.0.0/tests/test_integration.py +221 -0
  50. padrelay-1.0.0/tests/test_messages.py +39 -0
  51. padrelay-1.0.0/tests/test_migration.py +38 -0
  52. padrelay-1.0.0/tests/test_rate_limiting.py +19 -0
  53. padrelay-1.0.0/tests/test_server_client_apps.py +176 -0
  54. padrelay-1.0.0/tests/test_tcp_protocol.py +30 -0
  55. padrelay-1.0.0/tests/test_udp_protocol.py +93 -0
  56. padrelay-1.0.0/tests/test_virtual_gamepad.py +72 -0
@@ -0,0 +1,17 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog],
6
+ and this project adheres to [Semantic Versioning].
7
+
8
+ ## [1.0.0] - 2025-06-14
9
+
10
+ - initial release
11
+
12
+ <!-- Links -->
13
+ [keep a changelog]: https://keepachangelog.com/en/1.0.0/
14
+ [semantic versioning]: https://semver.org/spec/v2.0.0.html
15
+
16
+ <!-- Versions -->
17
+ [1.0.0]: https://github.com/ssh-den/PadRelay/releases/tag/v1.0.0
padrelay-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Den
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,11 @@
1
+ include README.md
2
+ include LICENSE
3
+ include requirements.txt
4
+ include pyproject.toml
5
+ include CHANGELOG.md
6
+ recursive-include config *.ini
7
+ recursive-include src *.py
8
+ recursive-include tests *.py
9
+ global-exclude __pycache__
10
+ global-exclude *.pyc
11
+ global-exclude *.pyo
@@ -0,0 +1,169 @@
1
+ Metadata-Version: 2.4
2
+ Name: padrelay
3
+ Version: 1.0.0
4
+ Summary: A client-server application for transmitting gamepad input over a network
5
+ Author-email: ssh-den <sshden@duck.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/ssh-den/PadRelay
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: End Users/Desktop
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.6
14
+ Classifier: Programming Language :: Python :: 3.7
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Topic :: Games/Entertainment
18
+ Requires-Python: >=3.6
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: pygame
22
+ Provides-Extra: server
23
+ Requires-Dist: vgamepad; extra == "server"
24
+ Dynamic: license-file
25
+
26
+ # PadRelay
27
+
28
+ **PadRelay** forwards gamepad input from a local machine to a Windows PC where a virtual controller is created using the `vgamepad` library. The client captures input with `pygame` and the server emulates either an Xbox 360 or DualShock 4 gamepad.
29
+
30
+ ## Features
31
+
32
+ - Works with Python 3.6+ on any system with `pygame` for the client
33
+ - Windows server with [ViGEmBus](https://github.com/ViGEm/ViGEmBus) installs a virtual gamepad
34
+ - Supports TCP (reliable) or UDP (low latency) transport
35
+ - Challenge/response authentication for TCP and token authentication for UDP
36
+ - Heartbeat and rate limiting to keep connections healthy
37
+ - Configurable block duration and higher defaults for UDP to avoid false limits
38
+ - Automatic reconnection if the server disconnects
39
+
40
+ ## Installation
41
+
42
+ Clone the repository and install the Python requirements if you want to run the
43
+ scripts directly from source:
44
+
45
+ ```bash
46
+ pip install -r requirements.txt
47
+ ```
48
+
49
+ After installing the dependencies, you can run the applications directly from source with: `python scripts/server.py` and
50
+ `python scripts/client.py`.
51
+
52
+ Alternatively install the package in editable mode to make the console commands
53
+ available:
54
+
55
+ ```bash
56
+ pip install -e .
57
+ ```
58
+
59
+ This will expose `padrelay-server` and `padrelay-client` on your `PATH`. When the
60
+ project will be published on PyPI you may also install it with `pip install
61
+ padrelay`.
62
+
63
+ When running the server on Windows install `vgamepad` and
64
+ [ViGEmBus](https://github.com/ViGEm/ViGEmBus) as well.
65
+
66
+ ## Configuration
67
+
68
+ Example INI files live in the `config/` directory. A trimmed server configuration looks like:
69
+ For a detailed explanation of every setting see [the full configuration reference](src/core/CONFIGURATION.md).
70
+
71
+ ```ini
72
+ [server]
73
+ host = 127.0.0.1
74
+ port = 9999
75
+ protocol = tcp
76
+ password = your_secure_password
77
+ rate_limit_window = 60
78
+ max_requests = 100
79
+ block_duration = 2
80
+ ```
81
+
82
+ On first run the server will replace any plaintext `password` value with a
83
+ PBKDF2 hash string so the file no longer contains the original secret. Use the
84
+ `PASSWORD` or `PASSWORD_HASH` environment variable to override the value without
85
+ modifying the configuration file. When the password is stored as a hash the
86
+ server automatically includes the hash parameters in its authentication
87
+ challenge so clients using the original plaintext password continue to work.
88
+
89
+ ```ini
90
+ [vgamepad]
91
+ type = xbox360
92
+ ```
93
+
94
+ and a matching client configuration:
95
+
96
+ ```ini
97
+ [network]
98
+ server_ip = 192.168.1.100
99
+ server_port = 9999
100
+ protocol = tcp
101
+ password = your_secure_password
102
+
103
+ [joystick]
104
+ index = 0
105
+
106
+ [client]
107
+ update_rate = 60
108
+ ```
109
+
110
+ ## Usage
111
+
112
+ If you installed the project with `pip install -e .` or from PyPI you can use
113
+ the `padrelay-server` and `padrelay-client` commands. When running directly from
114
+ source replace them with `python scripts/server.py` and
115
+ `python scripts/client.py`.
116
+
117
+ Start the server with your configuration:
118
+
119
+ ```bash
120
+ padrelay-server --config config/server_config.ini
121
+ ```
122
+
123
+ Then start the client and point it at the server:
124
+
125
+ ```bash
126
+ padrelay-client --config config/client_config.ini
127
+ ```
128
+
129
+ Both scripts accept command line flags (see `--help`) and load values from the configuration files if provided.
130
+ The server also checks the `PASSWORD` or `PASSWORD_HASH` environment variables
131
+ which override any configured value at runtime. Clients may specify a
132
+ `--password-hash` argument, a `[network] password_hash` setting, or the
133
+ `PASSWORD_HASH` environment variable when using UDP so the secret never needs to
134
+ be stored in plaintext.
135
+
136
+ When a client only has the plaintext password for UDP, it will automatically
137
+ send an `auth_params_request` when connecting. Servers that store only a hashed
138
+ password reply with their salt and iteration count so the client can derive the
139
+ same key and authenticate using time‑based tokens. Servers using a plaintext
140
+ password simply ignore the request and the client continues with the plaintext
141
+ key.
142
+
143
+ ## Testing
144
+
145
+ To run the unit tests:
146
+
147
+ ```bash
148
+ pytest
149
+
150
+ ## Logging
151
+
152
+ All components write logs to a single file in the `logs` directory at the project
153
+ root by default. The directory will be created automatically if it does not
154
+ exist. Set the ``PADRELAY_LOG_DIR`` environment variable to override this
155
+ location. Logs are rotated automatically and never include passwords or tokens.
156
+
157
+ ## Disclaimer
158
+
159
+ **Security Notice**
160
+
161
+ PadRelay does **not** implement TLS or any built-in encryption. It is intended for use on **trusted, private networks** only.
162
+ You should always secure communication via a **VPN, SSH tunnel**, or other private channel. **Never expose the server directly to the public internet.**
163
+
164
+ Use this software **at your own risk**. The author assumes no responsibility for data loss, damage, or security issues resulting from its use.
165
+
166
+ **Bug Reports**
167
+
168
+ This project is under active development. If you encounter any issues, misbehavior, or unexpected crashes, please open an issue on GitHub with steps to reproduce.
169
+ Contributions and pull requests are always welcome.
@@ -0,0 +1,144 @@
1
+ # PadRelay
2
+
3
+ **PadRelay** forwards gamepad input from a local machine to a Windows PC where a virtual controller is created using the `vgamepad` library. The client captures input with `pygame` and the server emulates either an Xbox 360 or DualShock 4 gamepad.
4
+
5
+ ## Features
6
+
7
+ - Works with Python 3.6+ on any system with `pygame` for the client
8
+ - Windows server with [ViGEmBus](https://github.com/ViGEm/ViGEmBus) installs a virtual gamepad
9
+ - Supports TCP (reliable) or UDP (low latency) transport
10
+ - Challenge/response authentication for TCP and token authentication for UDP
11
+ - Heartbeat and rate limiting to keep connections healthy
12
+ - Configurable block duration and higher defaults for UDP to avoid false limits
13
+ - Automatic reconnection if the server disconnects
14
+
15
+ ## Installation
16
+
17
+ Clone the repository and install the Python requirements if you want to run the
18
+ scripts directly from source:
19
+
20
+ ```bash
21
+ pip install -r requirements.txt
22
+ ```
23
+
24
+ After installing the dependencies, you can run the applications directly from source with: `python scripts/server.py` and
25
+ `python scripts/client.py`.
26
+
27
+ Alternatively install the package in editable mode to make the console commands
28
+ available:
29
+
30
+ ```bash
31
+ pip install -e .
32
+ ```
33
+
34
+ This will expose `padrelay-server` and `padrelay-client` on your `PATH`. When the
35
+ project will be published on PyPI you may also install it with `pip install
36
+ padrelay`.
37
+
38
+ When running the server on Windows install `vgamepad` and
39
+ [ViGEmBus](https://github.com/ViGEm/ViGEmBus) as well.
40
+
41
+ ## Configuration
42
+
43
+ Example INI files live in the `config/` directory. A trimmed server configuration looks like:
44
+ For a detailed explanation of every setting see [the full configuration reference](src/core/CONFIGURATION.md).
45
+
46
+ ```ini
47
+ [server]
48
+ host = 127.0.0.1
49
+ port = 9999
50
+ protocol = tcp
51
+ password = your_secure_password
52
+ rate_limit_window = 60
53
+ max_requests = 100
54
+ block_duration = 2
55
+ ```
56
+
57
+ On first run the server will replace any plaintext `password` value with a
58
+ PBKDF2 hash string so the file no longer contains the original secret. Use the
59
+ `PASSWORD` or `PASSWORD_HASH` environment variable to override the value without
60
+ modifying the configuration file. When the password is stored as a hash the
61
+ server automatically includes the hash parameters in its authentication
62
+ challenge so clients using the original plaintext password continue to work.
63
+
64
+ ```ini
65
+ [vgamepad]
66
+ type = xbox360
67
+ ```
68
+
69
+ and a matching client configuration:
70
+
71
+ ```ini
72
+ [network]
73
+ server_ip = 192.168.1.100
74
+ server_port = 9999
75
+ protocol = tcp
76
+ password = your_secure_password
77
+
78
+ [joystick]
79
+ index = 0
80
+
81
+ [client]
82
+ update_rate = 60
83
+ ```
84
+
85
+ ## Usage
86
+
87
+ If you installed the project with `pip install -e .` or from PyPI you can use
88
+ the `padrelay-server` and `padrelay-client` commands. When running directly from
89
+ source replace them with `python scripts/server.py` and
90
+ `python scripts/client.py`.
91
+
92
+ Start the server with your configuration:
93
+
94
+ ```bash
95
+ padrelay-server --config config/server_config.ini
96
+ ```
97
+
98
+ Then start the client and point it at the server:
99
+
100
+ ```bash
101
+ padrelay-client --config config/client_config.ini
102
+ ```
103
+
104
+ Both scripts accept command line flags (see `--help`) and load values from the configuration files if provided.
105
+ The server also checks the `PASSWORD` or `PASSWORD_HASH` environment variables
106
+ which override any configured value at runtime. Clients may specify a
107
+ `--password-hash` argument, a `[network] password_hash` setting, or the
108
+ `PASSWORD_HASH` environment variable when using UDP so the secret never needs to
109
+ be stored in plaintext.
110
+
111
+ When a client only has the plaintext password for UDP, it will automatically
112
+ send an `auth_params_request` when connecting. Servers that store only a hashed
113
+ password reply with their salt and iteration count so the client can derive the
114
+ same key and authenticate using time‑based tokens. Servers using a plaintext
115
+ password simply ignore the request and the client continues with the plaintext
116
+ key.
117
+
118
+ ## Testing
119
+
120
+ To run the unit tests:
121
+
122
+ ```bash
123
+ pytest
124
+
125
+ ## Logging
126
+
127
+ All components write logs to a single file in the `logs` directory at the project
128
+ root by default. The directory will be created automatically if it does not
129
+ exist. Set the ``PADRELAY_LOG_DIR`` environment variable to override this
130
+ location. Logs are rotated automatically and never include passwords or tokens.
131
+
132
+ ## Disclaimer
133
+
134
+ **Security Notice**
135
+
136
+ PadRelay does **not** implement TLS or any built-in encryption. It is intended for use on **trusted, private networks** only.
137
+ You should always secure communication via a **VPN, SSH tunnel**, or other private channel. **Never expose the server directly to the public internet.**
138
+
139
+ Use this software **at your own risk**. The author assumes no responsibility for data loss, damage, or security issues resulting from its use.
140
+
141
+ **Bug Reports**
142
+
143
+ This project is under active development. If you encounter any issues, misbehavior, or unexpected crashes, please open an issue on GitHub with steps to reproduce.
144
+ Contributions and pull requests are always welcome.
@@ -0,0 +1,11 @@
1
+ [network]
2
+ server_ip = 172.26.8.240
3
+ server_port = 9999
4
+ protocol = udp
5
+ password = 1234
6
+
7
+ [joystick]
8
+ index = 0
9
+
10
+ [client]
11
+ update_rate = 60
@@ -0,0 +1,42 @@
1
+ [server]
2
+ host = 127.0.0.1
3
+ port = 9999
4
+ protocol = tcp
5
+ password = your_secure_password
6
+ rate_limit_window = 60
7
+ max_requests = 100
8
+ block_duration = 2
9
+
10
+ [vgamepad]
11
+ type = xbox360
12
+
13
+ [button_mapping_xbox360]
14
+ 0 = XUSB_GAMEPAD_A
15
+ 1 = XUSB_GAMEPAD_B
16
+ 2 = XUSB_GAMEPAD_X
17
+ 3 = XUSB_GAMEPAD_Y
18
+ 4 = XUSB_GAMEPAD_LEFT_SHOULDER
19
+ 5 = XUSB_GAMEPAD_RIGHT_SHOULDER
20
+ 6 = XUSB_GAMEPAD_BACK
21
+ 7 = XUSB_GAMEPAD_START
22
+ 8 = XUSB_GAMEPAD_LEFT_THUMB
23
+ 9 = XUSB_GAMEPAD_RIGHT_THUMB
24
+ 10 = XUSB_GAMEPAD_DPAD_UP
25
+ 11 = XUSB_GAMEPAD_DPAD_DOWN
26
+ 12 = XUSB_GAMEPAD_DPAD_LEFT
27
+ 13 = XUSB_GAMEPAD_DPAD_RIGHT
28
+ 14 = XUSB_GAMEPAD_GUIDE
29
+
30
+ [axis_mapping]
31
+ left_stick_x = 0
32
+ left_stick_y = 1
33
+ right_stick_x = 2
34
+ right_stick_y = 3
35
+ trigger_left = 4
36
+ trigger_right = 5
37
+
38
+ [axis_options]
39
+ dead_zone = 0.1
40
+ trigger_threshold = 0.1
41
+ invert_left_y = false
42
+ invert_right_y = false
@@ -0,0 +1,42 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "padrelay"
7
+ version = "1.0.0"
8
+ description = "A client-server application for transmitting gamepad input over a network"
9
+ readme = "README.md"
10
+ authors = [{ name = "ssh-den", email = "sshden@duck.com" }]
11
+ license = "MIT"
12
+ requires-python = ">=3.6"
13
+ dependencies = ["pygame"]
14
+
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Environment :: Console",
18
+ "Intended Audience :: End Users/Desktop",
19
+ "Operating System :: OS Independent",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.6",
22
+ "Programming Language :: Python :: 3.7",
23
+ "Programming Language :: Python :: 3.8",
24
+ "Programming Language :: Python :: 3.9",
25
+ "Topic :: Games/Entertainment"
26
+ ]
27
+
28
+ [project.optional-dependencies]
29
+ server = ["vgamepad"]
30
+
31
+ [project.scripts]
32
+ padrelay-client = "padrelay.scripts.client:main"
33
+ padrelay-server = "padrelay.scripts.server:main"
34
+
35
+ [project.urls]
36
+ Homepage = "https://github.com/ssh-den/PadRelay"
37
+
38
+ [tool.setuptools]
39
+ include-package-data = true
40
+
41
+ [tool.setuptools.packages.find]
42
+ where = ["src"]
@@ -0,0 +1,10 @@
1
+ # Core dependencies
2
+ pygame==2.6.1
3
+
4
+ # Windows-only dependency for emulating a gamepad (client or server)
5
+ vgamepad==0.1.0; platform_system=="Windows"
6
+
7
+ # Testing dependencies
8
+ pytest==8.4.0
9
+ pytest-asyncio==1.0.0
10
+
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """
2
+ PadRelay - A client-server application for transmitting gamepad input over a network
3
+ """
@@ -0,0 +1 @@
1
+ """Client-side utilities for the PadRelay"""