Compare commits

...

10 Commits

8 changed files with 338 additions and 0 deletions

6
launcher/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
client_id
ms_auth_blob
xbl_auth_blob
xsts_auth_blob
auth.json
version_manifest.json

68
launcher/auth.sh Executable file
View File

@ -0,0 +1,68 @@
#!/bin/bash
# Authenticate with Mojang's authserver
_AUTH_BASE_URL="https://authserver.mojang.com"
function escape_json() {
sed 's/["\\]/\\&/g;s/\t/\\t/g' <<< "$1"
}
# login(username, password)
function login() {
local mail=$(escape_json "$1")
local password=$(escape_json "$2")
local json='
{
"agent": {
"name": "Minecraft",
"version": 1
},
"username": "'"$mail"'",
"password": "'"$password"'",
"requestUser": true
}'
curl -s \
-H "Content-Type: application/json" \
--data-raw "$json" \
$_AUTH_BASE_URL/authenticate > auth.json
}
function refresh() {
local accessToken=$(jq -r '.accessToken' < auth.json)
local clientToken=$(jq -r '.clientToken' < auth.json)
local json='
{
"accessToken": "'"$accessToken"'",
"clientToken": "'"$clientToken"'",
"requestUser": true
}'
curl -s \
-H "Content-Type: application/json" \
--data-raw "$json" \
$_AUTH_BASE_URL/refresh > auth.json
}
function validate() {
local accessToken=$(jq -r '.accessToken' < auth.json)
local clientToken=$(jq -r '.clientToken' < auth.json)
local json='
{
"accessToken": "'"$accessToken"'",
"clientToken": "'"$clientToken"'",
"requestUser": true
}'
local meow=$(curl -i -s \
-H "Content-Type: application/json" \
--data-raw "$json" \
$_AUTH_BASE_URL/validate)
if [[ "$meow" == *"204"* ]]; then
return 0
else
return 1
fi
}

36
launcher/helper.sh Normal file
View File

@ -0,0 +1,36 @@
#!/bin/bash
# helper.sh - sources everything and tries to refresh the token
cd /meow
source auth.sh
source ms_auth.sh
source launch.sh
source version.sh
function _login() {
read -p "E-Mail: " login
read -s -p "Password: " pass
login "$login" "$pass"
cat auth.json
}
echo "Welcome to CurseMe (WIP)!"
if [[ -f auth.json ]]; then
refresh
else
echo -e 'This looks like your first launch. Start with logging in by executing `_login` or `ms_login` (i will rename those later)'
fi
PS1='CurseMe$ '
echo "Available (user-facing) commands:
list_versions - well...
fetch_version <version> - downloads a specific version
launch <version> - launches a previously downloaded version
_login - classic Mojang login
ms_login - microsoft login
Have fun!"

60
launcher/launch.sh Executable file
View File

@ -0,0 +1,60 @@
#!/bin/bash
function launch() {
if [[ "$1" == '' ]]; then
echo uh oh
exit 1
fi
cd "$1"
mkdir -p natives
if [[ "$2" == '' ]]; then # for testing
for i in $(find libraries/ | grep natives); do
cp "$i" natives/
done
for i in natives/*.jar; do
7z x -onatives/ $i -y
done
fi
if [[ $(uname -o) == "Msys" ]]; then # winblows
windows_fetch_java
../jdk-18*/bin/java \
-Xms128M \
-Xmx4G \
-Djava.library.path=natives/ \
-cp $(find libraries/ -type f | tr '\n' ';')client.jar \
$(jq -r '.mainClass' < manifest.json) \
--gameDir . \
--assetsDir assets \
--version $1 \
--accessToken "$(jq -r '.accessToken' < ../auth.json)" \
--username "$(jq -r '.selectedProfile.name' < ../auth.json)" \
--uuid "$(jq -r '.selectedProfile.id' < ../auth.json)"
else
java \
-Xms128M \
-Xmx4G \
-Djava.library.path=natives/ \
-cp $(find libraries/ -type f | tr '\n' ':')client.jar \
$(jq -r '.mainClass' < manifest.json) \
--gameDir . \
--assetsDir assets \
--version $1 \
--accessToken "$(jq -r '.accessToken' < ../auth.json)" \
--username "$(jq -r '.selectedProfile.name' < ../auth.json)" \
--uuid "$(jq -r '.selectedProfile.id' < ../auth.json)"
fi
}
function windows_fetch_java() {
pushd /meow
if [[ $(ls jdk-18*) == '' ]]; then
url="$(curl https://jdk.java.net/18/ | grep windows-x64 | grep -Poh 'https:.*?zip"' | sed 's/"//')"
curl -o java.zip "$url"
7z x java.zip
fi
popd
}

68
launcher/ms_auth.sh Executable file
View File

