Splatlogger 1.2.1__tar.gz → 1.2.3__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 (26) hide show
  1. {splatlogger-1.2.1/src/Splatlogger.egg-info → splatlogger-1.2.3}/PKG-INFO +43 -46
  2. {splatlogger-1.2.1 → splatlogger-1.2.3}/README.md +30 -37
  3. {splatlogger-1.2.1 → splatlogger-1.2.3}/pyproject.toml +18 -10
  4. {splatlogger-1.2.1 → splatlogger-1.2.3/src/Splatlogger.egg-info}/PKG-INFO +43 -46
  5. {splatlogger-1.2.1 → splatlogger-1.2.3}/src/Splatlogger.egg-info/SOURCES.txt +1 -0
  6. splatlogger-1.2.3/src/Splatlogger.egg-info/requires.txt +15 -0
  7. splatlogger-1.2.3/src/splatlogger/__init__.py +2 -0
  8. splatlogger-1.2.3/src/splatlogger/__main__.py +8 -0
  9. {splatlogger-1.2.1 → splatlogger-1.2.3}/src/splatlogger/cemu_gecko.py +5 -2
  10. {splatlogger-1.2.1 → splatlogger-1.2.3}/src/splatlogger/cli.py +10 -7
  11. splatlogger-1.2.3/src/splatlogger/errors.py +2 -0
  12. {splatlogger-1.2.1 → splatlogger-1.2.3}/src/splatlogger/match_logger.py +12 -6
  13. {splatlogger-1.2.1 → splatlogger-1.2.3}/src/splatlogger/splatlogger.py +20 -11
  14. {splatlogger-1.2.1 → splatlogger-1.2.3}/src/splatlogger/tuples.py +2 -3
  15. {splatlogger-1.2.1 → splatlogger-1.2.3}/src/splatlogger/utility_functions.py +5 -8
  16. splatlogger-1.2.1/src/Splatlogger.egg-info/requires.txt +0 -7
  17. splatlogger-1.2.1/src/splatlogger/__init__.py +0 -0
  18. splatlogger-1.2.1/src/splatlogger/__main__.py +0 -4
  19. {splatlogger-1.2.1 → splatlogger-1.2.3}/LICENSE +0 -0
  20. {splatlogger-1.2.1 → splatlogger-1.2.3}/setup.cfg +0 -0
  21. {splatlogger-1.2.1 → splatlogger-1.2.3}/src/Splatlogger.egg-info/dependency_links.txt +0 -0
  22. {splatlogger-1.2.1 → splatlogger-1.2.3}/src/Splatlogger.egg-info/entry_points.txt +0 -0
  23. {splatlogger-1.2.1 → splatlogger-1.2.3}/src/Splatlogger.egg-info/top_level.txt +0 -0
  24. {splatlogger-1.2.1 → splatlogger-1.2.3}/src/splatlogger/enums.py +0 -0
  25. {splatlogger-1.2.1 → splatlogger-1.2.3}/src/splatlogger/resources/names.json +0 -0
  26. {splatlogger-1.2.1 → splatlogger-1.2.3}/src/splatlogger/tcpgecko.py +0 -0
@@ -1,22 +1,26 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Splatlogger
3
- Version: 1.2.1
3
+ Version: 1.2.3
4
4
  Summary: PID Grabber and player/match information logging tool for Splatoon
5
5
  Author-email: Shadow Doggo <shadowdoggo@protonmail.com>
6
6
  License-Expression: MIT
7
7
  Project-URL: Source Code, https://codeberg.org/ShadowDoggo/Splatlogger
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: Operating System :: OS Independent
10
- Requires-Python: >=3.11
10
+ Requires-Python: >=3.10
11
11
  Description-Content-Type: text/markdown
12
12
  License-File: LICENSE
13
- Requires-Dist: userpaths
14
- Requires-Dist: requests
15
- Requires-Dist: psutil
16
- Requires-Dist: pymemoryeditor>=2.0.0
17
- Requires-Dist: colorama
18
- Requires-Dist: clean-text
19
- Requires-Dist: prompt_toolkit
13
+ Requires-Dist: tomli>=1.1.0; python_version < "3.11"
14
+ Requires-Dist: userpaths>=0.1.3
15
+ Requires-Dist: requests>=2.28.0
16
+ Requires-Dist: colorama>=0.4.6
17
+ Requires-Dist: clean-text>=0.7.1
18
+ Requires-Dist: prompt_toolkit>=3.0.0
19
+ Provides-Extra: cemu
20
+ Requires-Dist: psutil>=5.9.0; extra == "cemu"
21
+ Requires-Dist: pymemoryeditor>=2.0.0; extra == "cemu"
22
+ Provides-Extra: build
23
+ Requires-Dist: pyinstaller>=6.6.0; extra == "build"
20
24
  Dynamic: license-file
21
25
 
22
26
  # Splatlogger
