IT WORKS!
This commit is contained in:
parent
4d6dbd40ac
commit
4bf65a0025
4
go.mod
4
go.mod
@ -2,17 +2,19 @@ module minecraft
|
|||||||
|
|
||||||
go 1.23.2
|
go 1.23.2
|
||||||
|
|
||||||
|
require github.com/jaypipes/ghw v0.13.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/go-gl/mathgl v1.1.0 // indirect
|
github.com/go-gl/mathgl v1.1.0 // indirect
|
||||||
github.com/go-jose/go-jose/v3 v3.0.3 // indirect
|
github.com/go-jose/go-jose/v3 v3.0.3 // indirect
|
||||||
github.com/golang/snappy v0.0.4 // indirect
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/jaypipes/ghw v0.13.0
|
|
||||||
github.com/klauspost/compress v1.17.11 // indirect
|
github.com/klauspost/compress v1.17.11 // indirect
|
||||||
github.com/muhammadmuzzammil1998/jsonc v1.0.0 // indirect
|
github.com/muhammadmuzzammil1998/jsonc v1.0.0 // indirect
|
||||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||||
github.com/sandertv/go-raknet v1.14.2 // indirect
|
github.com/sandertv/go-raknet v1.14.2 // indirect
|
||||||
github.com/sandertv/gophertunnel v1.41.1 // indirect
|
github.com/sandertv/gophertunnel v1.41.1 // indirect
|
||||||
|
github.com/zhyee/zipstream v0.0.0-20230625125559-133d8d1afaa0 // indirect
|
||||||
golang.org/x/crypto v0.28.0 // indirect
|
golang.org/x/crypto v0.28.0 // indirect
|
||||||
golang.org/x/image v0.21.0 // indirect
|
golang.org/x/image v0.21.0 // indirect
|
||||||
golang.org/x/net v0.30.0 // indirect
|
golang.org/x/net v0.30.0 // indirect
|
||||||
|
2
go.sum
2
go.sum
@ -24,6 +24,8 @@ github.com/sandertv/gophertunnel v1.41.1/go.mod h1:krvLSeRUNQ2iEYJNEgzrKtWO8W5yb
|
|||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
github.com/zhyee/zipstream v0.0.0-20230625125559-133d8d1afaa0 h1:BcjUUYzMORs7sJtOCWLXaelG7woHMN1QEs4yCB1QZ48=
|
||||||
|
github.com/zhyee/zipstream v0.0.0-20230625125559-133d8d1afaa0/go.mod h1:aaGtAo3dTqYtHjcliPNlyXMIIodvGm8y6uK2KMTYHrk=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
|
BIN
logs/2024-10-29-1.log.gz
Normal file
BIN
logs/2024-10-29-1.log.gz
Normal file
Binary file not shown.
BIN
logs/2024-10-29-2.log.gz
Normal file
BIN
logs/2024-10-29-2.log.gz
Normal file
Binary file not shown.
BIN
logs/2024-10-29-3.log.gz
Normal file
BIN
logs/2024-10-29-3.log.gz
Normal file
Binary file not shown.
BIN
logs/2024-10-29-4.log.gz
Normal file
BIN
logs/2024-10-29-4.log.gz
Normal file
Binary file not shown.
BIN
logs/2024-10-29-5.log.gz
Normal file
BIN
logs/2024-10-29-5.log.gz
Normal file
Binary file not shown.
BIN
logs/2024-10-29-6.log.gz
Normal file
BIN
logs/2024-10-29-6.log.gz
Normal file
Binary file not shown.
BIN
logs/2024-10-29-7.log.gz
Normal file
BIN
logs/2024-10-29-7.log.gz
Normal file
Binary file not shown.
226
logs/latest.log
Normal file
226
logs/latest.log
Normal file
File diff suppressed because one or more lines are too long
222
main.go
222
main.go
@ -10,19 +10,28 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const client_id string = "9305aeb8-5ecb-4e7a-b28f-c33aefcfbd8d"
|
const client_id string = "9305aeb8-5ecb-4e7a-b28f-c33aefcfbd8d"
|
||||||
|
|
||||||
|
type McProfile struct {
|
||||||
|
Id string
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
type Authentication struct {
|
type Authentication struct {
|
||||||
Access authenticationResp
|
Access authenticationResp
|
||||||
XboxAuth xboxAuthResponse
|
XboxAuth xboxAuthResponse
|
||||||
XboxAPI xboxAuthResponse
|
XboxAPI xboxAuthResponse
|
||||||
McAPI xboxAuthResponse
|
McAPI xboxAuthResponse
|
||||||
McAuth McAuthResponse
|
McAuth McAuthResponse
|
||||||
|
Profile McProfile
|
||||||
}
|
}
|
||||||
|
|
||||||
type devCodeResp struct {
|
type devCodeResp struct {
|
||||||
@ -120,8 +129,8 @@ type McVersionManifest struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type McArguments struct {
|
type McArguments struct {
|
||||||
Game interface{}
|
Game []string
|
||||||
Jvm interface{}
|
Jvm []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type McAssetIndex struct {
|
type McAssetIndex struct {
|
||||||
@ -139,10 +148,10 @@ type McDownload struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type McDownloads struct {
|
type McDownloads struct {
|
||||||
Client []McDownload
|
Client McDownload
|
||||||
Client_mappings []McDownload
|
Client_mappings McDownload
|
||||||
Server []McDownload
|
Server McDownload
|
||||||
Server_mappings []McDownload
|
Server_mappings McDownload
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,10 +171,22 @@ type McLibraryDownload struct {
|
|||||||
Artifact McLibraryArtifact
|
Artifact McLibraryArtifact
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type McRuleOs struct {
|
||||||
|
Name string
|
||||||
|
Version string
|
||||||
|
Arch string
|
||||||
|
}
|
||||||
|
|
||||||
|
type McRule struct {
|
||||||
|
Action string
|
||||||
|
Features map[string]bool
|
||||||
|
Os McRuleOs
|
||||||
|
}
|
||||||
|
|
||||||
type McLibrary struct {
|
type McLibrary struct {
|
||||||
Downloads McLibraryDownload
|
Downloads McLibraryDownload
|
||||||
Name string
|
Name string
|
||||||
Rules interface{}
|
Rules []McRule
|
||||||
}
|
}
|
||||||
|
|
||||||
type McMetadata struct {
|
type McMetadata struct {
|
||||||
@ -326,6 +347,17 @@ func main() {
|
|||||||
}
|
}
|
||||||
d, _ = io.ReadAll(resp.Body)
|
d, _ = io.ReadAll(resp.Body)
|
||||||
json.Unmarshal(d, &auth.McAuth)
|
json.Unmarshal(d, &auth.McAuth)
|
||||||
|
httpReq, err = http.NewRequest("GET", "https://api.minecraftservices.com/minecraft/profile", new(bytes.Buffer))
|
||||||
|
httpReq.Header.Add("Content-Type", "application/json")
|
||||||
|
httpReq.Header.Add("Accept", "application/json")
|
||||||
|
httpReq.Header.Add("Authorization", "Bearer "+auth.McAuth.Access_token)
|
||||||
|
resp, _ = client.Do(httpReq)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error obtaining mc profile information: %s\n", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
data, _ = io.ReadAll(resp.Body)
|
||||||
|
json.Unmarshal(data, &auth.Profile)
|
||||||
resp, err = http.Get("https://piston-meta.mojang.com/mc/game/version_manifest_v2.json")
|
resp, err = http.Get("https://piston-meta.mojang.com/mc/game/version_manifest_v2.json")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("manifest error")
|
fmt.Printf("manifest error")
|
||||||
@ -342,24 +374,44 @@ func main() {
|
|||||||
data, _ = io.ReadAll(resp.Body)
|
data, _ = io.ReadAll(resp.Body)
|
||||||
var metadata McMetadata
|
var metadata McMetadata
|
||||||
json.Unmarshal(data, &metadata)
|
json.Unmarshal(data, &metadata)
|
||||||
resp, err = http.Get(metadata.AssetIndex.Url)
|
os.MkdirAll(filepath.Join(dir, "minecraft_test", "assets", "indexes"), 0755)
|
||||||
if err != nil {
|
os.MkdirAll(filepath.Join(dir, "minecraft_test", "assets", "objects"), 0755)
|
||||||
fmt.Printf("asset index error")
|
download_index := false
|
||||||
|
if _, err := os.Stat(filepath.Join(dir, "minecraft_test", "assets", "indexes", metadata.Assets+".json")); err == nil {
|
||||||
|
f, _ := os.OpenFile(filepath.Join(dir, "minecraft_test", "assets", "indexes", metadata.Assets+".json"), os.O_RDONLY, 0755)
|
||||||
|
defer f.Close()
|
||||||
|
data, _ = io.ReadAll(f)
|
||||||
|
sha := sha1.Sum(data)
|
||||||
|
if hex.EncodeToString(sha[:20]) != metadata.AssetIndex.Sha1 {
|
||||||
|
download_index = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
download_index = true
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
if download_index {
|
||||||
data, _ = io.ReadAll(resp.Body)
|
resp, err = http.Get(metadata.AssetIndex.Url)
|
||||||
sha := sha1.Sum(data)
|
if err != nil {
|
||||||
if hex.EncodeToString(sha[:20]) != metadata.AssetIndex.Sha1 {
|
fmt.Printf("asset index error")
|
||||||
fmt.Printf("Error downloading asset index")
|
}
|
||||||
return
|
defer resp.Body.Close()
|
||||||
|
data, _ = io.ReadAll(resp.Body)
|
||||||
|
sha := sha1.Sum(data)
|
||||||
|
if hex.EncodeToString(sha[:20]) != metadata.AssetIndex.Sha1 {
|
||||||
|
fmt.Printf("Error downloading asset index")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f, _ = os.OpenFile(filepath.Join(dir, "minecraft_test", "assets", "indexes", metadata.Assets + ".json"), os.O_CREATE|os.O_RDWR, 0755)
|
||||||
|
defer f.Close()
|
||||||
|
f.Write(data)
|
||||||
}
|
}
|
||||||
var index map[string]interface{}
|
var index map[string]interface{}
|
||||||
json.Unmarshal(data, &index)
|
json.Unmarshal(data, &index)
|
||||||
index = index["objects"].(map[string]interface{})
|
index = index["objects"].(map[string]interface{})
|
||||||
for name, asset := range index {
|
for name, asset := range index {
|
||||||
asset_map := asset.(map[string]interface{})
|
asset_map := asset.(map[string]interface{})
|
||||||
if _, err = os.Stat(filepath.Join(dir, "minecraft_test", "assets", metadata.Assets, name)); err == nil {
|
path := asset_map["hash"].(string)[:2] + "/" + asset_map["hash"].(string)
|
||||||
f, _ := os.OpenFile(filepath.Join(dir, "minecraft_test", "assets", metadata.Assets, name), os.O_RDONLY, 0755)
|
if _, err = os.Stat(filepath.Join(dir, "minecraft_test", "assets", "objects", path)); err == nil {
|
||||||
|
f, _ := os.OpenFile(filepath.Join(dir, "minecraft_test", "assets", "objects", path), os.O_RDONLY, 0755)
|
||||||
data, _ := io.ReadAll(f)
|
data, _ := io.ReadAll(f)
|
||||||
sha := sha1.Sum(data)
|
sha := sha1.Sum(data)
|
||||||
if hex.EncodeToString(sha[:20]) == asset_map["hash"].(string) {
|
if hex.EncodeToString(sha[:20]) == asset_map["hash"].(string) {
|
||||||
@ -374,26 +426,28 @@ func main() {
|
|||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
data, _ = io.ReadAll(resp.Body)
|
data, _ = io.ReadAll(resp.Body)
|
||||||
sha = sha1.Sum(data)
|
sha := sha1.Sum(data)
|
||||||
if hex.EncodeToString(sha[:20]) != asset_map["hash"].(string) {
|
if hex.EncodeToString(sha[:20]) != asset_map["hash"].(string) {
|
||||||
fmt.Printf("Sha1 Mismatch\n")
|
fmt.Printf("Sha1 Mismatch\n")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Printf("Ok\n")
|
fmt.Printf("Ok\n")
|
||||||
path := ""
|
os.MkdirAll(filepath.Join(dir, "minecraft_test", "assets", "objects", asset_map["hash"].(string)[:2]), 0755)
|
||||||
tokens := strings.Split(name, "/")
|
f, _ := os.OpenFile(filepath.Join(dir, "minecraft_test", "assets", "objects", path), os.O_CREATE|os.O_RDWR, 0755)
|
||||||
for ind, token := range tokens {
|
|
||||||
if ind != len(tokens)-1 {
|
|
||||||
path = filepath.Join(path, token)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
os.MkdirAll(filepath.Join(dir, "minecraft_test", "assets", metadata.Assets, path), 0755)
|
|
||||||
f, _ := os.OpenFile(filepath.Join(dir, "minecraft_test", "assets", metadata.Assets, name), os.O_CREATE|os.O_RDWR, 0755)
|
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
f.Write(data)
|
f.Write(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, lib := range metadata.Libraries {
|
for _, lib := range metadata.Libraries {
|
||||||
|
if _, err = os.Stat(filepath.Join(dir, "minecraft_test", "lib", lib.Downloads.Artifact.Path)); err == nil {
|
||||||
|
f, _ := os.OpenFile(filepath.Join(dir, "minecraft_test", "lib", lib.Downloads.Artifact.Path), os.O_RDONLY, 0755)
|
||||||
|
defer f.Close()
|
||||||
|
data, _ := io.ReadAll(f)
|
||||||
|
sha := sha1.Sum(data)
|
||||||
|
if hex.EncodeToString(sha[:20]) == lib.Downloads.Artifact.Sha1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
fmt.Printf("Downloading %s: ", lib.Name)
|
fmt.Printf("Downloading %s: ", lib.Name)
|
||||||
resp, err = http.Get(lib.Downloads.Artifact.Url)
|
resp, err = http.Get(lib.Downloads.Artifact.Url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -402,13 +456,121 @@ func main() {
|
|||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
data, _ = io.ReadAll(resp.Body)
|
data, _ = io.ReadAll(resp.Body)
|
||||||
sha = sha1.Sum(data)
|
sha := sha1.Sum(data)
|
||||||
if hex.EncodeToString(sha[:20]) != lib.Downloads.Artifact.Sha1 {
|
if hex.EncodeToString(sha[:20]) != lib.Downloads.Artifact.Sha1 {
|
||||||
fmt.Printf("Sha1 Mismatch\n")
|
fmt.Printf("Sha1 Mismatch\n")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
path := ""
|
||||||
|
tokens := strings.Split(lib.Downloads.Artifact.Path, "/")
|
||||||
|
for ind, token := range tokens {
|
||||||
|
if ind != len(tokens)-1 {
|
||||||
|
path = filepath.Join(path, token)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
os.MkdirAll(filepath.Join(dir, "minecraft_test", "lib", path), 0755)
|
||||||
|
f, _ := os.OpenFile(filepath.Join(dir, "minecraft_test", "lib", lib.Downloads.Artifact.Path), os.O_CREATE|os.O_RDWR, 0755)
|
||||||
|
defer f.Close()
|
||||||
|
f.Write(data)
|
||||||
fmt.Printf("OK\n")
|
fmt.Printf("OK\n")
|
||||||
}
|
}
|
||||||
|
download := false
|
||||||
|
if os.Stat(filepath.Join(dir, "minecraft_test", "bin", metadata.Id, "client.jar")); err == nil {
|
||||||
|
f, _ := os.OpenFile(filepath.Join(dir, "minecraft_test", "bin", metadata.Id, "client.jar"), os.O_RDONLY, 0755)
|
||||||
|
defer f.Close()
|
||||||
|
data, _ := io.ReadAll(f)
|
||||||
|
sha := sha1.Sum(data)
|
||||||
|
if hex.EncodeToString(sha[:20]) != metadata.Downloads.Client.Sha1 {
|
||||||
|
download = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
download = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if download {
|
||||||
|
fmt.Printf("Downloading minecraft.jar: ")
|
||||||
|
req, err := http.Get(metadata.Downloads.Client.Url)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("ERROR\n")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer req.Body.Close()
|
||||||
|
data, _ := io.ReadAll(req.Body)
|
||||||
|
sha := sha1.Sum(data)
|
||||||
|
if hex.EncodeToString(sha[:20]) != metadata.Downloads.Client.Sha1 {
|
||||||
|
fmt.Printf("Sha Mismatch\n")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Printf("OK\n")
|
||||||
|
os.MkdirAll(filepath.Join(dir, "minecraft_test", "bin", metadata.Id), 0755)
|
||||||
|
f, _ := os.OpenFile(filepath.Join(dir, "minecraft_test", "bin", metadata.Id, "client.jar"), os.O_CREATE|os.O_RDWR, 0755)
|
||||||
|
defer f.Close()
|
||||||
|
f.Write(data)
|
||||||
|
}
|
||||||
|
os.MkdirAll(filepath.Join(dir, "minecraft_test", "minecraft"), 0755)
|
||||||
|
args := []string{}
|
||||||
|
args = append(args, "-Xms512m")
|
||||||
|
args = append(args, "-Xmx1024m")
|
||||||
|
for _, val := range metadata.Arguments.Jvm {
|
||||||
|
val = strings.ReplaceAll(val, "${natives_directory}", filepath.Join(dir, "minecraft_test", "minecraft", "natives"))
|
||||||
|
switch val {
|
||||||
|
case "-cp":
|
||||||
|
args = append(args, val)
|
||||||
|
case "${classpath}":
|
||||||
|
arg := ""
|
||||||
|
for _, lib := range metadata.Libraries {
|
||||||
|
if lib.Rules != nil && lib.Rules[0].Os.Name != runtime.GOOS {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
arg += filepath.Join(dir, "minecraft_test", "lib", lib.Downloads.Artifact.Path) + ":"
|
||||||
|
}
|
||||||
|
arg += filepath.Join(dir, "minecraft_test", "bin", metadata.Id, "client.jar")
|
||||||
|
args = append(args, arg)
|
||||||
|
default:
|
||||||
|
//args = append(args, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
args = append(args, "net.minecraft.client.main.Main")
|
||||||
|
|
||||||
|
for _, val := range metadata.Arguments.Game {
|
||||||
|
switch val{
|
||||||
|
case "${auth_player_name}":
|
||||||
|
args = append(args, auth.Profile.Name)
|
||||||
|
case "${version_name}":
|
||||||
|
args = append(args, metadata.Id)
|
||||||
|
case "${game_directory}":
|
||||||
|
args = append(args, filepath.Join(dir, "minecraft_test", "minecraft"))
|
||||||
|
case "${assets_root}":
|
||||||
|
args = append(args, filepath.Join(dir, "minecraft_test", "assets"))
|
||||||
|
case "${auth_uuid}":
|
||||||
|
args = append(args, auth.Profile.Id)
|
||||||
|
case "${auth_access_token}":
|
||||||
|
args = append(args, auth.McAuth.Access_token)
|
||||||
|
case "${clientid}":
|
||||||
|
args = append(args, client_id)
|
||||||
|
case "${auth_xuid}":
|
||||||
|
args = append(args, auth.Profile.Id)
|
||||||
|
case "${version_type}":
|
||||||
|
args = append(args, "release")
|
||||||
|
case "${user_type}":
|
||||||
|
args = append(args, "mojang")
|
||||||
|
case "${assets_index_name}":
|
||||||
|
args = append(args, metadata.Assets)
|
||||||
|
|
||||||
|
default:
|
||||||
|
args = append(args, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Args: %+v", args)
|
||||||
|
|
||||||
|
cmd := exec.Command("/usr/lib/jvm/java-21-openjdk/bin/java", args...)
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error: %s\n", err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Output: %s\n", out)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user