Skip to content

Instantly share code, notes, and snippets.

@MadeBaruna
Last active April 24, 2024 12:35
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 12 You must be signed in to fork a gist
  • Save MadeBaruna/9ff8b7a2af11f3002395af7963b5ed18 to your computer and use it in GitHub Desktop.
Save MadeBaruna/9ff8b7a2af11f3002395af7963b5ed18 to your computer and use it in GitHub Desktop.
Paimon.moe Local Importer (Windows)
Add-Type -AssemblyName System.Web
Write-Host "Paimon.moe Wish Importer" -ForegroundColor Cyan
Write-Host "1. Open Genshin Impact in this PC"
Write-Host "2. Then open the wish history and wait it to load"
Write-Host "3. When you are ready press [ENTER] to continue! (or any key to cancel)"
Write-Host "Waiting..."
$keyInput = [Console]::ReadKey($true).Key
if ($keyInput -ne "13") {
Write-Host "Bye~"
exit
}
$logLocation = "%userprofile%\AppData\LocalLow\miHoYo\Genshin Impact\output_log.txt";
$path = [System.Environment]::ExpandEnvironmentVariables($logLocation);
if (-Not [System.IO.File]::Exists($path)) {
Write-Host "Cannot find the log file! Make sure to open the wish history first!" -ForegroundColor Red
exit
}
$logs = Get-Content -Path $path
$match = $logs -match "^OnGetWebViewPageFinish.*log$"
if (-Not $match) {
Write-Host "Cannot find the wish history url! Make sure to open the wish history first!" -ForegroundColor Red
exit
}
[string] $wishHistoryUrl = $match -replace 'OnGetWebViewPageFinish:', ''
$uri = [System.UriBuilder]::New($wishHistoryUrl)
$uri.Path = "event/gacha_info/api/getGachaLog"
$uri.Host = "hk4e-api-os.mihoyo.com"
$uri.Fragment = ""
$banners = [ordered]@{
100 = "Beginners' Wish";
200 = "Standard";
301 = "Character Event";
302 = "Weapon Event";
}
$wishes = [System.Collections.ArrayList]@()
function fetch($url) {
$ProgressPreference = 'SilentlyContinue'
$retrycount = 0
$completed = $false
$response = $null
while (-Not $completed) {
try {
$response = Invoke-WebRequest -Uri $url -ContentType "application/json" -UseBasicParsing -TimeoutSec 30
$completed = $true
}
catch {
if ($retrycount -ge 3) {
throw
}
else {
$retrycount++
}
}
}
return $response
}
function GetBannerLog($code, $type) {
$total = 0
$params = [System.Web.HttpUtility]::ParseQueryString($uri.Query)
$params.Set("lang", "en");
$params.Set("gacha_type", $code);
$params.Set("size", "20");
$params.Add("lang", "en-us");
$page = 1
$lastList = [System.Collections.ArrayList]@()
$lastId = 0
do {
$params.Set("page", $page)
$params.Set("end_id", $lastId);
$uri.Query = $params.ToString()
$apiUrl = $uri.Uri.AbsoluteUri
Write-Host "`rProcessing $type Banner - Page $page - x$total" -NoNewline
try {
$response = fetch $apiUrl
$result = $response | ConvertFrom-Json
if ($result.retcode -ne 0) {
if ($result.message -eq "authkey timeout") {
Write-Host "Authkey expired, please re-open the Wish History page" -ForegroundColor Red
exit
}
Write-Host "Error code returned from MiHoYo API! Try again later" -ForegroundColor Red
exit
}
$lastList = $result.data.list
foreach ($wish in $result.data.list) {
[void]$wishes.Add(@($wish.gacha_type, $wish.time, $wish.name, $wish.item_type, $wish.rank_type))
}
$total = $total + $result.data.list.Count;
$page++;
if ($result.data.list.Count -gt 0) {
$lastId = $result.data.list[$result.data.list.Count - 1].id
}
else {
$lastId = 0
}
}
catch {
Write-Host "Error when connecting to MiHoYo API! (Check your internet connection)" -ForegroundColor Red
exit
}
Write-Host "`rProcessing $type Banner - Page $page - x$total" -NoNewline
Start-Sleep -Seconds 1
} while ($lastList.Count -ne 0)
}
foreach ($banner in $banners.GetEnumerator()) {
Write-Host ""
GetBannerLog $banner.Name $banner.Value
}
$generated = "paimonmoe,importer,version,1,0`n"
foreach ($w in $wishes) {
$str = $w -join ","
$generated += "$str`n"
}
Write-Host ""
Write-Host "Press any key to copy the result, then paste it back to paimon.moe" -ForegroundColor Green
[void][Console]::ReadKey($true)
Set-Clipboard -Value $generated
$documentpath = [Environment]::GetFolderPath("MyDocuments")
$time = Get-Date -Format "yyyyMMddHHmm"
$generated | Out-File -FilePath "$documentpath\paimon-moe-import-$time.csv"
Write-Host "The file also saved on $documentpath\paimon-moe-import-$time.csv" -ForegroundColor Green
@hpacleb
Copy link

hpacleb commented Jun 30, 2021

change
$uri.Host = "hk4e-api.mihoyo.com"
to
$uri.Host = "hk4e-api-os.mihoyo.com"

@ginwantsplay
Copy link

Hello, I am playing on chinese official server ("天空岛"), and on paimon.moe I found that auto import from PC failed (API error).
Then I tried to use this script to export the data to my local PC, I found that the problem is the path and the URL of chinese version differ from the international version.
So I did following adjustment:
Line 15-20:

