nds-converter.go (view raw)
1package main
2
3import (
4 "encoding/hex"
5 "io"
6 "net/http"
7 "os"
8 "path/filepath"
9 "strconv"
10
11 "github.com/joho/godotenv"
12)
13
14type ConverterFunction func([]byte) []byte
15
16const (
17 MB = 1 << 20
18 DefaultMaxFileSize = 2
19 DefaultPort = "1111"
20 TrimBytes = 122
21 AdditionalBytesHex = "7C3C2D2D536E69702061626F7665206865726520746F2063726561746520612072617720736176206279206578636C7564696E672074686973204465536D754D4520736176656461746120666F6F7465723A0000010000000100030000000200000000000100000000007C2D4445534D554D4520534156452D7C"
22)
23
24var (
25 MaxFileSize int64
26 AdditionalBytes []byte
27 ConverterFunctions = map[string]ConverterFunction{
28 ".dsv": DsvToSav,
29 ".sav": SavToDsv,
30 }
31)
32
33func main() {
34 // Load the .env file
35 err := godotenv.Load()
36 if err != nil {
37 println("Could not load .env file")
38 }
39
40 port := os.Getenv("PORT")
41 if port == "" {
42 port = DefaultPort
43 }
44
45 fileSizeString := os.Getenv("MAX_SIZE_MB")
46 MaxFileSize, err = strconv.ParseInt(fileSizeString, 10, 64)
47 if err != nil {
48 MaxFileSize = DefaultMaxFileSize
49 }
50 MaxFileSize *= MB
51
52 AdditionalBytes, _ = hex.DecodeString(AdditionalBytesHex)
53
54 http.HandleFunc("/", uploadHandler)
55 println("Listening on port " + port)
56 http.ListenAndServe(":"+port, nil)
57}
58
59func DsvToSav(input []byte) []byte {
60 return input[:len(input)-TrimBytes]
61}
62
63func SavToDsv(input []byte) []byte {
64 return append(input, AdditionalBytes...)
65}
66
67func uploadHandler(w http.ResponseWriter, r *http.Request) {
68 // Parse the multipart form data
69 err := r.ParseMultipartForm(MaxFileSize)
70 if err != nil {
71 http.Error(w, "Error parsing form", http.StatusBadRequest)
72 return
73 }
74
75 r.Body = http.MaxBytesReader(w, r.Body, MaxFileSize)
76
77 // Get the file from the request
78 file, h, err := r.FormFile("file")
79 if err != nil {
80 http.Error(w, "Error retrieving file from form data", http.StatusBadRequest)
81 return
82 }
83 defer file.Close()
84
85 // Check file size
86 if h.Size > MaxFileSize {
87 http.Error(w, "File size exceeds 1MB", http.StatusBadRequest)
88 return
89 }
90
91 var outputContent []byte
92
93 // Check file extension
94 fileExt := filepath.Ext(h.Filename)
95 converterFunction, exists := ConverterFunctions[fileExt]
96 if !exists {
97 http.Error(w, "Invalid file format, only .dsv and .sav files are allowed", http.StatusBadRequest)
98 return
99 }
100
101 content, err := io.ReadAll(file)
102 if err != nil {
103 http.Error(w, "Error reading file content", http.StatusInternalServerError)
104 return
105 }
106 outputContent = converterFunction(content)
107
108 w.Header().Set("Content-Length", strconv.Itoa(len(outputContent)))
109 w.Header().Set("Content-Type", "application/octet-stream")
110 w.WriteHeader(http.StatusOK)
111 w.Write(outputContent)
112}