Code Monkey home page Code Monkey logo

mtgosdk's Introduction

@videre/monorepo

⚡ Quick Links

Overview

Packages

Isomorphic JavaScript utilities optimized for performance and DX.
Exposes APIs for testing and building scalable NodeJS applications.
Re-packages binaries to partition builds for AWS build-size limits.
Optimizes Puppeteer for fast execution on Serverless platforms.

Services

A real-time globally distributed API for Magic: The Gathering.
A Discord Bot for Magic: The Gathering cards, deck building, and strategy.

✨ Getting Started

Installation

1. Installing NodeJS

NodeJS (aka Node) is a cross-platform JavaScript environment built on top of the V8 engine that powers Google Chrome. It is used for testing and running packages and applications developed in this project. NodeJS also comes packaged with the NPM package manager, which is recommended for installing global dependencies.

You can download a NodeJS installer from the official downloads page, or through a package manager.

Verify or check your installed NodeJS version by running the below command:

node --version

Note If a project requires a specific version of NodeJS determined by the V8 version, use:

$ node
> process.versions.v8
'9.4.146.19-node.13'

2. Installing Yarn

This project uses the Yarn package manager to manage project dependencies and scripts. Yarn version 3.5.0+ is supported, though it's recommended to install Yarn through Corepack as detailed below.

Note If you're using Yarn <2.0, you can upgrade by running yarn set version berry.

The recommended way to install or upgrade Yarn is through a NodeJS binary called Corepack. Corepack installs a proxy for Yarn or PNPM binaries that transparently intercepts Yarn or PNPM commands, installs them (if not already installed), and runs the command. This vastly simplifies installation and versioning of package managers across NodeJS projects without the fuss of OS-specific quirks.

To install Yarn through Corepack, run the below command(s) depending on your NodeJS version:

# For NodeJS v16.9.0+ and v14.19.0+
$ corepack enable

# For NodeJS <16.10
$ npm uninstall -g yarn pnpm
$ npm install -g corepack

When completed, verify yarn installs successfully:

$ yarn --version
3.5.0

To install project dependencies, run yarn or yarn install. For a comprehensive list of Yarn commands, consult the Yarn docs.

Working with Yarn Workspaces

This project uses a monorepo approach to manage dependencies and projects. Monorepos allow for a simplified developer experience, providing better discoverability and atomicity.

With the Yarn workspaces feature, multiple packages and applications can easily coexist and cross-reference each other across different workspaces (aka packages/ or services/). This aids in the efficiency of testability and sharability of configurations, packages and applications without duplicating dependencies or code.

You can list all available workspaces by running:

$ yarn workspaces list

To run a script from a specific workspace, run:

$ yarn workspace <workspace> run <script>
# or
$ yarn workspace <workspace> <script>

Note You can also use yarn run <script> or yarn run <script> to run a script from your current working directory. This is the recommended way of running scripts if you're working on a specific project.

Additionally, to run scripts by name from all workspaces, use:

$ yarn workspaces foreach <script>

Configuring projects

In addition to sharing dependencies with yarn workspaces, projects can also share scripts from the config/ workspace withing adding any dependencies to the project's project.json file. This allows for a single source of truth for running scripts across the monorepo.

Shared configs also typically contain base configurations and executables for extending and bootstrapping new projects, establishing sensible defaults or extending the base functionality of tooling. This is useful if nuances in a base configuration can't be separated into individual configuration files, where it'd instead make more sense to control or vendor features programmatically.

Below is a breakdown of all shared configs in this monorepo:

Config Docs Scripts Command
Typescript logo CLI
Config
watch
force
clean
prepack
$ yarn tsc <...args?>
$ yarn g:config tsc -d <workspace> <...args?>
Jest logo CLI
Config
watch
clean
$ yarn jest <...args?>
$ yarn g:config jest -d <workspace> <...args?>

Learn more about running shared scripts with the Yarn Global Runner.

Yarn Global Runner

Run workspace scripts anyhow and from anywhere with the yarn global runner.

This allows you to run pre-defined scripts like yarn jest clean. You can run your own commands independently or combine them with pre-defined scripts, e.g. with yarn tsc watch --target ES5 or yarn tsc -w --target ES5.