@@ -47,63 +51,71 @@ On Aroma, use [TCPGecko-Plugin](https://github.com/PinkDiamondTeam/TCPGecko-Plug
47
51
 
48
52
  ## Usage
49
53
  ### Running the executable
50
- Windows and Linux executables are provided on the Releases page.
54
+ Windows and Linux executables are provided on the [Releases](https://codeberg.org/ShadowDoggo/Splatlogger/releases/latest) page.
51
55
 
52
56
  Run Splatlogger with:
53
57
  ```
54
- path/to/Splatlogger-executable --ip IP [options]
58
+ path/to/Splatlogger-executable --ip IP [options] / --cemu [PID] [options]
55
59
  ```
56
- where `IP` is your Wii U's LAN IP address.
60
+ Use the `--ip` target where `IP` is your Wii U's LAN IP address,
61
+ or the `-c` / `--cemu` target to enable Cemu mode where `PID` is the process ID of the Cemu process (optional, should be detected automatically).
57
62
 
58
63
  Open a command prompt/terminal window and drag the executable into it to automatically get the path.
59
64
 
65
+ On Linux, you might need to make the file executable first with `chmod +x path/to/Splatlogger-executable`
66
+
60
67
  ### Running with Python
61
68
  You can install Splatlogger as a package from PyPI:
62
69
  ```
63
70
  pip install Splatlogger
64
71
  ```
65
72
 
66
- The run with:
73
+ To enable Cemu support, install with the `cemu` extra:
74
+ ```
75
+ pip install "Splatlogger[cemu]"
76
+ ```
77
+
78
+ Then run with:
67
79
  ```
68
- splatlogger --ip IP [options]
80
+ splatlogger --ip IP [options] / --cemu [PID] [options]
69
81
  ```
70
- (if that fails, try `python -m splatlogger`) where `IP` is your Wii U's LAN IP address.
82
+ (if that fails, try `python -m splatlogger`)
83
+
84
+ Use the `--ip` target where `IP` is your Wii U's LAN IP address,
85
+ or the `-c` / `--cemu` target to enable Cemu mode where `PID` is the process ID of the Cemu process (optional, should be detected automatically).
71
86
 
72
- To run from source instead, download the latest source archive from the Releases
87
+ To run from source instead, download the latest source archive from the [Releases](https://codeberg.org/ShadowDoggo/Splatlogger/releases/latest)
73
88
  page and extract it, then open a terminal window in the extracted directory.
74
89
 
75
90
  Install the required dependencies:
76
91
  ```
77
- pip install -r requirements.txt
92
+ pip install -r requirements.txt / cemu_requirements.txt
78
93
  ```
79
94
 
80
95
  Then move into the `src` directory and run:
81
96
  ```
82
- python -m splatlogger --ip IP [options]
97
+ python -m splatlogger --ip IP [options] / --cemu [PID] [options]
83
98
  ```
84
99
 
85
100
  ### Options
86
- - `-c [PID]`, `--cemu [PID]` - Switch to Cemu mode. The `--ip` argument is not required.
87
- - `PID` - Process ID of the Cemu process (optional).
88
-
89
101
  - `--log-level option` - Set how much data should be logged.
90
102
  - `none` - Don't create a log file.
91
103
  - `standard` - Log only basic player information, the same as what's printed to the console (default).
92
104
  - `extended` - Log all player information and additional match information.
93
- - `stats` - Same as above with the addition of player stats (points, K/D, win/lose) and disconnect detection.
105
+ - `stats` - Same as above with the addition of player stats (points, K/D, win/lose) and disconnect detection.
94
106
  Requires the match to end to finish logging; if it ends abruptly, the stats won't be logged.
95
107
 
96
108
  - `--service` - Choose which network service you're using.
97
109
  - `none` - Disable fetching account info.
98
110
  - `pretendo` - Pretendo Network (default).
99
- - `spfn` - Splatfestival Network.
111
+ - `altendo` - Altendo Network.
100
112
 
101
- - `-a [option]`, `--auto [option]` - Enable auto logging. When enabled will automatically log every match you play.
113
+ - `-a [option]`, `--auto [option]` - Enable auto logging. When enabled will automatically log every match you play.
102
114
  Also allows you to view information about the lobby/gathering while on the matching screen.
103
115
  - `all` - Save a log of all matches you play (default).
104
116
  - `latest` - Save a log of only the latest match.
105
117
 
106
- (These options don't affect anything if log level is set to `none`)
118
+ (These options don't affect anything if the log level is set to `none`)
107
119
 
108
120
  - `--stack Address (in hex)` - (Cemu only, optional) Beginning address of the stack space for Default Core 1 (Debug > View PPC threads).
109
121
  Only required for logging stats. If the default values don't work, you'll need to specify this manually.
@@ -134,7 +146,7 @@ Example `config.toml`:
134
146
  # Target Wii U LAN IP address (omit if using Cemu)
135
147
  ip = "192.168.1.50"
136
148
 
137
- # Target network service: "pretendo", "spfn", or "none"
149
+ # Target network service: "pretendo", "altendo", or "none"
138
150
  service = "pretendo"
139
151
 
140
152
  # Log level: "standard", "extended", "stats", or "none"
@@ -178,7 +190,7 @@ In that case, it's best to run the package from source or use the executable ins
178
190
  ## Important notes
179
191
  - The data collected by Splatlogger is public player info shared by the game with every user you play with in online matches.
180
192
 
181
- - Network IDs and Mii names are fetched from the Pretendo or SPFN account server; this can be disabled with `--service none`.
193
+ - Network IDs and Mii names are fetched from the network's account server; this can be disabled with `--service none`.
182
194
 
183
195
  - Splatlogger does not collect any sensitive information such as account email addresses or IP addresses.
184
196
 
@@ -187,28 +199,13 @@ In that case, it's best to run the package from source or use the executable ins
187
199
  - Please handle the logs responsibly. I do not encourage sharing other users' data without their permission, even if no real harm can be done with it.
188
200
 
189
201
  ## Building the executable with PyInstaller
190
- Set up a virtual environment and install PyInstaller as well as the required dependencies.
202
+ Set up a virtual environment and run `pip install -r build_requirements.txt` to install PyInstaller as well as the required dependencies.
191
203
 
192
- In `match_logger.py`, replace `from importlib import resources` with `import sys` and
193
- ```py
194
- names_path = resources.files(__package__).joinpath("resources", "names.json")
204
+ Run:
195
205
  ```
196
-
197
- with
198
- ```py
199
- names_path = Path(sys._MEIPASS) / "resources/names.json"
200
- ```
201
-
202
- Then run:
206
+ python scripts/build.py [--upx-dir path/to/upx]
203
207
  ```
204
- pyinstaller --noconfirm --onefile --console --name "Splatlogger-v1.x" --upx-dir "path/to/upx" --optimize "2" --add-data "path/to/Splatlogger/src/splatlogger/resources:resources/" --icon "NONE" "path/to/Splatlogger/src/run.py"
205
- ```
206
- replacing the placeholder paths with the actual ones.
207
-
208
- You can omit `--upx-dir` if you're not using UPX to compress the executable and `--optimize "2"` to disable
209
- bytecode optimization.
210
-
211
- On Linux, add `--bootloader-ignore-signals` and remove `--upx-dir` and `--icon` as they are not supported.
208
+ use `--upx-dir` if you're using UPX to compress the executable.
212
209
 
213
210
  ## Acknowledgments
214
211
  - NWPlayer123 for the reference implementation of a TCPGecko library.
@@ -26,63 +26,71 @@ On Aroma, use [TCPGecko-Plugin](https://github.com/PinkDiamondTeam/TCPGecko-Plug
26
26
 
27
27
  ## Usage
28
28
  ### Running the executable
29
- Windows and Linux executables are provided on the Releases page.
29
+ Windows and Linux executables are provided on the [Releases](https://codeberg.org/ShadowDoggo/Splatlogger/releases/latest) page.
30
30
 
31
31
  Run Splatlogger with:
32
32
  ```
33
- path/to/Splatlogger-executable --ip IP [options]
33
+ path/to/Splatlogger-executable --ip IP [options] / --cemu [PID] [options]
34
34
  ```
35
- where `IP` is your Wii U's LAN IP address.
35
+ Use the `--ip` target where `IP` is your Wii U's LAN IP address,
36
+ or the `-c` / `--cemu` target to enable Cemu mode where `PID` is the process ID of the Cemu process (optional, should be detected automatically).
36
37
 
37
38
  Open a command prompt/terminal window and drag the executable into it to automatically get the path.
38
39
 
40
+ On Linux, you might need to make the file executable first with `chmod +x path/to/Splatlogger-executable`
41
+
39
42
  ### Running with Python
40
43
  You can install Splatlogger as a package from PyPI:
41
44
  ```
42
45
  pip install Splatlogger
43
46
  ```
44
47
 
45
- The run with:
48
+ To enable Cemu support, install with the `cemu` extra:
49
+ ```
50
+ pip install "Splatlogger[cemu]"
51
+ ```
52
+
53
+ Then run with:
46
54
  ```
47
- splatlogger --ip IP [options]
55
+ splatlogger --ip IP [options] / --cemu [PID] [options]
48
56
  ```
49
- (if that fails, try `python -m splatlogger`) where `IP` is your Wii U's LAN IP address.
57
+ (if that fails, try `python -m splatlogger`)
58
+
59
+ Use the `--ip` target where `IP` is your Wii U's LAN IP address,
60
+ or the `-c` / `--cemu` target to enable Cemu mode where `PID` is the process ID of the Cemu process (optional, should be detected automatically).
50
61
 
51
- To run from source instead, download the latest source archive from the Releases
62
+ To run from source instead, download the latest source archive from the [Releases](https://codeberg.org/ShadowDoggo/Splatlogger/releases/latest)
52
63
  page and extract it, then open a terminal window in the extracted directory.
53
64
 
54
65
  Install the required dependencies:
55
66
  ```
56
- pip install -r requirements.txt
67
+ pip install -r requirements.txt / cemu_requirements.txt
57
68
  ```
58
69
 
59
70
  Then move into the `src` directory and run:
60
71
  ```
61
- python -m splatlogger --ip IP [options]
72
+ python -m splatlogger --ip IP [options] / --cemu [PID] [options]
62
73
  ```
63
74
 
64
75
  ### Options
65
- - `-c [PID]`, `--cemu [PID]` - Switch to Cemu mode. The `--ip` argument is not required.
66
- - `PID` - Process ID of the Cemu process (optional).
67
-
68
76
  - `--log-level option` - Set how much data should be logged.
69
77
  - `none` - Don't create a log file.
70
78
  - `standard` - Log only basic player information, the same as what's printed to the console (default).
71
79
  - `extended` - Log all player information and additional match information.
72
- - `stats` - Same as above with the addition of player stats (points, K/D, win/lose) and disconnect detection.
80
+ - `stats` - Same as above with the addition of player stats (points, K/D, win/lose) and disconnect detection.
73
81
  Requires the match to end to finish logging; if it ends abruptly, the stats won't be logged.
74
82
 
75
83
  - `--service` - Choose which network service you're using.
76
84
  - `none` - Disable fetching account info.
77
85
  - `pretendo` - Pretendo Network (default).
78
- - `spfn` - Splatfestival Network.
86
+ - `altendo` - Altendo Network.
79
87
 
80
- - `-a [option]`, `--auto [option]` - Enable auto logging. When enabled will automatically log every match you play.
88
+ - `-a [option]`, `--auto [option]` - Enable auto logging. When enabled will automatically log every match you play.
81
89
  Also allows you to view information about the lobby/gathering while on the matching screen.
82
90
  - `all` - Save a log of all matches you play (default).
83
91
  - `latest` - Save a log of only the latest match.
84
92
 
85
- (These options don't affect anything if log level is set to `none`)
93
+ (These options don't affect anything if the log level is set to `none`)
86
94
 
87
95
  - `--stack Address (in hex)` - (Cemu only, optional) Beginning address of the stack space for Default Core 1 (Debug > View PPC threads).
88
96
  Only required for logging stats. If the default values don't work, you'll need to specify this manually.
@@ -113,7 +121,7 @@ Example `config.toml`:
113
121
  # Target Wii U LAN IP address (omit if using Cemu)
114
122
  ip = "192.168.1.50"
115
123
 
116
- # Target network service: "pretendo", "spfn", or "none"
124
+ # Target network service: "pretendo", "altendo", or "none"
117
125
  service = "pretendo"
118
126
 
119
127
  # Log level: "standard", "extended", "stats", or "none"
@@ -157,7 +165,7 @@ In that case, it's best to run the package from source or use the executable ins
157
165
  ## Important notes
158
166
  - The data collected by Splatlogger is public player info shared by the game with every user you play with in online matches.
159
167
 
160
- - Network IDs and Mii names are fetched from the Pretendo or SPFN account server; this can be disabled with `--service none`.
168
+ - Network IDs and Mii names are fetched from the network's account server; this can be disabled with `--service none`.
161
169
 
162
170
  - Splatlogger does not collect any sensitive information such as account email addresses or IP addresses.
163
171
 
@@ -166,28 +174,13 @@ In that case, it's best to run the package from source or use the executable ins
166
174
  - Please handle the logs responsibly. I do not encourage sharing other users' data without their permission, even if no real harm can be done with it.
167
175
 
168
176
  ## Building the executable with PyInstaller
169
- Set up a virtual environment and install PyInstaller as well as the required dependencies.
177
+ Set up a virtual environment and run `pip install -r build_requirements.txt` to install PyInstaller as well as the required dependencies.
170
178
 
171
- In `match_logger.py`, replace `from importlib import resources` with `import sys` and
172
- ```py
173
- names_path = resources.files(__package__).joinpath("resources", "names.json")
179
+ Run:
174
180
  ```
175
-
176
- with
177
- ```py
178
- names_path = Path(sys._MEIPASS) / "resources/names.json"
179
- ```
180
-
181
- Then run:
181
+ python scripts/build.py [--upx-dir path/to/upx]
182
182
  ```
183
- pyinstaller --noconfirm --onefile --console --name "Splatlogger-v1.x" --upx-dir "path/to/upx" --optimize "2" --add-data "path/to/Splatlogger/src/splatlogger/resources:resources/" --icon "NONE" "path/to/Splatlogger/src/run.py"
184
- ```
185
- replacing the placeholder paths with the actual ones.
186
-
187
- You can omit `--upx-dir` if you're not using UPX to compress the executable and `--optimize "2"` to disable
188
- bytecode optimization.
189
-
190
- On Linux, add `--bootloader-ignore-signals` and remove `--upx-dir` and `--icon` as they are not supported.
183
+ use `--upx-dir` if you're using UPX to compress the executable.
191
184
 
192
185
  ## Acknowledgments
193
186
  - NWPlayer123 for the reference implementation of a TCPGecko library.
@@ -1,24 +1,23 @@
1
1
  [build-system]
2
- requires = ["setuptools>=83.0.0"]
2
+ requires = ["setuptools>=77.0.3"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "Splatlogger"
7
- version = "1.2.1"
7
+ version = "1.2.3"
8
8
  authors = [
9
9
  { name="Shadow Doggo", email="shadowdoggo@protonmail.com" }
10
10
  ]
11
11
  description = "PID Grabber and player/match information logging tool for Splatoon"
12
12
  readme = "README.md"
13
- requires-python = ">=3.11"
13
+ requires-python = ">=3.10"
14
14
  dependencies = [
15
- "userpaths",
16
- "requests",
17
- "psutil",
18
- "pymemoryeditor>=2.0.0",
19
- "colorama",
20
- "clean-text",
21
- "prompt_toolkit"
15
+ "tomli>=1.1.0; python_version<'3.11'",
16
+ "userpaths>=0.1.3",
17
+ "requests>=2.28.0",
18
+ "colorama>=0.4.6",
19
+ "clean-text>=0.7.1",
20
+ "prompt_toolkit>=3.0.0"
22
21
  ]
23
22
  classifiers = [
24
23
  "Programming Language :: Python :: 3",
@@ -27,6 +26,15 @@ classifiers = [
27
26
  license = "MIT"
28
27
  license-files = ["LICENSE"]
29
28
 
29
+ [project.optional-dependencies]
30
+ cemu = [
31
+ "psutil>=5.9.0",
32
+ "pymemoryeditor>=2.0.0"
33
+ ]
34
+ build = [
35
+ "pyinstaller>=6.6.0"
36
+ ]
37
+
30
38
  [project.urls]
31
39
  "Source Code" = "https://codeberg.org/ShadowDoggo/Splatlogger"
32
40
 
@@ -1,22 +1,26 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Splatlogger
3
- Version: 1.2.1
3
+ Version: 1.2.3
4
4
  Summary: PID Grabber and player/match information logging tool for Splatoon
5
5
  Author-email: Shadow Doggo <shadowdoggo@protonmail.com>
6
6
  License-Expression: MIT
7
7
  Project-URL: Source Code, https://codeberg.org/ShadowDoggo/Splatlogger
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: Operating System :: OS Independent
10
- Requires-Python: >=3.11
10
+ Requires-Python: >=3.10
11
11
  Description-Content-Type: text/markdown
12
12
  License-File: LICENSE
13
- Requires-Dist: userpaths
14
- Requires-Dist: requests
15
- Requires-Dist: psutil
16
- Requires-Dist: pymemoryeditor>=2.0.0
17
- Requires-Dist: colorama
18
- Requires-Dist: clean-text
19
- Requires-Dist: prompt_toolkit
13
+ Requires-Dist: tomli>=1.1.0; python_version < "3.11"
14
+ Requires-Dist: userpaths>=0.1.3
15
+ Requires-Dist: requests>=2.28.0
16
+ Requires-Dist: colorama>=0.4.6
17
+ Requires-Dist: clean-text>=0.7.1
18
+ Requires-Dist: prompt_toolkit>=3.0.0
19
+ Provides-Extra: cemu
20
+ Requires-Dist: psutil>=5.9.0; extra == "cemu"
21
+ Requires-Dist: pymemoryeditor>=2.0.0; extra == "cemu"
22
+ Provides-Extra: build
23
+ Requires-Dist: pyinstaller>=6.6.0; extra == "build"
20
24
  Dynamic: license-file
21
25
 
22
26
  # Splatlogger
@@ -47,63 +51,71 @@ On Aroma, use [TCPGecko-Plugin](https://github.com/PinkDiamondTeam/TCPGecko-Plug
47
51
 
48
52
  ## Usage
49
53
  ### Running the executable
50
- Windows and Linux executables are provided on the Releases page.
54
+ Windows and Linux executables are provided on the [Releases](https://codeberg.org/ShadowDoggo/Splatlogger/releases/latest) page.
51
55
 
52
56
  Run Splatlogger with:
53
57
  ```
54
- path/to/Splatlogger-executable --ip IP [options]
58
+ path/to/Splatlogger-executable --ip IP [options] / --cemu [PID] [options]
55
59
  ```
56
- where `IP` is your Wii U's LAN IP address.
60
+ Use the `--ip` target where `IP` is your Wii U's LAN IP address,
61
+ or the `-c` / `--cemu` target to enable Cemu mode where `PID` is the process ID of the Cemu process (optional, should be detected automatically).
57
62
 
58
63
  Open a command prompt/terminal window and drag the executable into it to automatically get the path.
59
64
 
65
+ On Linux, you might need to make the file executable first with `chmod +x path/to/Splatlogger-executable`
66
+
60
67
  ### Running with Python
61
68
  You can install Splatlogger as a package from PyPI:
62
69
  ```
63
70
  pip install Splatlogger
64
71
  ```
65
72
 
66
- The run with:
73
+ To enable Cemu support, install with the `cemu` extra:
74
+ ```
75
+ pip install "Splatlogger[cemu]"
76
+ ```
77
+
78
+ Then run with:
67
79
  ```
68
- splatlogger --ip IP [options]
80
+ splatlogger --ip IP [options] / --cemu [PID] [options]
69
81
  ```
70
- (if that fails, try `python -m splatlogger`) where `IP` is your Wii U's LAN IP address.
82
+ (if that fails, try `python -m splatlogger`)
83
+
84
+ Use the `--ip` target where `IP` is your Wii U's LAN IP address,
85
+ or the `-c` / `--cemu` target to enable Cemu mode where `PID` is the process ID of the Cemu process (optional, should be detected automatically).
71
86
 
72
- To run from source instead, download the latest source archive from the Releases
87
+ To run from source instead, download the latest source archive from the [Releases](https://codeberg.org/ShadowDoggo/Splatlogger/releases/latest)
73
88
  page and extract it, then open a terminal window in the extracted directory.
74
89
 
75
90
  Install the required dependencies:
76
91
  ```
77
- pip install -r requirements.txt
92
+ pip install -r requirements.txt / cemu_requirements.txt
78
93
  ```
79
94
 
80
95
  Then move into the `src` directory and run:
81
96
  ```
82
- python -m splatlogger --ip IP [options]
97
+ python -m splatlogger --ip IP [options] / --cemu [PID] [options]
83
98
  ```
84
99
 
85
100
  ### Options
86
- - `-c [PID]`, `--cemu [PID]` - Switch to Cemu mode. The `--ip` argument is not required.
87
- - `PID` - Process ID of the Cemu process (optional).
88
-
89
101
  - `--log-level option` - Set how much data should be logged.
90
102
  - `none` - Don't create a log file.
91
103
  - `standard` - Log only basic player information, the same as what's printed to the console (default).
92
104
  - `extended` - Log all player information and additional match information.
93
- - `stats` - Same as above with the addition of player stats (points, K/D, win/lose) and disconnect detection.
105
+ - `stats` - Same as above with the addition of player stats (points, K/D, win/lose) and disconnect detection.
94
106
  Requires the match to end to finish logging; if it ends abruptly, the stats won't be logged.
95
107
 
96
108
  - `--service` - Choose which network service you're using.
97
109
  - `none` - Disable fetching account info.
98
110
  - `pretendo` - Pretendo Network (default).
99
- - `spfn` - Splatfestival Network.
111
+ - `altendo` - Altendo Network.
100
112
 
101
- - `-a [option]`, `--auto [option]` - Enable auto logging. When enabled will automatically log every match you play.
113
+ - `-a [option]`, `--auto [option]` - Enable auto logging. When enabled will automatically log every match you play.
102
114
  Also allows you to view information about the lobby/gathering while on the matching screen.
103
115
  - `all` - Save a log of all matches you play (default).
104
116
  - `latest` - Save a log of only the latest match.
105
117
 
106
- (These options don't affect anything if log level is set to `none`)
118
+ (These options don't affect anything if the log level is set to `none`)
107
119
 
108
120
  - `--stack Address (in hex)` - (Cemu only, optional) Beginning address of the stack space for Default Core 1 (Debug > View PPC threads).
109
121
  Only required for logging stats. If the default values don't work, you'll need to specify this manually.
@@ -134,7 +146,7 @@ Example `config.toml`:
134
146
  # Target Wii U LAN IP address (omit if using Cemu)
135
147
  ip = "192.168.1.50"
136
148
 
137
- # Target network service: "pretendo", "spfn", or "none"
149
+ # Target network service: "pretendo", "altendo", or "none"
138
150
  service = "pretendo"
139
151
 
140
152
  # Log level: "standard", "extended", "stats", or "none"
@@ -178,7 +190,7 @@ In that case, it's best to run the package from source or use the executable ins
178
190
  ## Important notes
179
191
  - The data collected by Splatlogger is public player info shared by the game with every user you play with in online matches.
180
192
 
181
- - Network IDs and Mii names are fetched from the Pretendo or SPFN account server; this can be disabled with `--service none`.
193
+ - Network IDs and Mii names are fetched from the network's account server; this can be disabled with `--service none`.
182
194
 
183
195
  - Splatlogger does not collect any sensitive information such as account email addresses or IP addresses.
184
196
 
@@ -187,28 +199,13 @@ In that case, it's best to run the package from source or use the executable ins
187
199
  - Please handle the logs responsibly. I do not encourage sharing other users' data without their permission, even if no real harm can be done with it.
188
200
 
189
201
  ## Building the executable with PyInstaller
190
- Set up a virtual environment and install PyInstaller as well as the required dependencies.
202
+ Set up a virtual environment and run `pip install -r build_requirements.txt` to install PyInstaller as well as the required dependencies.
191
203
 
192
- In `match_logger.py`, replace `from importlib import resources` with `import sys` and
193
- ```py
194
- names_path = resources.files(__package__).joinpath("resources", "names.json")
204
+ Run:
195
205
  ```
196
-
197
- with
198
- ```py
199
- names_path = Path(sys._MEIPASS) / "resources/names.json"
200
- ```
201
-
202
- Then run:
206
+ python scripts/build.py [--upx-dir path/to/upx]
203
207
  ```
204
- pyinstaller --noconfirm --onefile --console --name "Splatlogger-v1.x" --upx-dir "path/to/upx" --optimize "2" --add-data "path/to/Splatlogger/src/splatlogger/resources:resources/" --icon "NONE" "path/to/Splatlogger/src/run.py"
205
- ```
206
- replacing the placeholder paths with the actual ones.
207
-
208
- You can omit `--upx-dir` if you're not using UPX to compress the executable and `--optimize "2"` to disable
209
- bytecode optimization.
210
-
211
- On Linux, add `--bootloader-ignore-signals` and remove `--upx-dir` and `--icon` as they are not supported.
208
+ use `--upx-dir` if you're using UPX to compress the executable.
212
209
 
213
210
  ## Acknowledgments
214
211
  - NWPlayer123 for the reference implementation of a TCPGecko library.
@@ -12,6 +12,7 @@ src/splatlogger/__main__.py
12
12
  src/splatlogger/cemu_gecko.py
13
13
  src/splatlogger/cli.py
14
14
  src/splatlogger/enums.py
15
+ src/splatlogger/errors.py
15
16
  src/splatlogger/match_logger.py
16
17
  src/splatlogger/splatlogger.py
17
18
  src/splatlogger/tcpgecko.py
@@ -0,0 +1,15 @@
1
+ userpaths>=0.1.3
2
+ requests>=2.28.0
3
+ colorama>=0.4.6
4
+ clean-text>=0.7.1
5
+ prompt_toolkit>=3.0.0
6
+
7
+ [:python_version < "3.11"]
8
+ tomli>=1.1.0
9
+
10
+ [build]
11
+ pyinstaller>=6.6.0
12
+
13
+ [cemu]
14
+ psutil>=5.9.0
15
+ pymemoryeditor>=2.0.0
@@ -0,0 +1,2 @@
1
+ __version__ = "1.2.3"
2
+ __author__ = "Shadow Doggo"
@@ -0,0 +1,8 @@
1
+ try:
2
+ from .cli import cli
3
+ except ImportError:
4
+ from splatlogger.cli import cli
5
+
6
+
7
+ if __name__ == "__main__":
8
+ cli()
@@ -6,8 +6,11 @@ import struct
6
6
  from types import TracebackType
7
7
  from typing import Type
8
8
 
9
- import psutil
10
- from PyMemoryEditor import OpenProcess, ProcessIDNotExistsError # type: ignore[import-untyped]
9
+ try:
10
+ import psutil
11
+ from PyMemoryEditor import OpenProcess, ProcessIDNotExistsError # type: ignore[import-untyped]
12
+ except ImportError as ex:
13
+ raise ImportError("psutil and PyMemoryEditor must be installed to use Cemu mode.") from ex
11
14
 
12
15
 
13
16
  class CemuGecko:
@@ -3,7 +3,6 @@
3
3
  import argparse
4
4
  import platform
5
5
  import sys
6
- import tomllib
7
6
  import webbrowser
8
7
  from pathlib import Path
9
8
 
@@ -12,18 +11,22 @@ from colorama import Fore, Style, just_fix_windows_console
12
11
  from prompt_toolkit import PromptSession
13
12
  from prompt_toolkit.patch_stdout import patch_stdout
14
13
 
15
- from . import utility_functions as uf
16
- from .splatlogger import SplatloggerError, command_lobby_info, main
14
+ from . import utility_functions as uf, __version__
15
+ from .errors import SplatloggerError
16
+ from .splatlogger import command_lobby_info, main
17
17
  from .tuples import AppContext, Options
18
18
 
19
- VERSION = "1.2.1"
19
+ if sys.version_info >= (3, 11):
20
+ import tomllib
21
+ else:
22
+ import tomli as tomllib
20
23
 
21
24
 
22
25
  def cli() -> None:
23
26
  if platform.system() == "Windows":
24
27
  just_fix_windows_console()
25
28
 
26
- print(f"Splatlogger v{VERSION} by Shadow Doggo\n")
29
+ print(f"Splatlogger v{__version__} by Shadow Doggo\n")
27
30
 
28
31
  try:
29
32
  options = parse_args()
@@ -112,7 +115,7 @@ def add_parser_arguments(parser: argparse.ArgumentParser) -> None:
112
115
  parser.add_argument("--log-level", help="Set how much data should be logged (see README).",
113
116
  choices=["none", "standard", "extended", "stats"], default="standard")
114
117
  parser.add_argument("--service", help="Choose which network service you're using (Pretendo by default).",
115
- choices=["none", "pretendo", "spfn"], default="pretendo")
118
+ choices=["none", "pretendo", "altendo"], default="pretendo")
116
119
  parser.add_argument("-a", "--auto",
117
120
  help="Enable auto logging (see README).",
118
121
  choices=["all", "latest"], nargs="?", const="all")
@@ -130,7 +133,7 @@ CONFIG_TEMPLATE = """# Splatlogger Configuration
130
133
  # Target Wii U LAN IP address (omit if using Cemu)
131
134
  # ip = "192.168.1.50"
132
135
 
133
- # Target network service: "pretendo", "spfn", or "none"
136
+ # Target network service: "pretendo", "altendo", or "none"
134
137
  # service = "pretendo"
135
138
 
136
139
  # Log level: "standard", "extended", "stats", or "none"
@@ -0,0 +1,2 @@
1
+ class SplatloggerError(Exception):
2
+ pass
@@ -2,7 +2,7 @@
2
2
 
3
3
  import json
4
4
  import platform
5
- # import sys
5
+ import sys
6
6
  import time
7
7
  from datetime import datetime
8
8
  from importlib import resources
@@ -16,6 +16,13 @@ from .enums import Addresses, Offsets, Pointers, VSMode, VSRule
16
16
  from .tuples import AccountInfo, AppContext, CommonAddresses, PlayerInfo
17
17
 
18
18
 
19
+ def get_resource_path(relative_path: str | Path) -> Path:
20
+ if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"):
21
+ return Path(sys._MEIPASS) / relative_path
22
+
23
+ return Path(str(resources.files(__package__).joinpath(str(relative_path))))
24
+
25
+
19
26
  class MatchLogger:
20
27
  """Provides the match logging functionality of Splatlogger."""
21
28
 
@@ -24,8 +31,7 @@ class MatchLogger:
24
31
  self._ctx = ctx
25
32
  self._stats_offset: int | None = None
26
33
  self._align = 2 if ctx.options.auto_logging or ctx.options.single_log else 0
27
- names_path = resources.files(__package__).joinpath("resources", "names.json")
28
- # names_path = Path(sys._MEIPASS) / "resources/names.json"
34
+ names_path = get_resource_path("resources/names.json")
29
35
  try:
30
36
  with names_path.open("r", encoding="utf-8") as names_f:
31
37
  self._names: dict[str, Any] = json.load(names_f)
@@ -70,9 +76,9 @@ class MatchLogger:
70
76
  match_info = self._get_match_info()
71
77
  versus_mode, versus_rule = match_info[2], match_info[3]
72
78
  if self._ctx.options.log_level == "standard":
73
- match_log = (f"\nMatch {match_count}\n\n{uf.player_table_header(self._ctx.options.service == 'spfn')}\n"
79
+ match_log = (f"\nMatch {match_count}\n\n{uf.player_table_header(self._ctx.options.service == 'altendo')}\n"
74
80
  if self._ctx.options.auto_logging or self._ctx.options.single_log else
75
- f"\n{uf.player_table_header(self._ctx.options.service == 'spfn')}\n")
81
+ f"\n{uf.player_table_header(self._ctx.options.service == 'altendo')}\n")
76
82
  else:
77
83
  match_log = self._format_match_info(match_count, date, session_id, match_info)
78
84
 
@@ -144,7 +150,7 @@ class MatchLogger:
144
150
  )
145
151
 
146
152
  def _format_match_log(self, player_info: PlayerInfo, vs_mode: int) -> str:
147
- network_id_type = "SFID" if self._ctx.options.service == "spfn" else "PNID"
153
+ network_id_type = "ANID" if self._ctx.options.service == "altendo" else "PNID"
148
154
  indent = " " * (self._align + 2)
149
155
  fest_info = (
150
156
  f"{indent}Splatfest: Team: {self._get_name('fest_team', player_info.fest_team)} ({player_info.fest_team}) | "
@@ -1,5 +1,7 @@
1
1
  # Splatlogger (c) 2025 Shadow Doggo.
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  import binascii
4
6
  import ipaddress
5
7
  import logging
@@ -8,18 +10,20 @@ import time
8
10
  from base64 import b64decode
9
11
  from contextlib import contextmanager
10
12
  from datetime import datetime
11
- from typing import Callable, Iterator
13
+ from typing import Callable, Iterator, TYPE_CHECKING
12
14
 
13
15
  import requests
14
16
  import userpaths # type: ignore[import-untyped]
15
17
 
16
18
  from . import utility_functions as uf
17
- from .cemu_gecko import CemuGecko, CemuGeckoError
18
19
  from .enums import Offsets, Pointers
19
20
  from .match_logger import MatchLogger
20
21
  from .tcpgecko import GeckoConnectionFailedError, TCPGecko
21
22
  from .tuples import AccountInfo, AppContext, CommonAddresses, Options, PlayerInfo
22
- from .utility_functions import SplatloggerError
23
+ from .errors import SplatloggerError
24
+
25
+ if TYPE_CHECKING:
26
+ from .cemu_gecko import CemuGecko
23
27
 
24
28
  # Hack to remove the unidecode warning from clean-text
25
29
  logging.disable(logging.CRITICAL)
@@ -94,7 +98,7 @@ def command_lobby_info(ctx: AppContext) -> bool:
94
98
  if players:
95
99
  print("\nPlayers (from first to last joined, you will always be first):")
96
100
  print(
97
- f"\n{'PID':<10} | {'SFID' if ctx.options.service == 'spfn' else 'PNID':<16}\n{'-' * 30}"
101
+ f"\n{'PID':<10} | {'ANID' if ctx.options.service == 'altendo' else 'PNID':<16}\n{'-' * 30}"
98
102
  )
99
103
  for player in players:
100
104
  print(f"{player[0]} | {player[1]}")
@@ -123,6 +127,11 @@ def create_match_logger_instance(ctx: AppContext) -> MatchLogger | None:
123
127
 
124
128
  def create_tcpgecko_instance(options: Options) -> TCPGecko | CemuGecko:
125
129
  if options.platform == "cemu":
130
+ try:
131
+ from .cemu_gecko import CemuGecko, CemuGeckoError
132
+ except ImportError as e:
133
+ raise SplatloggerError(str(e)) from e
134
+
126
135
  try:
127
136
  print("Opening Cemu process...")
128
137
  return CemuGecko(options.cemu_pid)
@@ -194,7 +203,7 @@ def splatlog(ctx: AppContext, match_logger: MatchLogger | None, match_count: int
194
203
  session_id = get_session_id(ctx)
195
204
  player_count = get_player_count(ctx, adrs.main_mgr_base_adr)
196
205
 
197
- print_if_not_silent(ctx, uf.player_table_header(ctx.options.service == "spfn"))
206
+ print_if_not_silent(ctx, uf.player_table_header(ctx.options.service == "altendo"))
198
207
 
199
208
  player_info_list: list[PlayerInfo] = []
200
209
  request_errors: list[str] = []
@@ -291,7 +300,7 @@ def get_player_account_info(ctx: AppContext, player_pid: int, player_name: str)
291
300
  if ctx.options.service == "none":
292
301
  return AccountInfo("", player_name, "")
293
302
 
294
- act_info = get_spfn_account_info(player_pid) if ctx.options.service == "spfn" else get_pn_account_info(player_pid)
303
+ act_info = get_altendo_account_info(player_pid) if ctx.options.service == "altendo" else get_pn_account_info(player_pid)
295
304
  if act_info.request_error:
296
305
  return AccountInfo("", player_name, act_info.request_error)
297
306
 
@@ -382,7 +391,7 @@ def get_pn_account_info(player_pid: int) -> AccountInfo:
382
391
  time.sleep(1)
383
392
  continue
384
393
 
385
- response = uf.process_response(raw_response, spfn=False)
394
+ response = uf.process_response(raw_response, altendo=False)
386
395
  if response is None:
387
396
  request_error = "Got empty or invalid response."
388
397
  time.sleep(1)
@@ -397,7 +406,7 @@ def get_pn_account_info(player_pid: int) -> AccountInfo:
397
406
  return AccountInfo(user_id, mii_name, request_error)
398
407
 
399
408
 
400
- def get_spfn_account_info(player_pid: int) -> AccountInfo:
409
+ def get_altendo_account_info(player_pid: int) -> AccountInfo:
401
410
  user_id = ""
402
411
  mii_name = ""
403
412
  request_error = ""
@@ -405,12 +414,12 @@ def get_spfn_account_info(player_pid: int) -> AccountInfo:
405
414
  for _ in range(3):
406
415
  try:
407
416
  raw_response = requests.get(
408
- f"https://account.spfn.net/v1/api/admin/mapped_ids?input_type=pid&output_type=user_id&input={player_pid}",
417
+ f"https://account.altendo.cc/v1/api/admin/mapped_ids?input_type=pid&output_type=user_id&input={player_pid}",
409
418
  headers={"User-Agent": "Mozilla/5.0"},
410
419
  timeout=5
411
420
  )
412
421
  mii_data_response = requests.get(
413
- f"https://account.spfn.net/api/v2/users/{player_pid}/mii",
422
+ f"https://account.altendo.cc/api/v2/users/{player_pid}/mii",
414
423
  headers={"User-Agent": "Mozilla/5.0"},
415
424
  timeout=5
416
425
  )
@@ -425,7 +434,7 @@ def get_spfn_account_info(player_pid: int) -> AccountInfo:
425
434
  time.sleep(1)
426
435
  continue
427
436
 
428
- response = uf.process_response(raw_response, spfn=True)
437
+ response = uf.process_response(raw_response, altendo=True)
429
438
  if response is None:
430
439
  request_error = "Got empty or invalid response."
431
440
  time.sleep(1)
@@ -6,11 +6,10 @@ import threading
6
6
  from dataclasses import dataclass, field
7
7
  from typing import NamedTuple, TYPE_CHECKING
8
8
 
9
- from .cemu_gecko import CemuGecko
10
- from .tcpgecko import TCPGecko
11
-
12
9
  if TYPE_CHECKING:
13
10
  from prompt_toolkit import PromptSession
11
+ from .cemu_gecko import CemuGecko
12
+ from .tcpgecko import TCPGecko
14
13
 
15
14
 
16
15
  class Options(NamedTuple):
@@ -14,6 +14,7 @@ import requests
14
14
  from colorama import Fore, Style
15
15
 
16
16
  from .enums import Offsets
17
+ from .errors import SplatloggerError
17
18
  from .tcpgecko import GeckoConnectionClosedError, GeckoReadMemError, TCPGeckoError
18
19
  from .tuples import AccountInfo, PlayerInfo
19
20
 
@@ -26,8 +27,8 @@ from cleantext import clean # type: ignore[import-untyped]
26
27
  logging.disable(logging.NOTSET)
27
28
 
28
29
 
29
- def player_table_header(spfn: bool) -> str:
30
- return f"{'Player':<8} | {'PID':<10} | {'SFID' if spfn else 'PNID':<16} | Name\n{'-' * 60}"
30
+ def player_table_header(altendo: bool) -> str:
31
+ return f"{'Player':<8} | {'PID':<10} | {'ANID' if altendo else 'PNID':<16} | Name\n{'-' * 60}"
31
32
 
32
33
 
33
34
  def player_table_entry(player_info: PlayerInfo, act_info: AccountInfo) -> str:
@@ -81,12 +82,12 @@ def handle_gecko_errors(func: Callable[..., Any]) -> Any:
81
82
  return wrapper
82
83
 
83
84
 
84
- def process_response(response: requests.Response, spfn: bool) -> tuple[str, str] | None:
85
+ def process_response(response: requests.Response, altendo: bool) -> tuple[str, str] | None:
85
86
  try:
86
87
  root = ElementTree.fromstring(response.text)
87
88
  assert len(root) != 0
88
89
 
89
- if spfn:
90
+ if altendo:
90
91
  user_id = root[0].find("out_id")
91
92
  assert isinstance(user_id, ElementTree.Element) and user_id.text is not None
92
93
 
@@ -139,7 +140,3 @@ def get_utc_offset(date: datetime) -> int:
139
140
  return 0
140
141
 
141
142
  return round(offset.total_seconds() / 3600)
142
-
143
-
144
- class SplatloggerError(Exception):
145
- pass
@@ -1,7 +0,0 @@
1
- userpaths
2
- requests
3
- psutil
4
- pymemoryeditor>=2.0.0
5
- colorama
6
- clean-text
7
- prompt_toolkit
File without changes
@@ -1,4 +0,0 @@
1
- from .cli import cli
2
-
3
- if __name__ == "__main__":
4
- cli()
File without changes
File without changes