Skip to content

Commit 6920f72

Browse files
author
XZB-1248
committed
release: v0.2.0
add: zmodem(lrzsz) support for terminal add: update notification (won't auto update) optimize: protocol of terminal and desktop optimize: experience of explorer optimize: github workflow remove: CryptoJS
1 parent 451bff4 commit 6920f72

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+7762
-1060
lines changed

.github/workflows/build.yml

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ jobs:
9191

9292
- name: Build and pack static resources
9393
run: |
94+
export COMMIT=`git rev-parse HEAD`
95+
export VERSION=`git describe --tags | sed 's/^v//'`
96+
sed -i "s/\$COMMIT/$COMMIT/g" ./web/src/config/version.json
97+
sed -i "s/\$VERSION/$VERSION/g" ./web/src/config/version.json
98+
9499
cd ./web
95100
npm install
96101
npm run build-prod
@@ -115,20 +120,20 @@ jobs:
115120
116121
- name: Prepare release note
117122
run: |
118-
wget -q https://1248.ink/Tools/release.js
119-
node release.js ${{ github.ref_name }}
123+
export REF_NAME=`git describe --tags`
124+
node ./scripts/release.js $REF_NAME
120125
121126
- name: Pack releases
122127
run: |
123128
mv ./built ./releases/built
124129
cd ./releases
125-
sudo apt install zip tar -y
126-
tar -zcf server_darwin_arm64.tar.gz server_darwin_arm64 ./built
127-
tar -zcf server_darwin_amd64.tar.gz server_darwin_amd64 ./built
128-
tar -zcf server_linux_arm.tar.gz server_linux_arm ./built
129-
tar -zcf server_linux_i386.tar.gz server_linux_i386 ./built
130-
tar -zcf server_linux_arm64.tar.gz server_linux_arm64 ./built
131-
tar -zcf server_linux_amd64.tar.gz server_linux_amd64 ./built
130+
sudo apt install zip tar pigz -y
131+
tar -cpf server_darwin_arm64.tar.gz server_darwin_arm64 ./built
132+
tar -cpf server_darwin_amd64.tar.gz server_darwin_amd64 ./built
133+
tar -cpf server_linux_arm.tar.gz server_linux_arm ./built
134+
tar -cpf server_linux_i386.tar.gz server_linux_i386 ./built
135+
tar -cpf server_linux_arm64.tar.gz server_linux_arm64 ./built
136+
tar -cpf server_linux_amd64.tar.gz server_linux_amd64 ./built
132137
zip -r -9 -q server_windows_arm.zip server_windows_arm.exe ./built
133138
zip -r -9 -q server_windows_i386.zip server_windows_i386.exe ./built
134139
zip -r -9 -q server_windows_arm64.zip server_windows_arm64.exe ./built
@@ -158,3 +163,9 @@ jobs:
158163
name: |
159164
darwin_arm64
160165
darwin_amd64
166+
167+
- name: Update version info
168+
env:
169+
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
170+
run: |
171+
curl -X POST -H "Authorization: $RELEASE_TOKEN" --retry 10 -m 60 -o /dev/null https://1248.ink/spark/release > /dev/null 2>&1

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
## v0.2.0
2+
3+
* Add: zmodem(lrzsz) support for terminal.
4+
* Add: update notification (won't auto update).
5+
* Optimize: protocol of terminal and desktop.
6+
* Optimize: experience of explorer.
7+
* Remove: CryptoJS.
8+
9+
* 新增:终端支持zmodem协议(lrzsz)。
10+
* 新增:版本更新通知(不会自动更新)。
11+
* 优化:终端和桌面端的通信协议。
12+
* 优化:文件管理器的使用体验。
13+
* 移除:CryptoJS。
14+
15+
16+
117
## v0.1.9
218

319
* Add: special keys for terminal.

LICENSE

Lines changed: 0 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -23,56 +23,3 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2323
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2424
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2525
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26-
27-
-------
28-
29-
utils/melody are copied and modified from olahol/melody.
30-
31-
Copyright (c) 2015 Ola Holmström. All rights reserved.
32-
33-
Redistribution and use in source and binary forms, with or without
34-
modification, are permitted provided that the following conditions are met:
35-
36-
Redistributions of source code must retain the above copyright notice, this
37-
list of conditions and the following disclaimer.
38-
39-
Redistributions in binary form must reproduce the above copyright notice,
40-
this list of conditions and the following disclaimer in the documentation
41-
and/or other materials provided with the distribution.
42-
43-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
44-
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
45-
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
46-
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
47-
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48-
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
49-
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
50-
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
51-
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52-
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53-
54-
-------
55-
56-
utils/cmap are copied and modified from orcaman/concurrent-map.
57-
58-
The MIT License (MIT)
59-
60-
Copyright (c) 2014 streamrail
61-
62-
Permission is hereby granted, free of charge, to any person obtaining a copy
63-
of this software and associated documentation files (the "Software"), to deal
64-
in the Software without restriction, including without limitation the rights
65-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
66-
copies of the Software, and to permit persons to whom the Software is
67-
furnished to do so, subject to the following conditions:
68-
69-
The above copyright notice and this permission notice shall be included in all
70-
copies or substantial portions of the Software.
71-
72-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
73-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
74-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
75-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
76-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
77-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
78-
SOFTWARE.

client/common/common.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"Spark/client/config"
55
"Spark/modules"
66
"Spark/utils"
7+
"encoding/binary"
78
"encoding/hex"
89
"errors"
910
ws "github.com/gorilla/websocket"
@@ -73,6 +74,25 @@ func (wsConn *Conn) SendPack(pack any) error {
7374
return wsConn.WriteMessage(ws.BinaryMessage, data)
7475
}
7576

77+
func (wsConn *Conn) SendRawData(event, data []byte, service byte, op byte) error {
78+
Mutex.Lock()
79+
defer Mutex.Unlock()
80+
if WSConn == nil {
81+
return errors.New(`${i18n|COMMON.DISCONNECTED}`)
82+
}
83+
buffer := make([]byte, 24)
84+
copy(buffer[6:22], event)
85+
copy(buffer[:4], []byte{34, 22, 19, 17})
86+
buffer[4] = service
87+
buffer[5] = op
88+
binary.BigEndian.PutUint16(buffer[22:24], uint16(len(data)))
89+
buffer = append(buffer, data...)
90+
91+
wsConn.SetWriteDeadline(utils.Now.Add(5 * time.Second))
92+
defer wsConn.SetWriteDeadline(time.Time{})
93+
return wsConn.WriteMessage(ws.BinaryMessage, buffer)
94+
}
95+
7696
func (wsConn *Conn) SendCallback(pack, prev modules.Packet) error {
7797
if len(prev.Event) > 0 {
7898
pack.Event = prev.Event

client/core/core.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,18 @@ func handleWS(wsConn *common.Conn) error {
161161
golog.Error(err)
162162
return nil
163163
}
164+
if service, op, isBinary := utils.CheckBinaryPack(data); isBinary && len(data) > 24 {
165+
event := hex.EncodeToString(data[6:22])
166+
switch service {
167+
case 20:
168+
case 21:
169+
switch op {
170+
case 0:
171+
inputRawTerminal(data[24:], event)
172+
}
173+
}
174+
continue
175+
}
164176
data, err = utils.Decrypt(data, wsConn.GetSecret())
165177
if err != nil {
166178
golog.Error(err)

client/core/device.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -179,16 +179,16 @@ func GetDevice() (*modules.Device, error) {
179179
}
180180
localIP, err := GetLocalIP()
181181
if err != nil {
182-
localIP = `unknown`
182+
localIP = `<unknown>`
183183
}
184184
macAddr, err := GetMacAddress()
185185
if err != nil {
186-
macAddr = `unknown`
186+
macAddr = `<unknown>`
187187
}
188188
cpuInfo, err := GetCPUInfo()
189189
if err != nil {
190190
cpuInfo = modules.CPU{
191-
Model: `unknown`,
191+
Model: `<unknown>`,
192192
Usage: 0,
193193
}
194194
}
@@ -221,11 +221,11 @@ func GetDevice() (*modules.Device, error) {
221221
}
222222
hostname, err := os.Hostname()
223223
if err != nil {
224-
hostname = `unknown`
224+
hostname = `<unknown>`
225225
}
226226
username, err := user.Current()
227227
if err != nil {
228-
username = &user.User{Username: `unknown`}
228+
username = &user.User{Username: `<unknown>`}
229229
} else {
230230
slashIndex := strings.Index(username.Username, `\`)
231231
if slashIndex > -1 && slashIndex+1 < len(username.Username) {
@@ -252,7 +252,7 @@ func GetPartialInfo() (*modules.Device, error) {
252252
cpuInfo, err := GetCPUInfo()
253253
if err != nil {
254254
cpuInfo = modules.CPU{
255-
Model: `unknown`,
255+
Model: `<unknown>`,
256256
Usage: 0,
257257
}
258258
}

client/core/handler.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,3 +370,7 @@ func execCommand(pack modules.Packet, wsConn *common.Conn) {
370370
proc.Process.Release()
371371
}
372372
}
373+
374+
func inputRawTerminal(pack []byte, event string) {
375+
terminal.InputRawTerminal(pack, event)
376+
}

client/service/desktop/desktop.go

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,22 @@ type message struct {
3333
frame *[]*[]byte
3434
}
3535

36-
// +---------+---------+----------+----------+------------+---------+---------+---------+---------+-------+
37-
// | magic | OP code | event id | img type | img length | x | y | width | height | image |
38-
// +---------+---------+----------+----------+------------+---------+---------+---------+---------+-------+
39-
// | 5 bytes | 1 byte | 16 bytes | 2 bytes | 2 bytes | 2 bytes | 2 bytes | 2 bytes | 2 bytes | - |
40-
// +---------+---------+----------+----------+------------+---------+---------+---------+---------+-------+
36+
// packet explanation:
37+
38+
// +---------+---------+----------+-------------+----------+---------+---------+---------+---------+-------+
39+
// | magic | op code | event id | body length | img type | x | y | width | height | image |
40+
// +---------+---------+----------+-------------+----------+---------+---------+---------+---------+-------+
41+
// | 5 bytes | 1 byte | 16 bytes | 2 bytes | 2 bytes | 2 bytes | 2 bytes | 2 bytes | 2 bytes | - |
42+
// +---------+---------+----------+-------------+----------+---------+---------+---------+---------+-------+
4143

4244
// magic:
4345
// []byte{34, 22, 19, 17, 20}
4446

45-
// OP code:
46-
// 00: first part of a frame
47-
// 01: rest parts of a frame
48-
// 02: set resolution of every frame
49-
// 03: JSON string (only for server)
47+
// op code:
48+
// 00: first part of a frame, device -> browser
49+
// 01: rest parts of a frame, device -> browser
50+
// 02: set resolution of every frame, device -> browser
51+
// 03: JSON string, server -> browser
5052

5153
// img type:
5254
// 0: raw image
@@ -167,12 +169,12 @@ func imageCompare(img, prev *image.RGBA, compress bool) []*[]byte {
167169
for _, rect := range diff {
168170
block := getImageBlock(img, rect, compress)
169171
buf := make([]byte, 12)
172+
binary.BigEndian.PutUint16(buf[0:2], uint16(len(block)+10))
170173
if compress {
171-
binary.BigEndian.PutUint16(buf[0:2], uint16(1))
174+
binary.BigEndian.PutUint16(buf[2:4], uint16(1))
172175
} else {
173-
binary.BigEndian.PutUint16(buf[0:2], uint16(0))
176+
binary.BigEndian.PutUint16(buf[2:4], uint16(0))
174177
}
175-
binary.BigEndian.PutUint16(buf[2:4], uint16(len(block)))
176178
binary.BigEndian.PutUint16(buf[4:6], uint16(rect.Min.X))
177179
binary.BigEndian.PutUint16(buf[6:8], uint16(rect.Min.Y))
178180
binary.BigEndian.PutUint16(buf[8:10], uint16(rect.Size().X))
@@ -197,12 +199,12 @@ func splitFullImage(img *image.RGBA, compress bool) []*[]byte {
197199
width := utils.If(x+blockSize > imgWidth, imgWidth-x, blockSize)
198200
block := getImageBlock(img, image.Rect(x, y, x+width, y+height), compress)
199201
buf := make([]byte, 12)
202+
binary.BigEndian.PutUint16(buf[0:2], uint16(len(block)+10))
200203
if compress {
201-
binary.BigEndian.PutUint16(buf[0:2], uint16(1))
204+
binary.BigEndian.PutUint16(buf[2:4], uint16(1))
202205
} else {
203-
binary.BigEndian.PutUint16(buf[0:2], uint16(0))
206+
binary.BigEndian.PutUint16(buf[2:4], uint16(0))
204207
}
205-
binary.BigEndian.PutUint16(buf[2:4], uint16(len(block)))
206208
binary.BigEndian.PutUint16(buf[4:6], uint16(x))
207209
binary.BigEndian.PutUint16(buf[6:8], uint16(y))
208210
binary.BigEndian.PutUint16(buf[8:10], uint16(width))
@@ -318,7 +320,9 @@ func InitDesktop(pack modules.Packet) error {
318320
if screenshot.NumActiveDisplays() == 0 {
319321
if displayBounds.Dx() == 0 || displayBounds.Dy() == 0 {
320322
close(desktop.channel)
321-
common.WSConn.SendCallback(modules.Packet{Act: `DESKTOP_QUIT`, Msg: `${i18n|DESKTOP.NO_DISPLAY_FOUND}`}, pack)
323+
data, _ := utils.JSON.Marshal(modules.Packet{Act: `DESKTOP_QUIT`, Msg: `${i18n|DESKTOP.NO_DISPLAY_FOUND}`})
324+
data = utils.XOR(data, common.WSConn.GetSecret())
325+
common.WSConn.SendRawData(desktop.rawEvent, data, 20, 03)
322326
return errors.New(`${i18n|DESKTOP.NO_DISPLAY_FOUND}`)
323327
}
324328
}
@@ -368,11 +372,13 @@ func KillDesktop(pack modules.Packet) {
368372
desktop = val.(*session)
369373
}
370374
sessions.Remove(uuid)
375+
data, _ := utils.JSON.Marshal(modules.Packet{Act: `DESKTOP_QUIT`, Msg: `${i18n|DESKTOP.SESSION_CLOSED}`})
376+
data = utils.XOR(data, common.WSConn.GetSecret())
377+
common.WSConn.SendRawData(desktop.rawEvent, data, 20, 03)
371378
desktop.lock.Lock()
372379
desktop.escape = true
373380
desktop.rawEvent = nil
374381
desktop.lock.Unlock()
375-
common.WSConn.SendCallback(modules.Packet{Act: `DESKTOP_QUIT`, Msg: `${i18n|DESKTOP.SESSION_CLOSED}`}, pack)
376382
}
377383

378384
func GetDesktop(pack modules.Packet) {
@@ -404,7 +410,9 @@ func handleDesktop(pack modules.Packet, uuid string, desktop *session) {
404410
case msg, ok := <-desktop.channel:
405411
// send error info
406412
if msg.t == 1 || !ok {
407-
common.WSConn.SendCallback(modules.Packet{Act: `DESKTOP_QUIT`, Msg: msg.info}, pack)
413+
data, _ := utils.JSON.Marshal(modules.Packet{Act: `DESKTOP_QUIT`, Msg: msg.info})
414+
data = utils.XOR(data, common.WSConn.GetSecret())
415+
common.WSConn.SendRawData(desktop.rawEvent, data, 20, 03)
408416
desktop.escape = true
409417
sessions.Remove(uuid)
410418
break
@@ -428,9 +436,10 @@ func handleDesktop(pack modules.Packet, uuid string, desktop *session) {
428436
// set resolution
429437
if msg.t == 2 {
430438
buf := append([]byte{34, 22, 19, 17, 20, 02}, desktop.rawEvent...)
431-
data := make([]byte, 4)
432-
binary.BigEndian.PutUint16(data[:2], uint16(displayBounds.Dx()))
433-
binary.BigEndian.PutUint16(data[2:], uint16(displayBounds.Dy()))
439+
data := make([]byte, 6)
440+
binary.BigEndian.PutUint16(data[:2], 4)
441+
binary.BigEndian.PutUint16(data[2:4], uint16(displayBounds.Dx()))
442+
binary.BigEndian.PutUint16(data[4:6], uint16(displayBounds.Dy()))
434443
buf = append(buf, data...)
435444
common.WSConn.SendData(buf)
436445
break

client/service/terminal/terminal.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,19 @@ var (
1010
errDataNotFound = errors.New(`no input found in packet`)
1111
errDataInvalid = errors.New(`can not parse data in packet`)
1212
errUUIDNotFound = errors.New(`can not find terminal identifier`)
13-
)
13+
)
14+
15+
// packet explanation:
16+
17+
// +---------+---------+----------+-------------+------+
18+
// | magic | op code | event id | data length | data |
19+
// +---------+---------+----------+-------------+------+
20+
// | 5 bytes | 1 byte | 16 bytes | 2 bytes | - |
21+
// +---------+---------+----------+-------------+------+
22+
23+
// magic:
24+
// []byte{34, 22, 19, 17, 21}
25+
26+
// op code:
27+
// 00: binary packet
28+
// 01: JSON packet

0 commit comments

Comments
 (0)