In yarn configured projects, just run:

# > videre-project/packages/@videre-nodejs/:
$ yarn jest <...args?>
# or
$ yarn tsc <...args?>

Or in any other project directory, run with g:workspace or g:config:

# > videre-project/.../:
$ yarn g:workspace @videre/js jest <...args?>
# or
$ yarn g:config jest -d @videre/nodejs <...args?>
More examples

For workspace scripts, run commands with g:workspace:

# > videre-project/.../:
$ yarn g:workspace <workspace> <...flags?> <script> <...args?>
# e.g.
$ yarn g:workspace @videre/js -v jest --watch -- file.test.ts
$ yarn g:workspace config-jest -d @videre/js -v watch -- file.test.ts

For config scripts, run commands with g:config:

# > videre-project/.../:
$ yarn g:config <workspace> <...flags> <script> <...args?>
# e.g.
$ yarn g:config jest -d @videre/js -v watch -- file.test.ts

Optional flags include:

  • (-d|--default) Passes a default argument to a script. You can pass multiple arguments with -d foo bar --.
  • (-q|--quiet) Disables yarn runner output (perserves script output).
  • (-v|--verbose) Enables verbose yarn runner script tracing.

Note The default argument for g:config scripts must be the current working directory or the name/location of a workspace. This is done to allow for scripts to efficiently read and execute in the expected workspace location.

🔥 Contributing

Contributions of any size to this project are always welcome!

Refer to CONTRIBUTING.md for instructions (and tips) on making contributions to this project.

⚖️ License

Apache-2.0 License.

mtgosdk's People

Contributors

qonfused avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

mtgosdk's Issues

Add SourceLink support to MTGOSDK

Enabling SourceLink allows VS debuggers to download source files based on commit information and symbols embedded in published binaries (reference). It essentially allows debuggers to further inspect calls within the MTGOSDK library.

For our purposes, it is preferred to distribute separate .snupkg PDBs so that debuggers can download symbols directly from NuGet, and avoid bundling additional resources into the ScubaDiver assembly (which consumes MTGOSDK.Core).

[MTGOSDK.Ref] Generate reference assemblies on restore

To avoid re-distributing MTGO assemblies, this project should make use of reference assemblies built against the latest ClickOnce deployment URLs for MTGO (or pulled from the client install path).

I'm unsure of whether to distribute these reference assemblies as a package, or just to leave it as an internal library used by the SDK. The latter case may be all that is needed to be done.

To maintain parity between the dotnet CLI and Visual Studio environment, any codegen tasks should be run with the below MSBuild targets:

<!--
  Runs before Restore and Compile targets for dotnet CLI and Visual Studio.
  Refer to https://github.com/NuGet/Home/issues/4781 for more info.
-->
<Target Name="PreBuild" BeforeTargets="_GenerateRestoreProjectSpec;CollectPackageReferences;Restore;Compile">
    ...
</Target>

Migrate HTTP clients to gRPC

Using gRPC should allow for better interop between languages and the host/client processes with support for bidirectional streaming, flow control, and comparatively better error handling. This will upgrade communication to HTTP/2 and require additional codegen for supporting protocol buffers.

Microsoft has a tutorial here explaining how to support this with existing C#/MSBuild projects, though this may be a better migration path for #2.

Tasks

  1. Qonfused
  2. Qonfused
  3. Qonfused

MSB3277 - Version conflict with 'System.Net.Http' between netstandard2.0 and netframework4.8

