Commit Graph

416 Commits

Author SHA1 Message Date
icex2
4f97282d97 React(iidxhook4-cn): Use sdk-hook and support new config api
Summary:

Test Plan:
Summary:

Test Plan:
2024-08-17 12:49:18 +02:00
icex2
617550b6e6 refact(iidxhook4): Use sdk-hook and support new config api
Summary:

Test Plan:
Summary:

Test Plan:
2024-08-15 13:26:41 +02:00
icex2
f3deaddba1 refact(iidxhook3): Use sdk-hook and support new config api
Summary:

Test Plan:
Summary:

Test Plan:
2024-08-15 13:26:41 +02:00
icex2
95e167c01c refact(iidxhook2): Use sdk-hook and support new config api
Summary:

Test Plan:
2024-08-15 13:26:20 +02:00
icex2
4e6385ea27 feat(iidxhook1): Implement hook cleanup
Summary:

Test Plan:
2024-08-15 13:24:47 +02:00
icex2
206e92a7d4 chore(iidxhook1): Cleanup unused headers, fix naming
Summary:

Test Plan:
Summary:

Test Plan:
2024-08-15 13:24:47 +02:00
icex2
51f3b07acf feat: Add missing cleanup functions various iidx hook modules
Summary:

Test Plan:
2024-08-15 13:24:47 +02:00
icex2
20e7cdaa31 fix: Setup config API on minimial boot env
Summary:

Test Plan:
2024-08-15 13:24:47 +02:00
icex2
b031d40d2d feat: Add helper to setup logger with null sink
Summary:

Test Plan:
2024-08-15 13:24:47 +02:00
icex2
9c538cccac fix: Add property node printing for float and double types
Summary:

Test Plan:
2024-08-15 13:24:47 +02:00
icex2
c3835118b1 chore: Improve log output, include config path
Summary:

Test Plan:
2024-08-15 13:24:47 +02:00
icex2
5531726fc2 feat(iidxhook1): Use sdk-hook and support config api
Summary:

Test Plan:
Read any configuration values through bemanitools's
configuration API abstraction. This still had to be
hooked up when a hook dll is being loaded. The
current implementation relies on an environment
variable providing the path to the original inject
configuration file, then it extracts the relevant hook
configuration section for the currently loaded hook
library.

This adheres to the limitations of not having any
other entry points than DllMain for a hook library
(as of now).
2024-08-15 13:24:47 +02:00
icex2
833fa2f99c feat: Add sdk-hook
Module to handle environment setup for hooks that use DllMain and
calls the bemanitools 6 API for hooks. This way, all hooks that use inject
(no AVS available) can be refactored and use the same API as any hooks that use launcher (with AVS available).

Remark: Module namespacing is not proper. This should move to a separate
part of the project that’s purely holding SDK related code that can be used
by other developers on other projects without requiring the whole
bemanitools project checkout. This problem is considered out of scope for now.
2024-08-15 11:34:34 +02:00
icex2
73da986d0b refactor: Inject
- Split into modules similar to launcher to improve overall structure
- Use property (node) API for configuration

Remark: "MVP" without IAT hooking working, command line arguments and overriding. Will be added (again) later
2024-08-15 11:34:33 +02:00
icex2
c965011788 feat: Add config-ext
Add wrapper functions that fatal on any error.
Saves a lot of error checking code on occasions
where we want to fail anyway because some
configuration value could not be retrieved
successfully.
2024-08-15 11:34:33 +02:00
icex2
e3c97801ed feat: Property (node) API impl with mxml
To provide a unified backend for all games, no
matter if they have AVS 2 available or now, use the
property (node) abstraction for any means of
configuration. This is somewhat annoying and a pain
because the property API isn't amazing. However,
the past has shown that having different means of
providing and handling (structured) configuration
data isn't great either.

Thus, have a non AVS implementation that allows
AVS independent applications/old games to use
the same core bemanitools API.
Summary:

Test Plan:
Summary:

Test Plan:
2024-08-15 11:34:33 +02:00
icex2
7a6c3af9c8 feat: Add log-ext, handle win last errors
Helper to easily deal with GetLastError, log it and
make the application fail
2024-08-15 11:34:33 +02:00
icex2
d73ded1895 chore: Add more debug logging
Good to know if the API actually got initialized
when tracing issues with these.
2024-08-15 11:34:33 +02:00
icex2
9a87281603 chore: Decrease log message level on debug messsage
Summary:

