-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
126 lines (108 loc) · 3.18 KB
/
main.go
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package main
import (
"fmt"
"golang.org/x/sys/windows"
"log"
"math/rand"
"os"
"os/exec"
"strings"
"syscall"
"unsafe"
"github.com/restartfu/portmypack/portmypack"
"github.com/restartfu/portmypack/portmypack/java"
)
func main() {
path, ok := getFileSelectionPath()
if !ok {
log.Fatalln("please select a valid zip archive")
}
javapack, err := java.NewResourcePack(path)
if err != nil {
log.Fatalln(err)
}
out := fmt.Sprintf("%s\\portmypack-%d.mcpack", os.TempDir(), rand.Int63())
portmypack.PortJavaEditionPack(javapack, out)
cmd := exec.Command("cmd", "/c", out)
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
err = cmd.Run()
if err != nil {
log.Fatalln(err)
}
}
var (
// https://docs.microsoft.com/en-us/windows/win32/api/commdlg/
_Dialog32 = windows.NewLazySystemDLL("comdlg32.dll")
_GetOpenFileName = _Dialog32.NewProc("GetOpenFileNameW")
// https://docs.microsoft.com/en-us/windows/win32/api/commdlg/ns-commdlg-openfilenamew
_FlagFileMustExist = uint32(0x00001000)
_FlagForceShowHidden = uint32(0x10000000)
_FlagDisableLinks = uint32(0x00100000)
_FilePathLength = uint32(65535)
_OpenFileStructLength = uint32(unsafe.Sizeof(_OpenFileName{}))
)
type (
// _OpenFileName is defined at https://docs.microsoft.com/pt-br/windows/win32/api/commdlg/ns-commdlg-openfilenamew
_OpenFileName struct {
StructSize uint32
Owner uintptr
Instance uintptr
Filter *uint16
CustomFilter *uint16
MaxCustomFilter uint32
FilterIndex uint32
File *uint16
MaxFile uint32
FileTitle *uint16
MaxFileTitle uint32
InitialDir *uint16
Title *uint16
Flags uint32
FileOffset uint16
FileExtension uint16
DefExt *uint16
CustData uintptr
FnHook uintptr
TemplateName *uint16
PvReserved uintptr
DwReserved uint32
FlagsEx uint32
}
)
func getFileSelectionPath() (string, bool) {
pathUTF16 := make([]uint16, _FilePathLength)
open := _OpenFileName{
File: &pathUTF16[0],
MaxFile: _FilePathLength,
Filter: buildFilter([]string{"zip"}),
Flags: _FlagFileMustExist | _FlagForceShowHidden | _FlagDisableLinks,
StructSize: _OpenFileStructLength,
}
if r, _, _ := _GetOpenFileName.Call(uintptr(unsafe.Pointer(&open))); r == 0 {
return "", false
}
path := windows.UTF16ToString(pathUTF16)
if len(path) == 0 {
return "", false
}
return path, true
}
func buildFilter(extensions []string) *uint16 {
if len(extensions) <= 0 {
return nil
}
for k, v := range extensions {
// Extension must have `*` wildcard, so `.jpg` must be `*.jpg`.
if !strings.HasPrefix(v, "*") {
extensions[k] = "*" + v
}
}
e := strings.ToUpper(strings.Join(extensions, ";"))
// That is a "string-pair", Windows have a Title and the Filter, for instance it could be:
// Images\0*.JPG;*.PNG\0\0
// Where `\0` means NULL
f := windows.StringToUTF16(e + " " + e) // Use the filter as title so it appear `*.JPG;*.PNG` for the user.
f[len(e)] = 0 // Replace the " " (space) with NULL.
f = append(f, uint16(0)) // Adding another NULL, because we need two.
return &f[0]
}