2>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\amd64\Microsoft.Common.CurrentVersion.targets(2364,5): warning MSB3277: Found conflicts between different versions of "System.Net.Http" that could not be resolved.
 warning MSB3277: There was a conflict between "System.Net.Http, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" and "System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
 warning MSB3277:     "System.Net.Http, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" was chosen because it was primary and "System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" was not.
 warning MSB3277:     References which depend on "System.Net.Http, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" [C:\Program Files\dotnet\packs\NETStandard.Library.Ref\2.1.0\ref\netstandard2.1\System.Net.Http.dll].
 warning MSB3277:         C:\Program Files\dotnet\packs\NETStandard.Library.Ref\2.1.0\ref\netstandard2.1\System.Net.Http.dll
 warning MSB3277:           Project file item includes which caused reference "C:\Program Files\dotnet\packs\NETStandard.Library.Ref\2.1.0\ref\netstandard2.1\System.Net.Http.dll".
 warning MSB3277:             C:\Program Files\dotnet\packs\NETStandard.Library.Ref\2.1.0\ref\netstandard2.1\System.Net.Http.dll
 warning MSB3277:     References which depend on "System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" [].
 warning MSB3277:         Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\WotC.MtGO.Client.Model.Core.ref.dll
 warning MSB3277:           Project file item includes which caused reference "Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\WotC.MtGO.Client.Model.Core.ref.dll".
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\WotC.MtGO.Client.Model.Core.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\CardManager.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\CollectionAndDeckEditorScene.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\Core.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\AdminScene.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\Card.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\Chat.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\DraftScene.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\DuelScene.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\GameDetails.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\HelpScene.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\HomeScene.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\LoginScene.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\MTGO.ref.exe
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\PlayScene.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\SettingsScene.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\SharedResources.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\ShopResources.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\StoreScene.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\TradeScene.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\WotC.MtGO.Client.Model.Chat.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\WotC.MtGO.Client.Model.Play.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\WotC.MtGO.Client.Model.Session.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\WotC.MtGO.Client.Model.Settings.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\WotC.MtGO.Client.Model.Store.ref.dll
 warning MSB3277:             Z:\GitHub\mtgo-injector\dist\Release\Reference\MTGO\3.4.135.4386\WotC.MtGO.Client.Model.Trade.ref.dll

[third_party/RemoteNET] ScubaDiver: Fix Win32Error traced from disposing WindowsProcessDataReader

The WindowsProcessDataReader's dispose method attempts to kill the snapshot process without waiting for process exit. As a result, a Win32Exception is thrown (as we don't have the correct privileges to force an exit without yielding first) which will repeatedly spam any subscribed Trace listeners (as a Trace.Write is called internally).

This seems to be called when invoking either the DataTarget.Dispose() or ClrRuntime.Dispose() methods. You can observe this behavior in Loupe Desktop when injecting RemoteNET into the MTGO client, which will trace this error on Diver startup and when pinning objects, etc.

Unfortunately, we can't (and shouldn't) unsubscribe Trace listeners as this may negatively affect Gibraltar logging on the MTGO client, which makes extensive use of Trace.Write calls to inform state changes.

This is a regression from microsoft/clrmd#926 that we'll need to work around by reimplementing the dispose method w/ the use of reflection.

Tasks

[third_party/RemoteNET] Add postfix/finalizer positions to Harmony patcher

Tasks

Postfix/finalizer patches must have a return type of void or the return signature must match the type of the first parameter (passthrough mode) return types.

Refer to pardeike/Harmony#130 (comment) for a simpler overview of the HarmonyLib's patching methods.

[third_party/RemoteNET] Properly resolve dependency graph for incremental builds

A consequence of the .csproj level approach used in ee5bc14 is breaking incremental builds when RemoteNET project dependencies are updated.

Additionally, MSBuild does not respect building these dependencies before running pre-build targets, which deviates from the behavior expected within Visual Studio.

It may be best to change RemoteNET's pre-build target to 'pre-compile instead, though resolving the former issue seems unclear.

Publish SDK packages to NuGet

The current SDK is only set up for users to build against a clone of the project. This is mostly due to unresolved questions on how/whether to distribute reference assemblies generated by the MTGOSDK.Ref project, which are required runtime dependencies by the main MTGOSDK library (for reflection).

Only the MTGOSDK and MTGOSDK.Win32 libraries would need to be published to NuGet, requiring an additional pipeline for packaging the built reference assemblies.

This also requires additional infrastructure for supporting publishing and building the SDK through .NET Core.

Investigate memory fragmentation from ClrMD snapshots

ClrMd calls PssCaptureSnapshot to create a 'copy-on-write' clone of the MTGO client's process memory, creating a new snapshot process. This creates a clone of the process's virtual address space, sharing the same physical memory pages until any page is modified. Essentially, if the client process attempts to modify one of these pages, it instead modifies a new page with a clone of the original page contents.