$Is_CN = $false
$logLocation = "%userprofile%\AppData\LocalLow\miHoYo\Genshin Impact\output_log.txt";
$logLocation_CN = "%userprofile%\AppData\LocalLow\miHoYo\原神\output_log.txt";
$path = [System.Environment]::ExpandEnvironmentVariables($logLocation);
$path_CN = [System.Environment]::ExpandEnvironmentVariables($logLocation_CN);
if (-Not [System.IO.File]::Exists($path)) {
    if (-Not [System.IO.File]::Exists($path_CN)){
        Write-Host "Cannot find the log file! Make sure to open the wish history first!" -ForegroundColor Red
        exit
    }
    $Is_CN = $true
    $path = $path_CN
}

And line 32

if (-Not $Is_CN){
    $uri.Host = "hk4e-api-os.mihoyo.com"
}else {
    $uri.Host = "hk4e-api.mihoyo.com"
}

And then it works fine to export the data from the chinese server "天空岛“.
I am not that familiar with PowerShell, so please forgive me if the code looks not pretty.

@beerpiss
Copy link

beerpiss commented Nov 24, 2021

It looks like that the PC Local importer isn't updated to support the new Character Event-2 banner, which has a $wish.gacha_type of 400. This is not recognized by paimon.moe and it will throw the error Invalid data, please use the latest importer app.

A workaround for this is to check for the $wish.gacha_type of 400 and change it to 301, since the character event banners share pity and even the same wish history page:

Before

foreach ($wish in $result.data.list) {
    [void]$wishes.Add(@($wish.gacha_type, $wish.time, $wish.name, $wish.item_type, $wish.rank_type))
}

After

foreach ($wish in $result.data.list) {
    if ($wish.gacha_type -eq 400) {
        [void]$wishes.Add(@(301, $wish.time, $wish.name, $wish.item_type, $wish.rank_type))
    }
    else {
        [void]$wishes.Add(@($wish.gacha_type, $wish.time, $wish.name, $wish.item_type, $wish.rank_type))
    }
}

@FrenkYang0918
Copy link

Hello, I am playing on chinese official server ("天空岛"), and on paimon.moe I found that auto import from PC failed (API error). Then I tried to use this script to export the data to my local PC, I found that the problem is the path and the URL of chinese version differ from the international version. So I did following adjustment: Line 15-20:

$Is_CN = $false
$logLocation = "%userprofile%\AppData\LocalLow\miHoYo\Genshin Impact\output_log.txt";
$logLocation_CN = "%userprofile%\AppData\LocalLow\miHoYo\原神\output_log.txt";
$path = [System.Environment]::ExpandEnvironmentVariables($logLocation);
$path_CN = [System.Environment]::ExpandEnvironmentVariables($logLocation_CN);
if (-Not [System.IO.File]::Exists($path)) {
    if (-Not [System.IO.File]::Exists($path_CN)){
        Write-Host "Cannot find the log file! Make sure to open the wish history first!" -ForegroundColor Red
        exit
    }
    $Is_CN = $true
    $path = $path_CN
}

And line 32

if (-Not $Is_CN){
    $uri.Host = "hk4e-api-os.mihoyo.com"
}else {
    $uri.Host = "hk4e-api.mihoyo.com"
}

And then it works fine to export the data from the chinese server "天空岛“. I am not that familiar with PowerShell, so please forgive me if the code looks not pretty.

To work in right way, the modified file MUST be saved as "UTF-8 with BOM" or "UTF-16 (UNICODE)"

@mizsterlong
Copy link

@SnowyField1906
Copy link

@gatcha4build
Copy link

Hello,
I was playing with the API and I got an error:
{ "RetCode" : -109, "Message" : "app id error", "Data" : null }
I tried different account genshin impact account to get different url but still the same error

@bwelpeep
Copy link

@kjperkin
Copy link

kjperkin commented Apr 24, 2022

On line 23, I think you need to pipe the match through select -Last 1. Today the script was not working as expected and I figured out that there were multiple matching lines in the log.

$match = $logs -match "^OnGetWebViewPageFinish.*log$" | select -Last 1

You can use $env:<varname> to get environment variables. Incorporating @ginwantsplay's suggestion, you can replace lines 15 through 22 with:

$logLocation = "$env:USERPROFILE\AppData\LocalLow\miHoYo\Genshin Impact\output_log.txt"
$apiHost = "hk4e-api-os.mihoyo.com"
if (-Not [System.IO.File]::Exists($logLocation)) {
    # Using [char](0xnnnn) avoids concerns about the script's encoding
    $logLocation = "$env:USERPROFILE\AppData\LocalLow\miHoYo\$([char]0x539f)$([char]0x795e)\output_log.txt"
    $apiHost = "hk4e-api.mihoyo.com"
    if (-Not [System.IO.File]::Exists($logLocation)) {     
        Write-Host "Cannot find the log file! Make sure to open the wish history first!" -ForegroundColor Red
        exit
    }
}

$logs = Get-Content -Path $logLocation

and then on line 36:

$uri.Host = $apiHost

Credit to @Nats-ji for the cast-to-character trick from their fork here.

@jogerj
Copy link

jogerj commented Dec 30, 2022

@peteranh
Copy link

peteranh commented Apr 24, 2024

Version 4.6 fix:
$uri.Path = "event/gacha_info/api/getGachaLog" is now $uri.Path = "gacha_info/api/getGachaLog"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment