Featured image of post Honkai Star Derailer

Honkai Star Derailer

Silly group of projects

I made this silly project after one of my friends decided to create their own game launcher for a variety of Mihoyo games. This was a very basic idea; all I had to do was write a program in whatever language I could think of, regardless of whether I had ever used that language before, to close Honkai Star Rail.

Following examples of different languages I used in this project:

C++

10/10 C++ this one was more fun to figure out and work with (I use C++ often anyway).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <windows.h>
#include <tlhelp32.h>
#include <set>

std::set<int> FindProcesses(const wchar_t* ProcessName)
{
    std::set<int> PID;
    HANDLE Snapshot;
    PROCESSENTRY32 PE;
    bool Result;

    Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if (INVALID_HANDLE_VALUE == Snapshot)
        return PID;

    PE.dwSize = sizeof(PROCESSENTRY32);
    Result = Process32First(Snapshot, &PE);

    while (Result)
    {
        if (wcscmp(ProcessName, PE.szExeFile) == 0)
        {
            PID.emplace(PE.th32ProcessID);
        }
        Result = Process32Next(Snapshot, &PE);
    }

    return PID;
}

int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    auto WindowTitle = (LPCWSTR)L"Star Derailer";

    MessageBox(NULL, (LPCWSTR)L"Press Ok to derail stars", WindowTitle, 0);

    auto GamePIDS = FindProcesses(L"StarRail.exe");
    if (GamePIDS.size() != 0)
    {
        for (int GamePID : GamePIDS)
        {
            auto Process = OpenProcess(PROCESS_TERMINATE, false, GamePID);
            if (Process)
            {
                TerminateProcess(Process, 0);
                CloseHandle(Process);
            }
        }
        MessageBox(NULL, (LPCWSTR)L"Derailed all the stars.", WindowTitle, 0);
    }
    else
    {
        MessageBox(NULL, (LPCWSTR)L"No stars to derail...", WindowTitle, 0);
    }
}

C#

7/10 I liked this it was fairly simple to figure out.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System.Diagnostics;

internal class HSRer
{
    private static void Main(string[] args)
    {
        Console.Title = "HSRer";

        Console.WriteLine("Press anything to derail stars...");
        Console.ReadKey(true);

        var ProcessesByName = Process.GetProcessesByName("StarRail");
        if (ProcessesByName.Length != 0)
        {
            foreach (var Process in ProcessesByName)
                if (Process != null)
                    Process.Kill();

            Console.WriteLine("Derailed all the stars.");
        }
        else
            Console.WriteLine("No stars to derail...");

        Console.ReadKey(true);
    }
}

F#

0/10 did not like.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
printfn "Press anything to derail stars..."
let Key = System.Console.ReadKey(false)

let ProcessesByName = System.Diagnostics.Process.GetProcessesByName("StarRail");

if (ProcessesByName.Length > 0) then
    for gameprocess in ProcessesByName do
        gameprocess.Kill()

    printfn "Derailed all the stars."

else
    printfn "No stars to derail..."

System.Console.ReadKey(false)

Visual Basic

This felt really weird to use but it wasn’t too bad (I had to use visual basic to write a powerpoint plugin), Now I look back Verse (the Fortnite langauge) really reminds me of visual basic in a few areas.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
Module HSRer
    Sub Main(args As String())

        Console.WriteLine("Press anything to derail stars...")
        Console.ReadKey(False)

        Dim Processes = Process.GetProcessesByName("StarRail")

        If Processes.Length > 0 Then
            For Each GameProcess In Processes
                GameProcess.Kill()
            Next

            Console.WriteLine("Derailed all the stars.")
        Else
            Console.WriteLine("No stars to derail...")
        End If

        Console.ReadKey(False)

    End Sub
End Module

Unreal Engine / C++

The Unreal Engine one I got to have some more fun with as I was able to add silly menus with A somewhat nice design.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include "StarFunctionLibrary.h"

#include <windows.h>
#include <TlHelp32.h>

TArray<FProcessInfo> UStarFunctionLibrary::GetProcesses(FString ProcessName, int ProcessID)
{
    TArray<FProcessInfo> PID;
    HANDLE Snapshot = HANDLE();
    PROCESSENTRY32 PE = PROCESSENTRY32();
    bool Result = false;

    Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if (INVALID_HANDLE_VALUE == Snapshot)
        return PID;

    PE.dwSize = sizeof(PROCESSENTRY32);
    Result = Process32First(Snapshot, &PE);

    while (Result)
    {
        if (ProcessID == -1 && wcscmp(*ProcessName, PE.szExeFile) == 0)
        {
            FProcessInfo ProcessInfo = FProcessInfo(PE.szExeFile, PE.th32ProcessID,
                PE.dwSize, PE.cntUsage, PE.th32DefaultHeapID, PE.th32ModuleID, PE.cntThreads,
                PE.th32ParentProcessID, PE.pcPriClassBase, PE.dwFlags);

            PID.Add(ProcessInfo);
        }
        else if (PE.th32ProcessID == ProcessID)
        {
            FProcessInfo ProcessInfo = FProcessInfo(PE.szExeFile, PE.th32ProcessID,
                PE.dwSize, PE.cntUsage, PE.th32DefaultHeapID, PE.th32ModuleID, PE.cntThreads,
                PE.th32ParentProcessID, PE.pcPriClassBase, PE.dwFlags);

            PID.Add(ProcessInfo);
        }
        Result = Process32Next(Snapshot, &PE);
    }

    return PID;
}

FProcessInfo UStarFunctionLibrary::GetProcessInfo(int ProcessID)
{
    return GetProcesses(L"", ProcessID)[0]; // realistically when will it return more than one process from a single id, windows 12?!?!
}

bool UStarFunctionLibrary::KillProcessByInfo(FProcessInfo ProcessInfo, FString& OutErrorCode)
{
    OutErrorCode = TEXT("Success");
    bool ReturningSuccess = false;

    if (!ProcessInfo.ProcessName.IsEmpty())
    {
        if (ProcessInfo.ProcessID > 0)
        {
            auto Process = OpenProcess(PROCESS_TERMINATE, false, ProcessInfo.ProcessID);
            if (Process)
            {
                ReturningSuccess = TerminateProcess(Process, 0);
                CloseHandle(Process);
            }
            else
                OutErrorCode = TEXT("Failed to OpenProcess for termination");
        }
        else
            OutErrorCode = TEXT("ProcessInfo has an invalid PID");
    }
    else
        OutErrorCode = TEXT("ProcessInfo has an invalid name");

    return ReturningSuccess;
}

bool UStarFunctionLibrary::EqualEqual_ProcessInfo(FProcessInfo A, FProcessInfo B)
{
    return A.ProcessID == B.ProcessID;
}

I got to make the background a tiling photo of the Honkai Star Rail app icon.

I still do want to make this silly kind of app in other languages I enocunter such as Rust, Javascript or Typescript and lastly x86 ASM (assembly). The last idea I did try and complete but working with assembly is really overwhelming.

Hi
Built with Hugo
Theme Stack designed by Jimmy