Test Plan:
2024-08-15 11:34:33 +02:00
icex2
57da0404cf fix: "Atomic" output log messages on minimial boot env, debug
Fully format log messages and call
OutputDebugStringA only once. This avoids getting
split log messages on concurrent calls to
OutputDebugStringA.
2024-08-15 11:34:33 +02:00
icex2
690d3b1385 fix: Default print to stderr and not stdout
Allows using stdout for outputting data/result
and not mixing it with log messages (by default).
2024-08-15 11:34:33 +02:00
icex2
b188b938dc chore: Add missing log module define
Module name becomes easier to recognize on
log statements.
2024-08-15 11:34:33 +02:00
icex2
b9819c9cb5 fix: Expose typedef in header
Required to re-use it in other modules to
type the hook api get function
2024-08-15 11:34:33 +02:00
icex2
d3b3951eee fix: Typo
Summary:

Test Plan:
2024-08-15 11:34:33 +02:00
icex2
dbd1a4c3e0 feat: Turn into macros to log line numbers correctly
See the comment on the macro
2024-08-15 11:34:33 +02:00
icex2
f990d839af chore: Remove property (node) log from API, make ext(ension) function
There is no need for different implementations
for this depending on the property (node) backend.
Thus, have these as ext(ension) functions that
already use parts of the actual API to implement
logging property (node) structures.
2024-08-15 11:34:32 +02:00
icex2
14f534b993 fix: Log fatal force flush
Summary:

Test Plan:
2024-08-15 11:34:32 +02:00
icex2
45d7a29cba feat: Add mxml
I checked out the few xml implementations that
are available as pure C and this one seemed like
the best choice so far. It's fairly small regarding
foot print, similar API to the property (node) API,
and I could get it to work fairly easily with a few
sandbox examples thanks to decent documentation.

This serves as the base for a bemanitools property
(node) implementation for games that do not come
with AVS 2 and the property API.
2024-08-15 11:34:32 +02:00
icex2
ee8f2a05fe refactor: property_node attribute handling
The previous implementation just went along with how AVS
property models and deals with attributes: attributes are just
another type of node that follow the same rules as standard
xml nodes/elements.

This design already showed several flaws in application as
these nodes always had to be referred to with an appended
‘@‘ on the attribute keys. This was mitigated with an “ext”
function that hides the whole details of “find the attribute node
before reading the attribute” steps.

By adding another property_node implementation with mxml,
the AVS style abstract layer showed incompatibilities with
the “an attribute is a node” approach. mxml doesn’t treat them as a type of node and just addresses them directly using their keys. This is lot simpler and aligns with how handling
attribute is done throughout the code thus far.

Refactor the property_node interface and the current AVS
implementation to also adapt this. Hide the detail that AVS
treats attributes as nodes and also the whole “append @“
to the keys notation.
2024-08-15 11:34:32 +02:00
icex2
a79c40b626 doc(inject): Remark regarding performance impact logging 2024-08-15 11:34:32 +02:00
icex2
27e9f8dea8 feat(inject): Use async log sink for logging
Solves similar issues with the old games not using
the AVS logging system (because there is none).

Threads calling the log functions are still logging
using OutputDebugStr, but the dispatching in the
debugger module in inject hands those messages
off to the async log sink which avoids blocking
the calling thread (for long).

We want to keep this feature around as there are
several games actually having non-removed
OutputDebugStr calls which can provide some
useful debugging information.

Furthermore, neutral hooks only using DllMain
and not the bemanitools API can still channel
log messages this way to bemanitools’s logging
system (though less efficiently than calling it
directly).

Further changes to existing hooks will be applied
to migrate their logger usage to using the logger
directly through the bemanitools API.
2024-08-15 11:34:32 +02:00
icex2
8bb8c3364e sqash with removal of log server 2024-08-15 11:34:32 +02:00
icex2
3f4dab5fd6 feat: Add helpers to easily setup the async logging sink 2024-08-15 11:34:32 +02:00
icex2
a970884873 feat(core): Async log sink
A long awaited solution to address several
long-standing problems:

* Remove the need for log-server band-aid for iidx
   versions using ezusb and the modern AVS logging
   System, i.e. iidx 19 to 24. Any non AVS thread calling
   the AVS log functions will crash due the mutex
   implementation in AVS being not compatible with
   non AVS threads (see the journal entry in the dev docs
   for the whole story).
* Discontinue using the AVS log functions instead of
   bemanitools’s own ones. There was never a technical
   reason to do that, actually. It was neat to share one common
   interface, but that was about it.
* Fixes performance issues on several games such as stuttering
   brief slowdowns and de-syncs

Why not make this an integral part of the logger? There are
situations where async logging is not desired, e.g. ensure
predictiable logging output during debugging/development
tasks, and performance doesn’t matter at this point.

