Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
mycard
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
syntax_j
mycard
Commits
b1aeea39
Commit
b1aeea39
authored
Dec 08, 2016
by
wudizhanche1000
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
修改更新
parent
ff7bf7d1
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
172 additions
and
39 deletions
+172
-39
app/app-detail.component.html
app/app-detail.component.html
+1
-1
app/app-detail.component.ts
app/app-detail.component.ts
+4
-0
app/apps.service.ts
app/apps.service.ts
+166
-37
app/download.service.ts
app/download.service.ts
+1
-1
No files found.
app/app-detail.component.html
View file @
b1aeea39
...
@@ -76,7 +76,7 @@
...
@@ -76,7 +76,7 @@
</div>
</div>
<h2
i18n
>
本地文件
</h2>
<h2
i18n
>
本地文件
</h2>
<button
i18n
(click)=
"appsService.browse(currentApp)"
type=
"button"
class=
"btn btn-secondary"
>
浏览本地文件
</button>
<button
i18n
(click)=
"appsService.browse(currentApp)"
type=
"button"
class=
"btn btn-secondary"
>
浏览本地文件
</button>
<button
i18n
type=
"button"
class=
"btn btn-secondary"
>
校验完整性
</button>
<button
i18n
type=
"button"
(click)=
"verifyFiles(currentApp)"
class=
"btn btn-secondary"
>
校验完整性
</button>
<button
i18n
(click)=
"uninstall(currentApp)"
type=
"button"
class=
"btn btn-secondary"
>
卸载
</button>
<button
i18n
(click)=
"uninstall(currentApp)"
type=
"button"
class=
"btn btn-secondary"
>
卸载
</button>
</div>
</div>
...
...
app/app-detail.component.ts
View file @
b1aeea39
...
@@ -145,6 +145,10 @@ export class AppDetailComponent implements OnInit {
...
@@ -145,6 +145,10 @@ export class AppDetailComponent implements OnInit {
this
.
appsService
.
runApp
(
app
,
'
custom
'
);
this
.
appsService
.
runApp
(
app
,
'
custom
'
);
}
}
verifyFiles
(
app
:
App
)
{
this
.
appsService
.
verifyFiles
(
app
);
}
copy
(
text
:
string
)
{
copy
(
text
:
string
)
{
clipboard
.
writeText
(
text
);
clipboard
.
writeText
(
text
);
}
}
...
...
app/apps.service.ts
View file @
b1aeea39
import
{
Injectable
,
ApplicationRef
,
EventEmitter
}
from
"
@angular/core
"
;
import
{
Injectable
,
ApplicationRef
,
EventEmitter
}
from
"
@angular/core
"
;
import
{
Http
}
from
"
@angular/http
"
;
import
{
Http
}
from
"
@angular/http
"
;
import
*
as
crypto
from
"
crypto
"
;
import
{
App
,
AppStatus
,
Action
}
from
"
./app
"
;
import
{
App
,
AppStatus
,
Action
}
from
"
./app
"
;
import
{
SettingsService
}
from
"
./settings.sevices
"
;
import
{
SettingsService
}
from
"
./settings.sevices
"
;
import
*
as
fs
from
"
fs
"
;
import
*
as
fs
from
"
fs
"
;
...
@@ -246,40 +247,168 @@ export class AppsService {
...
@@ -246,40 +247,168 @@ export class AppsService {
return
apps
;
return
apps
;
};
};
async
update
(
app
:
App
)
{
sha256sum
(
file
:
string
):
Promise
<
string
>
{
const
updateServer
=
"
https://thief.mycard.moe/update/metalinks/
"
;
return
new
Promise
((
resolve
,
reject
)
=>
{
if
(
app
.
isReady
()
&&
app
.
local
!
.
version
!==
app
.
version
)
{
let
input
=
fs
.
createReadStream
(
file
);
const
hash
=
crypto
.
createHash
(
"
sha256
"
);
hash
.
on
(
"
error
"
,
(
error
:
Error
)
=>
{
reject
(
error
)
});
input
.
on
(
"
error
"
,
(
error
:
Error
)
=>
{
reject
(
error
);
});
hash
.
on
(
'
readable
'
,
()
=>
{
let
data
=
hash
.
read
();
if
(
data
)
{
resolve
((
<
Buffer
>
data
).
toString
(
"
hex
"
));
}
});
input
.
pipe
(
hash
);
});
}
async
verifyFiles
(
app
:
App
)
{
if
(
app
.
isReady
())
{
app
.
status
.
status
=
"
updating
"
;
app
.
status
.
status
=
"
updating
"
;
let
updateMetalink
=
updateServer
+
app
.
id
;
Logger
.
info
(
"
Start to verify files:
"
,
app
);
if
(
app
.
id
===
"
ygopro
"
||
app
.
id
===
"
desmume
"
)
{
let
lastedFile
=
await
this
.
getChecksumFile
(
app
);
updateMetalink
=
updateMetalink
+
'
-
'
+
process
.
platform
;
let
changedList
:
string
[]
=
[];
for
(
let
[
file
,
checksum
]
of
lastedFile
)
{
let
absolutePath
=
path
.
join
(
app
.
local
!
.
path
,
file
);
await
new
Promise
((
resolve
,
reject
)
=>
{
fs
.
access
(
absolutePath
,
fs
.
constants
.
F_OK
,
(
err
)
=>
{
if
(
err
)
{
changedList
.
push
(
file
);
}
}
resolve
();
});
});
if
(
checksum
!==
""
)
{
let
c
=
await
this
.
sha256sum
(
file
);
if
(
c
!==
checksum
)
{
changedList
.
push
(
file
);
}
}
}
await
this
.
doUpdate
(
app
,
changedList
);
app
.
status
.
status
=
"
ready
"
;
}
}
async
update
(
app
:
App
)
{
let
readyToUpdate
:
boolean
=
false
;
// 已经安装的mod
let
mods
=
this
.
findChildren
(
app
).
filter
((
mod
)
=>
{
return
mod
.
parent
===
app
&&
mod
.
isInstalled
();
});
// 如果是不是mod,那么要所有已经安装mod都ready
// 如果是mod,那么要parent ready
if
(
app
.
parent
&&
app
.
parent
.
isReady
())
{
readyToUpdate
=
true
;
}
else
{
readyToUpdate
=
mods
.
every
((
mod
)
=>
{
return
mod
.
isReady
();
})
}
if
(
readyToUpdate
&&
app
.
local
!
.
version
!==
app
.
version
)
{
app
.
status
.
status
=
"
updating
"
;
Logger
.
info
(
"
Checking updating:
"
,
app
);
Logger
.
info
(
"
Checking updating:
"
,
app
);
let
latestFiles
=
await
this
.
getChecksumFile
(
app
);
let
latestFiles
=
await
this
.
getChecksumFile
(
app
);
let
localFiles
=
app
.
local
!
.
files
;
let
localFiles
=
app
.
local
!
.
files
;
let
changedFiles
:
string
[]
=
[]
;
let
changedFiles
:
Set
<
string
>
=
new
Set
<
string
>
()
;
let
deletedFiles
:
string
[]
=
[]
;
let
deletedFiles
:
Set
<
string
>
=
new
Set
<
string
>
()
;
for
(
let
[
file
,
checksum
]
of
latestFiles
)
{
for
(
let
[
file
,
checksum
]
of
latestFiles
)
{
if
(
!
localFiles
.
has
(
file
))
{
if
(
!
localFiles
.
has
(
file
))
{
changedFiles
.
push
(
file
);
changedFiles
.
add
(
file
);
}
}
}
}
for
(
let
[
file
,
checksum
]
of
localFiles
)
{
for
(
let
[
file
,
checksum
]
of
localFiles
)
{
if
(
latestFiles
.
has
(
file
))
{
if
(
latestFiles
.
has
(
file
))
{
if
(
latestFiles
.
get
(
file
)
!==
checksum
)
{
if
(
latestFiles
.
get
(
file
)
!==
checksum
)
{
changedFiles
.
push
(
file
);
changedFiles
.
add
(
file
);
}
}
}
else
{
}
else
{
deletedFiles
.
push
(
file
);
deletedFiles
.
add
(
file
);
}
}
let
backupFiles
:
string
[]
=
[];
let
restoreFiles
:
string
[]
=
[];
if
(
app
.
parent
)
{
let
parentFiles
=
app
.
parent
.
local
!
.
files
;
// 添加的文件和parent冲突,且不是目录,就添加到conflict列表
for
(
let
changedFile
of
changedFiles
)
{
if
(
parentFiles
.
has
(
changedFile
)
&&
parentFiles
.
get
(
changedFile
)
!==
""
)
{
backupFiles
.
push
(
changedFile
);
}
}
}
}
//如果要删除的文件parent里也有就恢复这个文件
for
(
let
deletedFile
of
deletedFiles
)
{
restoreFiles
.
push
(
deletedFile
);
}
if
(
changedFiles
.
length
>
0
)
{
let
backupDir
=
path
.
join
(
path
.
dirname
(
app
.
local
!
.
path
),
"
backup
"
,
app
.
parent
.
id
);
Logger
.
info
(
"
Found files changed:
"
,
changedFiles
);
await
this
.
backupFiles
(
app
.
local
!
.
path
,
backupDir
,
backupFiles
);
let
metalink
=
await
this
.
http
.
post
(
updateMetalink
,
changedFiles
).
map
((
response
)
=>
response
.
text
()).
toPromise
();
await
this
.
restoreFiles
(
app
.
local
!
.
path
,
backupDir
,
restoreFiles
);
let
library
=
path
.
dirname
(
app
.
local
!
.
path
);
}
else
{
let
downloadId
=
await
this
.
downloadService
.
addMetalink
(
metalink
,
library
);
for
(
let
mod
of
mods
)
{
await
this
.
downloadService
.
progress
(
downloadId
,
(
status
:
DownloadStatus
)
=>
{
// 如果changed列表与已经安装的mod有冲突,就push到back列表里
for
(
let
changedFile
of
changedFiles
)
{
if
(
mod
.
local
!
.
files
.
has
(
changedFile
))
{
backupFiles
.
push
(
changedFile
);
}
}
// 如果要删除的文件,mod里面存在,就不要删除这个文件
for
(
let
deletedFile
of
deletedFiles
)
{
if
(
mod
.
local
!
.
files
.
has
(
deletedFile
))
{
deletedFiles
.
delete
(
deletedFile
);
}
}
let
backupDir
=
path
.
join
(
path
.
dirname
(
app
.
local
!
.
path
),
"
mods_backup
"
,
app
.
id
);
}
}
// 筛选更新文件中与mod冲突的部分
for
(
let
mod
of
installedMods
)
{
changedFiles
.
forEach
((
changedFile
)
=>
{
if
(
mod
.
local
!
.
files
.
has
(
changedFile
))
{
conflictFiles
.
add
(
changedFile
);
}
});
deletedFiles
.
forEach
((
deletedFile
)
=>
{
if
(
mod
.
local
!
.
files
.
has
(
deletedFile
))
{
deletedFiles
.
delete
(
deletedFile
);
}
})
}
await
this
.
doUpdate
(
app
,
changedFiles
,
deletedFiles
);
app
.
local
!
.
version
=
app
.
version
;
app
.
local
!
.
files
=
latestFiles
;
this
.
saveAppLocal
(
app
);
app
.
status
.
status
=
"
ready
"
;
installedMods
.
forEach
((
mod
)
=>
mod
.
status
.
status
=
"
ready
"
);
Logger
.
info
(
"
Update Finished:
"
,
app
);
}
}
async
doUpdate
(
app
:
App
,
changedFiles
?:
Set
<
string
>
,
deletedFiles
?:
Set
<
string
>
)
{
const
updateServer
=
"
https://thief.mycard.moe/update/metalinks/
"
;
if
(
changedFiles
&&
changedFiles
.
size
>
0
)
{
Logger
.
info
(
"
Update changed files:
"
,
changedFiles
);
let
updateUrl
=
updateServer
+
app
.
id
;
if
(
app
.
id
===
"
ygopro
"
||
app
.
id
===
"
desmume
"
)
{
updateUrl
=
updateUrl
+
'
-
'
+
process
.
platform
;
}
let
metalink
=
await
this
.
http
.
post
(
updateUrl
,
changedFiles
).
map
((
response
)
=>
response
.
text
()).
toPromise
();
let
downloadDir
=
path
.
join
(
path
.
dirname
(
app
.
local
!
.
path
),
"
downloading
"
);
let
downloadId
=
await
this
.
downloadService
.
addMetalink
(
metalink
,
downloadDir
);
await
this
.
downloadService
.
progress
(
downloadId
,
(
status
:
DownloadStatus
)
=>
{
app
.
status
.
progress
=
status
.
completedLength
;
app
.
status
.
progress
=
status
.
completedLength
;
app
.
status
.
total
=
status
.
totalLength
;
app
.
status
.
total
=
status
.
totalLength
;
app
.
status
.
progressMessage
=
status
.
downloadSpeedText
;
app
.
status
.
progressMessage
=
status
.
downloadSpeedText
;
...
@@ -298,18 +427,12 @@ export class AppsService {
...
@@ -298,18 +427,12 @@ export class AppsService {
});
});
}
}
}
}
if
(
deletedFiles
.
length
>
0
)
{
if
(
deletedFiles
&&
deletedFiles
.
size
>
0
)
{
Logger
.
info
(
"
Found files deleted:
"
,
deletedFiles
);
Logger
.
info
(
"
Found files deleted:
"
,
deletedFiles
);
for
(
let
deletedFile
of
deletedFiles
)
{
for
(
let
deletedFile
of
deletedFiles
)
{
await
this
.
deleteFile
(
path
.
join
(
app
.
local
!
.
path
,
deletedFile
));
await
this
.
deleteFile
(
path
.
join
(
app
.
local
!
.
path
,
deletedFile
));
}
}
}
}
app
.
local
!
.
version
=
app
.
version
;
app
.
local
!
.
files
=
latestFiles
;
this
.
saveAppLocal
(
app
);
app
.
status
.
status
=
"
ready
"
;
Logger
.
info
(
"
Update Finished:
"
,
app
);
}
}
}
async
install
(
app
:
App
,
option
:
InstallOption
)
{
async
install
(
app
:
App
,
option
:
InstallOption
)
{
...
@@ -614,6 +737,12 @@ export class AppsService {
...
@@ -614,6 +737,12 @@ export class AppsService {
let
conflictFiles
=
appFiles
.
intersection
(
parentFiles
);
let
conflictFiles
=
appFiles
.
intersection
(
parentFiles
);
if
(
conflictFiles
.
size
>
0
)
{
if
(
conflictFiles
.
size
>
0
)
{
let
backupPath
=
path
.
join
(
option
.
installLibrary
,
"
backup
"
,
app
.
parent
.
id
);
let
backupPath
=
path
.
join
(
option
.
installLibrary
,
"
backup
"
,
app
.
parent
.
id
);
// 文件夹不需要备份,删除
for
(
let
conflictFile
of
conflictFiles
)
{
if
(
checksumFile
.
get
(
conflictFile
)
===
''
)
{
conflictFiles
.
delete
(
conflictFile
);
}
}
await
this
.
backupFiles
(
app
.
parent
.
local
!
.
path
,
backupPath
,
conflictFiles
);
await
this
.
backupFiles
(
app
.
parent
.
local
!
.
path
,
backupPath
,
conflictFiles
);
}
}
}
}
...
...
app/download.service.ts
View file @
b1aeea39
...
@@ -23,7 +23,7 @@ export class DownloadStatus {
...
@@ -23,7 +23,7 @@ export class DownloadStatus {
downloadSpeed
:
number
;
downloadSpeed
:
number
;
get
downloadSpeedText
():
string
{
get
downloadSpeedText
():
string
{
if
(
!
isNaN
(
this
.
downloadSpeed
))
{
if
(
!
isNaN
(
this
.
downloadSpeed
)
&&
this
.
downloadSpeed
!==
0
)
{
const
speedUnit
=
[
"
Byte/s
"
,
"
KB/s
"
,
"
MB/s
"
,
"
GB/s
"
,
"
TB/s
"
];
const
speedUnit
=
[
"
Byte/s
"
,
"
KB/s
"
,
"
MB/s
"
,
"
GB/s
"
,
"
TB/s
"
];
let
currentUnit
=
Math
.
floor
(
Math
.
log
(
this
.
downloadSpeed
)
/
Math
.
log
(
1024
));
let
currentUnit
=
Math
.
floor
(
Math
.
log
(
this
.
downloadSpeed
)
/
Math
.
log
(
1024
));
return
(
this
.
downloadSpeed
/
1024
**
currentUnit
).
toFixed
(
1
)
+
"
"
+
speedUnit
[
currentUnit
];
return
(
this
.
downloadSpeed
/
1024
**
currentUnit
).
toFixed
(
1
)
+
"
"
+
speedUnit
[
currentUnit
];
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment