Skip to content

Commit

Permalink
Merge pull request #20 from Digitalroot-Valheim/18-bug-sid_develop-co…
Browse files Browse the repository at this point in the history
…okie-is-gone-from-redesigned-nexus-page

Updated to use nexusmods_session, set via env var COOKIE_NEXUSMOD_SES…
  • Loading branch information
Digitalroot committed May 22, 2024
2 parents b01b801 + b8fb8ed commit d593a33
Show file tree
Hide file tree
Showing 20 changed files with 295 additions and 263 deletions.
24 changes: 10 additions & 14 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

## Introduction

This is a command-line tool that can be used to upload mod files to an existing mod on Thunderstore, ModVault and Nexus Mods.

**Note:** _Thunderstore support will be in a future release._
This is a command-line tool that can be used to upload mod files to an existing mod on Nexus Mods.

## Installation

Expand All @@ -25,7 +23,7 @@ Please use environment variables for the sensitive information.
### Environment Variables
- __NEXUSMOD_API_KEY__
- __NEXUSMOD_COOKIE_SID_DEVELOP__
- __COOKIE_NEXUSMOD_SESSION__

All Commands support the `-?, -h, --help` options to show help and usage information

Expand All @@ -34,7 +32,7 @@ All Commands support the `-?, -h, --help` options to show help and usage informa
###### Digitalroot.ModUploader.exe -h
```bat
Description:
Uploads mods to Thunderstore, ModVault, or NexusMods
Uploads mods to NexusMods
Usage:
Digitalroot.ModUploader.exe [command] [options]
Expand All @@ -44,9 +42,7 @@ Options:
-?, -h, --help Show help and usage information
Commands:
modvault, mv modvault.xyz commands.
nexusmods, nx nexusmods.com commands.
thunderstore, ts thunderstore.io commands.
```
---

Expand Down Expand Up @@ -76,9 +72,9 @@ Usage:
Digitalroot.ModUploader.exe nexusmods check [options]
Options:
-k, --key <key> Api Key, ENV: NEXUSMOD_API_KEY
-csid, --cookie_sid_develop <cookie value> Session Cookie, ENV: NEXUSMOD_COOKIE_SID_DEVELOP
-?, -h, --help Show help and usage information
-k, --key <key> Api Key, ENV: NEXUSMOD_API_KEY
-cnms, --cookie_nexusmods_session Session Cookie, ENV: COOKIE_NEXUSMOD_SESSION <cookie_nexusmods_session>
-?, -h, --help Show help and usage information
```
---

Expand All @@ -101,18 +97,19 @@ Options:
-d, --description <description> description
-g, --game <game> Game mod is for. [default: valheim]
-dmfu, --disable-main-file-update Skips replacing an existing file in the 'Main' category with the new one. [default: False]
-dfa, --disable-file-archive Skips archiving older versions of the existing file. [default: False]
-ddwm, --disable-download-with-manager Removes the 'Download With Manager' button. [default: False]
-dvu, --disable-version-update Skips updating mod's main version to match this file's version. [default: False]
-dmv, --disable-main-vortex Skips setting file as the main Vortex file. [default: False]
-drpu, --disable-requirements-pop-up Skips informing downloaders of this mod's requirements before they attempt to download this file [default: False]
-k, --key <key> Api Key, ENV: NEXUSMOD_API_KEY
-csid, --cookie_sid_develop <cookie value> Session Cookie, ENV: NEXUSMOD_COOKIE_SID_DEVELOP
-cnms, --cookie_nexusmods_session <cookie_nexusmods_session> Session Cookie, ENV: COOKIE_NEXUSMOD_SESSION
-?, -h, --help Show help and usage information
```