@ -0,0 +1,68 @@
#!/bin/bash
function get_client_id() {
# sorry polymc, I don't wanna agree to Azure/MS TOS
curl https://raw.githubusercontent.com/PolyMC/PolyMC/develop/CMakeLists.txt | grep Launcher_MSA_CLIENT_ID | awk '{print $2}' | sed 's/"//g' > client_id
}
function ms_login() {
res="$(curl "https://login.microsoftonline.com/consumers/oauth2/v2.0/devicecode?client_id=$(cat client_id)&scope=XboxLive.signin%20offline_access")"
jq '.message' <<< "$res"
echo "Press <return> after authenticating"
read
echo "Fetching token..."
curl -s \
https://login.microsoftonline.com/consumers/oauth2/v2.0/token \
--data 'grant_type=urn:ietf:params:oauth:grant-type:device_code&client_id='"$(cat client_id)"'&device_code='"$(jq -r '.device_code' <<< "$res")" > ms_auth_blob
json='{
"Properties": {
"AuthMethod": "RPS",
"SiteName": "user.auth.xboxlive.com",
"RpsTicket": "d='"$(jq -r '.access_token' < ms_auth_blob)"'"
},
"RelyingParty": "http://auth.xboxlive.com",
"TokenType": "JWT"
}'
echo "Talking with XBL..."
curl -s \
https://user.auth.xboxlive.com/user/authenticate \
-H "Content-Type: application/json" \
--data-raw "$json" > xbl_auth_blob
xbl_token=$(jq -r '.Token' < xbl_auth_blob)
xbl_xui=$(jq -r '.DisplayClaims.xui[0].uhs' < xbl_auth_blob)
echo "Talking with XSTS..."
json='
{
"Properties": {
"SandboxId": "RETAIL",
"UserTokens": [
"'"$xbl_token"'"
]
},
"RelyingParty": "rp://api.minecraftservices.com/",
"TokenType": "JWT"
}'
curl -s \
https://xsts.auth.xboxlive.com/xsts/authorize \
-H "Content-Type: application/json" \
--data-raw "$json" > xsts_auth_blob
xsts_token=$(jq -r '.Token' < xsts_auth_blob)
echo "Talking with minecraftservices..."
json='{"identityToken": "XBL3.0 x='"$xbl_xui"';'"$xsts_token"'"}'
curl -s \
https://api.minecraftservices.com/authentication/login_with_xbox \
-H "Content-Type: application/json" \
--data-raw "$json" > auth.json
}

58
launcher/version.sh Executable file
View File

@ -0,0 +1,58 @@
#!/bin/bash
function fetch_manifest() {
if [[ ! -f version_manifest.json ]]; then
curl https://launchermeta.mojang.com/mc/game/version_manifest.json -O
fi
}
function list_versions() {
fetch_manifest
jq -r '.versions[] | "\(.id)"' < version_manifest.json
}
function fetch_version() {
fetch_manifest
local url=$(jq -r '.versions[] | "\(.id),\(.url)"' < version_manifest.json | grep -P "^$1," | awk -F, '{print $2}')
if [[ "$url" == '' ]]; then
echo "Bad version?"
return 1
fi
mkdir -p $1; cd $1
curl -o manifest.json "$url"
curl -o client.jar "$(jq -r '.downloads.client.url' < manifest.json)"
curl -o assets.json "$(jq -r '.assetIndex.url' < manifest.json)"
if [[ "$(uname -o)" == "Msys" ]]; then # winblows
mew="$(jq -r '.libraries[].downloads | if .classifiers then select(.classifiers["natives-windows"]) | .classifiers["natives-windows"] else .artifact end | "\(.url) \(.path)"' < manifest.json)"
else
mew="$(jq -r '.libraries[].downloads | if .classifiers then select(.classifiers["natives-linux"]) | .classifiers["natives-linux"] else .artifact end | "\(.url) \(.path)"' < manifest.json)"
fi
IFS=$'\n'
mkdir -p libraries; cd libraries
for i in $mew; do
_url=$(awk '{print $1}' <<< "$i")
path=$(awk '{print $2}' <<< "$i")
mkdir -p $(dirname "$path")
curl -o "$path" "$_url"
done
cd ..
# assets
mkdir -p assets; cd assets
for i in $(jq -r '.objects | keys[] as $k | "\(.[$k].hash) \($k)"' < ../assets.json); do
hash=$(awk '{print $1}' <<< "$i")
hash_start=$(cut -c 1-2 <<< "$hash")
path=$(awk '{print $2}' <<< "$i")
mkdir -p $(dirname "$path")
curl -o $path "http://resources.download.minecraft.net/$hash_start/$hash"
done
cd ..
cd ..
unset IFS
}

View File

@ -0,0 +1,8 @@
#!/bin/bash
rm -R build/curseme-w32/meow/
curl -L -o meow.tar.gz https://git.sakamoto.pl/domi/curseme/-/archive/launcher/curseme-launcher.tar.gz?path=launcher
tar xvf meow.tar.gz
mkdir -p build/curseme-w32/meow
mv curseme-launcher-launcher/launcher/* build/curseme-w32/meow/
styrene -o ./build ./curseme.cfg

View File

@ -0,0 +1,34 @@
# Styrene config file for gtk-demo and related apps.
# https://github.com/achadwick/styrene/
[bundle]
packages = p7zip {pkg_prefix}jq {pkg_prefix}curl msys2-runtime grep sed {pkg_prefix}termcap ncurses awk findutils
filename_stub = curseme
display_name = CurseMe
description = 3rd-party Minecraft launcher
version = 0.1
url = https://git.sakamoto.pl/domi/curseme/
launchers = meow
delete =
mingw*/share/man/*
mingw*/share/doc/*
mingw*/include/*
# messy, but idc
nodelete =
usr/bin/7z
usr/bin/msys-2.0.dll
usr/lib/p7zip/*
usr/bin/cygpath.exe
mingw*/bin/*.dll
mingw*/bin/*.exe
[meow]
name = CurseMe
comment = nie wiem
exec = bash --rcfile /meow/helper.sh
icon = input-tablet
terminal = true