It's worth noting that the process is frozen for the duration of the call to PssCaptureSnapshot, so no page-ins can occur until the snapshot has been created. However, changes made while the snapshot is still active will incur overhead from these new page-ins. After the snapshot is disposed of, no further page-ins will be made, as there exist no more references from the snapshot process (as it is now exclusively owned by the MTGO process).

Therefore, the optimization path for reducing the window that these snapshots take is twofold:

  1. Avoid performance penalties from new page-ins for the snapshot's lifecycle.
  2. Avoid maintaining stale copies of the object heap that may reference changed or non-existent memory locations.

Memory fragmentation in the MTGO process (irrespective of any behaviors caused by this snapshot) may trigger GC cycles that touch and cause page-ins even if there was no actual modification of data. At the same time, any unused pages of memory left over from copy-on-write modifications also need to be garbage collected, consuming additional CPU cycles.

This leaves a third optimization path to investigate with GC, which is further exacerbated by the memory handling of the MTGO process. This may require a custom GC mechanism to control/hide shared regions of memory created by the snapshot to reduce redundant copying.

Add build provenance with Sigstore

Use Sigstore to sign build artifacts generated in CI, providing provenance for release artifacts and runtime assets. This is essentially a tamper-proof way of verifying that an artifact was actually built in our CI to verify it's identity. This is now available in GitHub Actions through a public beta of artifact attestations.

This isn't compatible with the Windows trust store for Authenticode, so we'll have to look into purchasing an EV certificate or using an OV certificate from SignPath. We'll have to wait and see whether GitHub is planning on offering a signed timestamp for Authenticode compatibility. Until then, we'll need to submit samples to Microsoft in order to gain reputation for SmartScreen (reference).

Merge MTGOSDK.MSBuild and MTGOSDK.Ref projects

Within the MTGOSDK.Ref project, a new target should include the built reference assemblies for consumption through the library (without needing explicit references for each DLL):

<!-- Packaging assemblies for NuGet publishing -->
<ItemGroup>
  <Content Include="$(_MTGOSDK_Refs)\*.dll">
    <Pack>true</Pack>
    <PackagePath>lib\$(TargetFramework)</PackagePath>
  </Content>
</ItemGroup>
<!-- Importing MTGOSDK.Ref in a consuming project -->
<PackageReference Include="VidereProject.MTGOSDK.Ref"
                  Version="1.0.0" />

Versus the current setup, which requires bootstrapping the MTGOSDK.Ref project with MTGOSDK.MSBuild (internal project):

<!--
  Bootstrap the MTGOSDK.Ref project to generate reference assemblies for
  the current MTGO version. Due to the way that MSBuild works, this must
  import the MTGOSDK.MSBuild.props file before referencing the project.
-->
<Import Project="..\MTGOSDK.MSBuild\build\MTGOSDK.MSBuild.props" />
<PropertyGroup>
  <MTGOSDK_Refs>$(_MTGOSDK_Refs)\3.4.*.*</MTGOSDK_Refs>
</PropertyGroup>
<ItemGroup>
  <ProjectReference Include="..\MTGOSDK.Ref\MTGOSDK.Ref.csproj"
                    ReferenceOutputAssembly="false" />
  <!--
    Include reference assemblies to compile against the current MTGO version.
    Note that the '_MTGOSDK_Refs' path does not reference the updated version
    subpath as it is only evaluated after building the MTGOSDK.Ref project.
  -->
  <Reference Include="$(MTGOSDK_Refs)\Core.dll" />
  <Reference Include="$(MTGOSDK_Refs)\FlsClient.dll" />
  <Reference Include="$(MTGOSDK_Refs)\MTGOEnumStruct.dll" />
  <Reference Include="$(MTGOSDK_Refs)\WotC.MtGO.Client.Common.dll" />
  <Reference Include="$(MTGOSDK_Refs)\WotC.MtGO.Client.Model.Chat.dll" />
  <Reference Include="$(MTGOSDK_Refs)\WotC.MtGO.Client.Model.Core.dll" />
  <Reference Include="$(MTGOSDK_Refs)\WotC.MtGO.Client.Model.Reference.dll" />
</ItemGroup>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.