#### Examples
```bash
nexusmods check -k "MyVeryLongNexusApiKey" -csid "%7B%22mechanism--MyVeryLongNexusSessionCookieSessIdValue--%22%7D"
nexusmods check -k "MyVeryLongNexusApiKey" -cnms "6c1ae4818867700000XX804f1f55ae72"
```
---
```bash
Expand All @@ -136,8 +133,7 @@ nexusmods upload 1303 "Digitalroot.Valheim.JVL.BT.Fix.v1.0.6.zip" -v "1.0.6" -f
##### Q4: Where do I get my Nexus Mods' Session Cookies?
> From your browser. This [site](https://www.cookieyes.com/how-to-check-cookies-on-your-website-manually/) covers how to do it in most browers.
> The cookie you are looking for is called `sid_develop`. It starts with `%7B%22mechanism`. This is the html encoded value for `{"mechanism`.
> If your browser displays a cookie value starting with `{"mechanism` then you will need to html encode the value before using this tool.
> The cookie you are looking for is called `nexusmods_session`. It is a hex value that looks like `6c1ae4818867700000XX804f1f55ae72`.

<br />
Expand Down
2 changes: 2 additions & 0 deletions src/Digitalroot.ModUploader.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=mins/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=NEXUSMOD/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=nexusmods/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Pickysaurus/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Thunderstore/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=alia/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Resumable/@EntryIndexedValue">True</s:Boolean>
Expand Down
42 changes: 18 additions & 24 deletions src/Digitalroot.ModUploader/Clients/AbstractRestClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,20 @@ public class AbstractRestClient
private protected AbstractRestClient(AbstractHostProviderConfiguration modsHostProviderConfiguration)
{
_configuration = modsHostProviderConfiguration;
ModHostProviderClient = new RestClient(_configuration.ServiceUri);
SetNewtonsoftJsonSerializerAsHandler(ModHostProviderClient);
var options = new RestClientOptions(_configuration.ServiceUri);
var jsonSerializerSettings = new JsonSerializerSettings
{
MissingMemberHandling = MissingMemberHandling.Ignore
, NullValueHandling = NullValueHandling.Ignore
};

ModHostProviderClient = new RestClient(options, configureSerialization: s => s.UseNewtonsoftJson(jsonSerializerSettings));
}

#region Helper Methods

internal string GetDefaultConfigValue(string value) => _configuration.GetDefaultConfigValue(value);

/// <summary>
/// Configures the client to use NewtonsoftJsonSerializer so that
/// The JsonProperty Attribute can be used.
/// e.g. [JsonProperty(PropertyName = "country")]
/// </summary>
/// <param name="restClient"></param>
private protected static void SetNewtonsoftJsonSerializerAsHandler(RestClient restClient)
{
restClient.UseNewtonsoftJson(new JsonSerializerSettings
{
MissingMemberHandling = MissingMemberHandling.Ignore
, NullValueHandling = NullValueHandling.Ignore
});
}

internal static ErrorResponseModel GetErrorMessage(RestResponse response)
{
return new ErrorResponseModel(response);
Expand All @@ -75,7 +66,7 @@ private static void TraceResponse(RestResponse response)
{
Trace.WriteLine($"** Response ** - IsSuccessful: {response.IsSuccessful}, StatusCode: {response.StatusCode}");
Trace.WriteLine("[Headers:]");
Trace.WriteLine(NewtonsoftJsonSerializer.Default.Serialize(response.Headers));
Trace.WriteLine(NewtonsoftJsonSerializer.Default.Serialize(response.Headers ?? throw new InvalidOperationException()));
Trace.WriteLine(string.Empty);

switch (response.ContentType)
Expand All @@ -91,7 +82,7 @@ private static void TraceResponse(RestResponse response)

default:
Trace.WriteLine("[Content]:");
Trace.WriteLine(NewtonsoftJsonSerializer.Default.Serialize(response.Content));
Trace.WriteLine(NewtonsoftJsonSerializer.Default.Serialize(response.Content ?? throw new InvalidOperationException()));
break;
}

Expand Down Expand Up @@ -127,14 +118,14 @@ private static void TraceResponse<TRestResponseModel>(RestResponse response, TRe

#region Obsolete

[Obsolete("Use Async Version")]
[Obsolete("Use Async Version", true)]
protected static TRestResponse Get<TRestResponse>(RestClient restClient, RestRequest request)
{
var response = restClient.Get(request);
return (TRestResponse)Activator.CreateInstance(typeof(TRestResponse), response);
}

[Obsolete("Use Async Version")]
[Obsolete("Use Async Version", true)]
protected static TRestResponse Get<TRestResponse, TRestResponseModel>(RestClient restClient, RestRequest request)
where TRestResponse : AbstractResponse
{
Expand Down Expand Up @@ -162,7 +153,8 @@ protected static async Task<TRestResponse> GetAsync<TRestResponse>(RestClient re

if (request is AbstractAuthorizedRequest { Model: CookieRequestModel model })
{
restClient.AddCookie("sid_develop", model.CookieSidDevelop, "/", ".nexusmods.com");
request.AddCookie("nexusmods_session", model.NexusmodsSession, "/", ".nexusmods.com");
// request.AddCookie("nexusmods_session_refresh", model.NexusmodsSessionRefresh, "/", ".nexusmods.com");
}

var response = await restClient.ExecuteGetAsync(request);
Expand All @@ -177,7 +169,8 @@ protected static async Task<TRestResponse> GetAsync<TRestResponse, TRestResponse

if (request is AbstractAuthorizedRequest { Model: CookieRequestModel model })
{
restClient.AddCookie("sid_develop", model.CookieSidDevelop, "/", ".nexusmods.com");
request.AddCookie("nexusmods_session", model.NexusmodsSession, "/", ".nexusmods.com");
// request.AddCookie("nexusmods_session_refresh", model.NexusmodsSessionRefresh, "/", ".nexusmods.com");
}

var response = await restClient.ExecuteGetAsync<TRestResponseModel>(request);
Expand All @@ -197,7 +190,8 @@ protected static async Task<TRestResponse> PostAsync<TRestResponse, TRestRespons

if (request is AbstractAuthorizedRequest { Model: CookieRequestModel model })
{
restClient.AddCookie("sid_develop", model.CookieSidDevelop, "/", ".nexusmods.com");
request.AddCookie("nexusmods_session", model.NexusmodsSession, "/", ".nexusmods.com");
// request.AddCookie("nexusmods_session_refresh", model.NexusmodsSessionRefresh, "/", ".nexusmods.com");
}

var response = await restClient.ExecutePostAsync<TRestResponseModel>(request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ internal class EnvironmentConfigurationProvider : IConfigs
/// <inheritdoc />
string IConfigs.GetConfig(string keyName)
{
return Environment.GetEnvironmentVariable(keyName);
var value = Environment.GetEnvironmentVariable(keyName);
return value;
}

#endregion
Expand Down
12 changes: 6 additions & 6 deletions src/Digitalroot.ModUploader/Digitalroot.ModUploader.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
<ToolCommandName>drmu</ToolCommandName>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Copyright>Copyright © Digitalroot Technologies 2021 - 2023</Copyright>
<Copyright>Copyright © Digitalroot Technologies 2021 - 2024</Copyright>
<PackageProjectUrl>https://github.com/Digitalroot-Valheim/Digitalroot.ModUploader</PackageProjectUrl>
<RepositoryUrl>https://github.com/Digitalroot-Valheim/Digitalroot.ModUploader</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageIcon>ValheimRcon_color.png</PackageIcon>
<PackageIconUrl />
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageTags>valheim, digitalroot, mods, cli, tool, nexusmods, thunderstore</PackageTags>
<PackageTags>valheim, digitalroot, mods, cli, tool, nexusmods</PackageTags>
<Authors>Digitalroot</Authors>
<Company>Digitalroot Technologies</Company>
<Product>Digitalroot Mod Uploader</Product>
Expand All @@ -29,7 +29,7 @@
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
<GenerateDocumentationFile>False</GenerateDocumentationFile>
<ProduceReferenceAssembly>False</ProduceReferenceAssembly>
<VersionPrefix>1.3.1</VersionPrefix>
<VersionPrefix>1.4.0</VersionPrefix>
<RestoreAdditionalProjectSources>
https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-libraries/nuget/v3/index.json;
https://digitalroot-valheim-nuget.s3.us-west-2.amazonaws.com/index.json
Expand All @@ -52,9 +52,9 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Pastel" Version="4.0.2" />
<PackageReference Include="RestSharp" Version="108.0.3" />
<PackageReference Include="RestSharp.Serializers.NewtonsoftJson" Version="108.0.3" />
<PackageReference Include="Pastel" Version="5.1.0" />
<PackageReference Include="RestSharp" Version="110.2.0" />
<PackageReference Include="RestSharp.Serializers.NewtonsoftJson" Version="110.2.0" />
<PackageReference Include="System.CommandLine" Version="[2.0.0-beta1.21568.1]" />
</ItemGroup>

Expand Down
17 changes: 10 additions & 7 deletions src/Digitalroot.ModUploader/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@ public static async Task<int> Main(string[] args)
Credits.PrintWelcome();

// Create a root command with some options
var rootCommand = new RootCommand("Uploads mods to Thunderstore, ModVault, or NexusMods")
var rootCommand = new RootCommand("Uploads mods to NexusMods")
{
Provider.ModVault.Commands.GetRootCommand() ?? throw new InvalidOperationException()
, Provider.NexusMods.Commands.CommandFactory.GetCommand(Provider.NexusMods.Enums.CommandName.Root) as Command ?? throw new InvalidOperationException()
, Provider.Thunderstore.Commands.GetRootCommand() ?? throw new InvalidOperationException()
// Provider.ModVault.Commands.GetRootCommand() ?? throw new InvalidOperationException()
Provider.NexusMods.Commands.CommandFactory.GetCommand(Provider.NexusMods.Enums.CommandName.Root) as Command ?? throw new InvalidOperationException()
// , Provider.Thunderstore.Commands.GetRootCommand() ?? throw new InvalidOperationException()
};

var cmdBuilder = new CommandLineBuilder(rootCommand);
cmdBuilder.AddMiddleware(async (context, next) =>
{
// Trace Output of Command passed. Warning this outputs -k and -c values.
Trace.WriteLineIf(context?.ParseResult != null, context.ParseResult);
Trace.WriteLine(context.ParseResult);
await next(context);
});

Expand All @@ -56,6 +56,10 @@ public static async Task<int> Main(string[] args)
Credits.PrintCredits();
}

#if DEBUG
Console.ReadKey();
#endif

return results;
}

Expand All @@ -78,10 +82,9 @@ private static IHelpBuilder GetHelpBuilder(int maxWidth)
}

// ReSharper disable once UnusedMember.Local
[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "Not implemented yet")]
private static MaskingHelpBuilder GetMaskingHelpBuilder(int maxWidth) => new(LocalizationResources.Instance, maxWidth);

[System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "Not implemented yet")]
// ReSharper disable once UnusedMember.Local
private static HelpBuilder GetUnMaskingHelpBuilder(int maxWidth) => new(LocalizationResources.Instance, maxWidth);

private static void AddHelpSubCommandsRecursively(Command command)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
using Digitalroot.ModUploader.Provider.NexusMods.Configuration;
using Digitalroot.ModUploader.Provider.NexusMods.Models;
using Digitalroot.ModUploader.Provider.NexusMods.Protocol;
using Newtonsoft.Json;
using RestSharp;
using RestSharp.Serializers.NewtonsoftJson;
using System.Threading.Tasks;

namespace Digitalroot.ModUploader.Provider.NexusMods.Clients
Expand All @@ -28,11 +30,18 @@ internal class NexusModsRestClient : AbstractRestClient
public NexusModsRestClient(NexusModsHostProviderConfiguration modsHostProviderConfiguration)
: base(modsHostProviderConfiguration)
{
_modHostApiProviderClient = new RestClient(modsHostProviderConfiguration.ServiceApiUri);
SetNewtonsoftJsonSerializerAsHandler(_modHostApiProviderClient);
var apiOptions = new RestClientOptions(modsHostProviderConfiguration.ServiceApiUri);
var jsonSerializerSettings = new JsonSerializerSettings
{
MissingMemberHandling = MissingMemberHandling.Ignore
, NullValueHandling = NullValueHandling.Ignore
};

_modHostUploadProviderClient = new RestClient(modsHostProviderConfiguration.ServiceUploadUri);
SetNewtonsoftJsonSerializerAsHandler(_modHostUploadProviderClient);
_modHostApiProviderClient = new RestClient(apiOptions, configureSerialization: s => s.UseNewtonsoftJson(jsonSerializerSettings));

var uploadOptions = new RestClientOptions(modsHostProviderConfiguration.ServiceUploadUri);

_modHostUploadProviderClient = new RestClient(uploadOptions, configureSerialization: s => s.UseNewtonsoftJson(jsonSerializerSettings));
}

public static ErrorResponseModel GetErrorMessage(AbstractResponse response)
Expand Down
Loading

0 comments on commit d593a33

Please sign in to comment.