sterepando commited on
Commit
9f4cc8b
·
verified ·
1 Parent(s): 953c409

Update Dockerfile

Browse files
Files changed (1) hide show
  1. Dockerfile +163 -234
Dockerfile CHANGED
@@ -1,241 +1,170 @@
1
- # --- START OF FILE Dockerfile ---
2
- FROM golang:1.21
3
 
4
- # 1. Установка инструментов + PYTHON3 для веб-сервера
5
- RUN apt-get update && apt-get install -y wget unzip build-essential python3
6
-
7
- # 2. Настройка Android NDK
8
- ENV ANDROID_NDK_HOME /opt/android-ndk
9
- ENV ANDROID_NDK_VERSION r25c
10
-
11
- RUN wget -q https://dl.google.com/android/repository/android-ndk-${ANDROID_NDK_VERSION}-linux.zip && \
12
- unzip -q android-ndk-${ANDROID_NDK_VERSION}-linux.zip && \
13
- mv android-ndk-${ANDROID_NDK_VERSION} /opt/android-ndk && \
14
- rm android-ndk-${ANDROID_NDK_VERSION}-linux.zip
15
-
16
- ENV PATH ${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH
17
 
 
18
  WORKDIR /app
19
 
20
- # 3. Инициализация Go модуля
21
- RUN go mod init mandre_server
22
-
23
- # 4. Код сервера (без лишних импортов)
24
- RUN cat <<EOF > main.go
25
- package main
26
-
27
- import "C"
28
-
29
- import (
30
- "bytes"
31
- "fmt"
32
- "image"
33
- "image/png"
34
- "net/http"
35
- "sync"
36
- "unsafe"
37
-
38
- "github.com/gorilla/websocket"
39
- )
40
-
41
- var (
42
- mu sync.RWMutex
43
- prevFrame *image.RGBA
44
- clients = make(map[*websocket.Conn]bool)
45
- broadcast = make(chan []byte)
46
- upgrader = websocket.Upgrader{CheckOrigin: func(r *http.Request) bool { return true }}
47
- serverStarted bool
48
- )
49
-
50
- const indexHTML = \`
51
- <!DOCTYPE html>
52
- <html>
53
- <head>
54
- <title>Mandre Stream (Delta)</title>
55
- <style>
56
- body { background: #1a1a1a; color: #eee; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; margin: 0; font-family: monospace; }
57
- canvas { border: 2px solid #444; background: #000; max-width: 100%; max-height: 80vh; }
58
- #status { margin-top: 10px; color: #0f0; }
59
- </style>
60
- </head>
61
- <body>
62
- <canvas id="screen"></canvas>
63
- <div id="status">Connecting...</div>
64
- <script>
65
- const canvas = document.getElementById('screen');
66
- const ctx = canvas.getContext('2d', { alpha: false });
67
- const status = document.getElementById('status');
68
-
69
- let ws = new WebSocket("ws://" + location.host + "/ws");
70
- ws.binaryType = "arraybuffer";
71
-
72
- ws.onopen = () => { status.innerText = "Connected (Delta Stream)"; };
73
- ws.onclose = () => { status.innerText = "Disconnected"; setTimeout(() => location.reload(), 2000); };
74
-
75
- ws.onmessage = (event) => {
76
- const blob = new Blob([event.data], {type: "image/png"});
77
- const url = URL.createObjectURL(blob);
78
- const img = new Image();
79
-
80
- img.onload = () => {
81
- if (canvas.width !== img.width || canvas.height !== img.height) {
82
- canvas.width = img.width;
83
- canvas.height = img.height;
84
- }
85
- ctx.drawImage(img, 0, 0);
86
- URL.revokeObjectURL(url);
87
- };
88
- img.src = url;
89
- };
90
- </script>
91
- </body>
92
- </html>
93
- \`
94
-
95
- //export StartServer
96
- func StartServer(port int) {
97
- if serverStarted {
98
- return
99
- }
100
- serverStarted = true
101
-
102
- go func() {
103
- http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
104
- w.Header().Set("Content-Type", "text/html")
105
- w.Write([]byte(indexHTML))
106
- })
107
-
108
- http.HandleFunc("/ws", handleConnections)
109
-
110
- addr := fmt.Sprintf(":%d", port)
111
- fmt.Printf("[Go] Server starting on %s\n", addr)
112
- http.ListenAndServe(addr, nil)
113
- }()
114
-
115
- go handleMessages()
116
- }
117
-
118
- //export StopServer
119
- func StopServer() {}
120
-
121
- //export UpdateFrame
122
- func UpdateFrame(width, height int, rawPtr unsafe.Pointer, length int) {
123
- rawBytes := unsafe.Slice((*byte)(rawPtr), length)
124
-
125
- img := image.NewRGBA(image.Rect(0, 0, width, height))
126
- copy(img.Pix, rawBytes)
127
-
128
- diffImg := generateDelta(img)
129
-
130
- var buf bytes.Buffer
131
- enc := png.Encoder{CompressionLevel: png.NoCompression}
132
- if err := enc.Encode(&buf, diffImg); err == nil {
133
- select {
134
- case broadcast <- buf.Bytes():
135
- default:
136
- }
137
- }
138
- }
139
-
140
- func generateDelta(current *image.RGBA) image.Image {
141
- mu.Lock()
142
- defer mu.Unlock()
143
-
144
- if prevFrame == nil || prevFrame.Bounds() != current.Bounds() {
145
- prevFrame = current
146
- return current
147
- }
148
-
149
- bounds := current.Bounds()
150
- diff := image.NewRGBA(bounds)
151
-
152
- totalPixels := len(current.Pix)
153
- changed := false
154
-
155
- for i := 0; i < totalPixels; i += 4 {
156
- if current.Pix[i] != prevFrame.Pix[i] ||
157
- current.Pix[i+1] != prevFrame.Pix[i+1] ||
158
- current.Pix[i+2] != prevFrame.Pix[i+2] ||
159
- current.Pix[i+3] != prevFrame.Pix[i+3] {
160
-
161
- diff.Pix[i] = current.Pix[i]
162
- diff.Pix[i+1] = current.Pix[i+1]
163
- diff.Pix[i+2] = current.Pix[i+2]
164
- diff.Pix[i+3] = current.Pix[i+3]
165
-
166
- changed = true
167
- }
168
- }
169
-
170
- prevFrame = current
171
-
172
- if !changed {
173
- return image.NewRGBA(image.Rect(0, 0, 1, 1))
174
- }
175
-
176
- return diff
177
- }
178
-
179
- func handleConnections(w http.ResponseWriter, r *http.Request) {
180
- ws, err := upgrader.Upgrade(w, r, nil)
181
- if err != nil {
182
- return
183
- }
184
- defer ws.Close()
185
-
186
- mu.Lock()
187
- clients[ws] = true
188
- prevFrame = nil
189
- mu.Unlock()
190
-
191
- for {
192
- _, _, err := ws.ReadMessage()
193
- if err != nil {
194
- mu.Lock()
195
- delete(clients, ws)
196
- mu.Unlock()
197
- break
198
- }
199
- }
200
- }
201
-
202
- func handleMessages() {
203
- for {
204
- pngData := <-broadcast
205
- mu.RLock()
206
- for client := range clients {
207
- err := client.WriteMessage(websocket.BinaryMessage, pngData)
208
- if err != nil {
209
- client.Close()
210
- delete(clients, client)
211
- }
212
- }
213
- mu.RUnlock()
214
- }
215
- }
216
-
217
- func main() {}
218
- EOF
219
-
220
- # 5. Зависимости
221
- RUN go get github.com/gorilla/websocket
222
-
223
- # 6. Компиляция
224
- RUN CGO_ENABLED=1 \
225
- GOOS=android \
226
- GOARCH=arm64 \
227
- CC=aarch64-linux-android33-clang \
228
- go build -buildmode=c-shared -o libmandre_server.so main.go
229
-
230
- # 7. Подготовка к раздаче файла
231
- # Создаем папку output и перемещаем туда .so файл
232
- RUN mkdir /output && mv libmandre_server.so /output/
233
-
234
- WORKDIR /output
235
 
236
- # Открываем порт для Hugging Face
237
  EXPOSE 7860
238
 
239
- # Запускаем веб-сервер Python для скачивания файлов
240
- CMD ["python3", "-m", "http.server", "7860"]
241
- # --- END OF FILE Dockerfile ---
 
1
+ FROM eclipse-temurin:17-jdk-jammy
 
2
 
3
+ # Установка необходимых пакетов
4
+ RUN apt-get update && apt-get install -y \
5
+ git \
6
+ python3 \
7
+ python3-pip \
8
+ && rm -rf /var/lib/apt/lists/*
 
 
 
 
 
 
 
9
 
10
+ # Создание рабочей директории
11
  WORKDIR /app
12
 
13
+ # Создание структуры мода
14
+ RUN mkdir -p src/main/java/com/freecam/mod src/main/resources
15
+
16
+ # Создание gradle wrapper и build.gradle
17
+ RUN echo 'plugins {\n\
18
+ id "fabric-loom" version "1.4-SNAPSHOT"\n\
19
+ id "maven-publish"\n\
20
+ }\n\
21
+ \n\
22
+ version = "1.0.0"\n\
23
+ group = "com.freecam"\n\
24
+ \n\
25
+ repositories {\n\
26
+ mavenCentral()\n\
27
+ maven { url "https://maven.fabricmc.net/" }\n\
28
+ }\n\
29
+ \n\
30
+ dependencies {\n\
31
+ minecraft "com.mojang:minecraft:1.20.1"\n\
32
+ mappings "net.fabricmc:yarn:1.20.1+build.10:v2"\n\
33
+ modImplementation "net.fabricmc:fabric-loader:0.15.0"\n\
34
+ modImplementation "net.fabricmc.fabric-api:fabric-api:0.92.0+1.20.1"\n\
35
+ }\n\
36
+ \n\
37
+ processResources {\n\
38
+ inputs.property "version", project.version\n\
39
+ filesMatching("fabric.mod.json") {\n\
40
+ expand "version": project.version\n\
41
+ }\n\
42
+ }\n\
43
+ \n\
44
+ java {\n\
45
+ sourceCompatibility = JavaVersion.VERSION_17\n\
46
+ targetCompatibility = JavaVersion.VERSION_17\n\
47
+ }\n\
48
+ \n\
49
+ jar {\n\
50
+ from("LICENSE") {\n\
51
+ rename { "${it}_${project.archivesBaseName}"}\n\
52
+ }\n\
53
+ }' > build.gradle
54
+
55
+ # Создание gradle.properties
56
+ RUN echo 'org.gradle.jvmargs=-Xmx2G\n\
57
+ org.gradle.daemon=false' > gradle.properties
58
+
59
+ # Создание settings.gradle
60
+ RUN echo 'pluginManagement {\n\
61
+ repositories {\n\
62
+ maven { url "https://maven.fabricmc.net/" }\n\
63
+ gradlePluginPortal()\n\
64
+ }\n\
65
+ }' > settings.gradle
66
+
67
+ # Создание основного класса мода
68
+ RUN echo 'package com.freecam.mod;\n\
69
+ \n\
70
+ import net.fabricmc.api.ClientModInitializer;\n\
71
+ import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;\n\
72
+ import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;\n\
73
+ import net.minecraft.client.MinecraftClient;\n\
74
+ import net.minecraft.client.option.KeyBinding;\n\
75
+ import net.minecraft.client.util.InputUtil;\n\
76
+ import org.lwjgl.glfw.GLFW;\n\
77
+ \n\
78
+ public class FreeCamMod implements ClientModInitializer {\n\
79
+ private static KeyBinding freecamKey;\n\
80
+ private static boolean freecamActive = false;\n\
81
+ private static double savedX, savedY, savedZ;\n\
82
+ private static float savedYaw, savedPitch;\n\
83
+ \n\
84
+ @Override\n\
85
+ public void onInitializeClient() {\n\
86
+ freecamKey = KeyBindingHelper.registerKeyBinding(new KeyBinding(\n\
87
+ "key.freecam.toggle",\n\
88
+ InputUtil.Type.KEYSYM,\n\
89
+ GLFW.GLFW_KEY_H,\n\
90
+ "category.freecam"\n\
91
+ ));\n\
92
+ \n\
93
+ ClientTickEvents.END_CLIENT_TICK.register(client -> {\n\
94
+ if (freecamKey.wasPressed() && client.player != null) {\n\
95
+ if (InputUtil.isKeyPressed(MinecraftClient.getInstance().getWindow().getHandle(), GLFW.GLFW_KEY_LEFT_CONTROL)) {\n\
96
+ toggleFreecam(client);\n\
97
+ }\n\
98
+ }\n\
99
+ });\n\
100
+ }\n\
101
+ \n\
102
+ private void toggleFreecam(MinecraftClient client) {\n\
103
+ if (client.player == null) return;\n\
104
+ \n\
105
+ freecamActive = !freecamActive;\n\
106
+ \n\
107
+ if (freecamActive) {\n\
108
+ savedX = client.player.getX();\n\
109
+ savedY = client.player.getY();\n\
110
+ savedZ = client.player.getZ();\n\
111
+ savedYaw = client.player.getYaw();\n\
112
+ savedPitch = client.player.getPitch();\n\
113
+ client.player.noClip = true;\n\
114
+ } else {\n\
115
+ client.player.setPosition(savedX, savedY, savedZ);\n\
116
+ client.player.setYaw(savedYaw);\n\
117
+ client.player.setPitch(savedPitch);\n\
118
+ client.player.noClip = false;\n\
119
+ }\n\
120
+ }\n\
121
+ }' > src/main/java/com/freecam/mod/FreeCamMod.java
122
+
123
+ # Создание fabric.mod.json
124
+ RUN echo '{\n\
125
+ "schemaVersion": 1,\n\
126
+ "id": "freecam",\n\
127
+ "version": "1.0.0",\n\
128
+ "name": "FreeCam Mod",\n\
129
+ "description": "FreeCam with Ctrl+H",\n\
130
+ "authors": ["Author"],\n\
131
+ "contact": {},\n\
132
+ "license": "MIT",\n\
133
+ "icon": "assets/freecam/icon.png",\n\
134
+ "environment": "client",\n\
135
+ "entrypoints": {\n\
136
+ "client": ["com.freecam.mod.FreeCamMod"]\n\
137
+ },\n\
138
+ "depends": {\n\
139
+ "fabricloader": ">=0.15.0",\n\
140
+ "minecraft": "1.20.1",\n\
141
+ "fabric-api": "*"\n\
142
+ }\n\
143
+ }' > src/main/resources/fabric.mod.json
144
+
145
+ # Установка Gradle
146
+ RUN wget https://services.gradle.org/distributions/gradle-8.5-bin.zip && \
147
+ unzip gradle-8.5-bin.zip && \
148
+ rm gradle-8.5-bin.zip && \
149
+ mv gradle-8.5 /opt/gradle
150
+
151
+ ENV PATH="/opt/gradle/bin:${PATH}"
152
+
153
+ # Сборка мода
154
+ RUN gradle build --no-daemon
155
+
156
+ # Копирование JAR в доступное место
157
+ RUN mkdir -p /app/download && \
158
+ cp build/libs/*.jar /app/download/freecam-mod.jar
159
+
160
+ # Создание простого Python HTTP сервера
161
+ RUN echo 'from http.server import HTTPServer, SimpleHTTPRequestHandler\n\
162
+ import os\n\
163
+ os.chdir("/app/download")\n\
164
+ server = HTTPServer(("0.0.0.0", 7860), SimpleHTTPRequestHandler)\n\
165
+ print("Server running on port 7860")\n\
166
+ server.serve_forever()' > server.py
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
 
 
168
  EXPOSE 7860
169
 
170
+ CMD ["python3", "server.py"]