With the decision to implement this as a sink, the async
component can be easily composed arbitrarily with the other
existing log sinks.
2024-08-15 11:34:32 +02:00
icex2
c3d95b0ffd feat(core): Expose message size on logger as parameter
Make this configurable. Normally the buffer size
doesn’t need to be 64k, that’s only required for
very verbose debug/development logging output.

Furthermore, the parameter needs to shared and
aligned with the async logger which has it’s own
buffer size. This avoids tight coupling between
the async sink and the logger.
2024-08-15 11:34:32 +02:00
icex2
903bddddce refactor(config): Use helper to setup logging
Reduces code a little code bloat
2024-08-15 11:34:32 +02:00
icex2
9540e9e115 feat: Use async logger in launcher 2024-08-15 11:34:32 +02:00
icex2
87fb71d769 feat: Add missing macro to check for errors
Other parts of core have this already, align
as these are useful to make the code more
readable.
2024-08-15 11:34:31 +02:00
icex2
71e6b1e29f fix: bootstrapping with logger on extiotest
Missing the core_boot setup and incorrect
order when setting the api. This must come
after initializing the actual logging system.
2024-08-15 11:34:31 +02:00
icex2
3987ef99ac fix: Mutex the std logging sink on colored messages
This is required to ensure colored log messages
are executed as an atomic operation. Otherwise,
the color code information written to the terminal
could interleave with concurrent log messages
which results in “randomly” colored messages or
parts of them.
2024-08-15 11:34:31 +02:00
icex2
e61dfb3977 refactor: Move all hook and IO libraries to use btools log and thread api
Remove usages of AVS threads and logging functions from the bemanitools backend. Use the bemanitools 6 API instead
which propagates interfaces to call thread and log APIs.

Prior design decisions for using these were:
- have a single log stream through the AVS logging system for “neatness”, log output redirection options in launcher, and theoretically logging to an xrpc endpoint
- IIDX 19 to IIDX 24 crash the AVS logging engine in libavs due to IO hook code running in a non AVS thread (threads in ezusb library) causing a stackoverflow when trying to acquire a mutex (see dev journal 2018-02-10-logging-breakdown-avs.md for details)

With a flexible log sink architecture in the core of bemanitools, and a separate writer function that is hooked up as a log writer to AVS, log streams are still unified on a sink level. This takes care of having all log messaged sinked to the same targets no matter how many logging engines are using them.

This avoids going through the AVS logging engine with the IO related hooking code in iidx, which just uses the bemanitools logging engine instead.

Furthermore, this removes any needs to having to switch thread and logging implementations once AVS is booted which significantly simplifies the runtime orchestration during bootstrapping.

The log-server, which was specifically implemented for iidx to solve the threading issue, can also be removed now. Unfortunately, this also caused performance issues such as stuttering due to it’s rather simplistic implementation.
2024-08-15 11:34:31 +02:00
icex2
57e68f928a feat: bemanitools 6 initial refactoring drop, alpha 1
**THIS IS A HIGHLY WORK/DEVELOPMENT IN PROGRESS VERSION**

**THINGS ARE BROKEN AND EVERYTHING IS SUBJECT TO CHANGE**

First cut after massive refactoring with most critical and fundamental changes implemented.
We need to start somewhere, and this might be as good as anything else, so we can get started
with testing, bug fixing and iterating for the next releases.

The following list is non-exhaustive, does not guarantee anything does work, yet, and is supposed
to give a high level idea of what all of this is about. Updated documentation will reflect all of
this at some later point in time in more detail.

* A common "core" now abstracts logging, thread, property and configuration infrastructure and
  provides a common interface. This is used by bemanitools internally as well as all tools, hooks
  and APIs provided and don't depend on the game, version of the game or AVS version available
  anymore
* New bemanitools (public) API
  * Versioned API allowing for handling incremental API changes as well as breaking changes by
    providing a new/different version when necessary
  * Unified interfaces for bemanitools core API, i.e. logging, threads, configuration
  * SDK with examples (TBD)
  * Dogfooding approach: Bemanitools uses its own (public) API to implement and provide fundamental
    features like configurable keyboard implementations for IO or hooks for different games and
    versions
* All bemanitools hooks and IO libraries have been or are about to be re-worked to use the new APIs
* New hook API allows for more fine grained runtime control when stages of the hook are to be
  executed, i.e. pre AVS, before main game, iat hooking instead of relying purely on DllMain
  (which is still a compatible option though)
* launcher as a replacement for bootstrap: Bring it significantly closer to the original bootstrap
  by supporting completely vanilla data and bootstrap.xml configurations to run the games. Note
  that bemanitools does not include any code or means to run DRM'd data, only decrypted
* inject is also being reworked to use as much of the same "infrastructure" as launcher to provide
  a more seamless bootstrapping process for games that keeps pre-eapki data as vanilla as possible
Summary:

Test Plan:
Summary:

Test Plan:
Summary:

Test Plan:
Summary:

Test Plan:
2024-08-15 11:34:31 +02:00
icex2
106b908f17 feat(launcher): Integrate procmon as optional dependency
Integrate this as an optional dependency into launcher and
load it dynamically. Thus, these can be easily loaded/enabled
by developers and end-users.
2024-08-14 17:53:52 +02:00
icex2
fd9f455bf3 feat(procmon): Library to hook and monitor selected system calls
A general debugging tool. 3rd party applications such as
"procmon" (same name) provide these capabilites and even
more. But, they are more difficult to run with bemanitools
and don't provide a unified look at the output in combination
with the log output by bemanitools.

Provide an initial set of system call hooks that have already
supported debugging efforts. More can be added when needed
later.
2024-08-14 17:53:52 +02:00
icex2
aaef2d94c5 feat(launcher): Improve error output when missing vcredist deps
Apply a simple heuristic to provide the user with more
specific information regarding which vcredist package
might not have been found on their system.

This is a common problem as different games require
different versions and different versions of windows
and installations might already come with some versions
already pre-installed.

Also improve the readme regarding that and provide links
to all versions that are required by one game or another
today.
2024-08-14 17:53:52 +02:00
icex2
1b8bf7b245 feat(util): Separate debug module with proper stacktrace printing
Because we are using mingw, we can't just use window's
dbghelp library as the symbols created are in dwarf format.

Fortunately, the dwarfstack library already provides all the
facilities to easily print very descriptive stacktraces,
including function names, file names and line numbers,
when dwarf symbols are available.

This moves the incomplete exception handling portion from
signal to a separate module as well to improve scoping.
2024-08-14 17:53:52 +02:00
icex2
4b352ed080 feat(inject): Use new exception handler with stacktraces
Adjust inject to utilize the new feature. This also
requires including the dwarfstack.dll in all distribution
packages.
2024-08-14 17:53:51 +02:00
icex2
4b38f50a39 fix(mingw): Version upgrade caused this to error
HRESULT not defined fixed by including windows header
2024-08-14 17:53:51 +02:00
icex2
35ca49fe7e refactor(launcher): Major re-work of launcher
Kudos to Shiz for providing the groundwork for this.

Fundamentally re-think how launcher operates and
bootstrapping the games is managed and configured.

This brings it significantly closer to how the original
bootstrap is doing the job: launcher now utilizes the
data (structures) provided by the bootstrap.xml configuration
file. This creates compatibility with vanilla data dumps
and original stock images. Note that bemanitools does not
include any code or means to run DRM'd data, only decrypted.

But, this allows users to keep decrypted dumps as stock as
possible which means:

* No copying around of property files anymore
* Keep the modules/ folder with the binaries
* Have bemanitools binaries separate in the data
* No need to edit/customize the original configuration files

A list of key features of the "new" launcher:

* Boostrap games by following the configuration provided by
  stock game's bootstrap.xml files
* Custom launcher.xml configuration file that adds further
  launcher configurable features, composability of
  bootstrap.xml configuration(s) as well as configuration
  overriding/stacking of selected types of configurations,
  e.g. eamuse config, avs-config. The latter eliminates
  the need for modifying stock config files in the prop/
  folder
* Unified logging system: launcher and AVS logging uses
  the same logger, all output can now be in a single file
* Original features such as various hook types still
  available

Due to the significant architectural changes, this also
breaks with any backwards compatibility to existing
launcher setups. Thus, users need to migrate by re-applying
the new configuration format and migrating their config
parameters accordingly.

Further migration instructions and updated documentation
will be provided upon release.

Co-authored-by: Shiz <hi@shiz.me>
2024-08-14 17:53:51 +02:00
icex2
947050d0c8 refactor(inject): Use new core thread and log modules
Keep this a separate commit because this also removes
inject's own logging engine and replaces it with the
streamlined core API. The core API provides all the
features of inject's own logging engine which also
performed horribly. The entire logging operation
was locked which included expensive operations
that formatted the log messages and required
memory allocations and copying around data.

The core API's implementation at least only
synchronizes the actual IO operations
(though this can be improved further with an
actual async logging sink, TBD)
2024-08-14 17:53:51 +02:00