Skip to content

Commit

Permalink
feat: universal drop import
Browse files Browse the repository at this point in the history
  • Loading branch information
ci010 committed Oct 23, 2020
1 parent 9c2f6f5 commit 5b2b8b4
Show file tree
Hide file tree
Showing 16 changed files with 903 additions and 14 deletions.
73 changes: 71 additions & 2 deletions src/main/service/ResourceService.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { copyPassively, readdirEnsured, sha1 } from '@main/util/fs';
import { commitResourceOnDisk, createResourceBuilder, decorateBuilderFromMetadata, decorateBuilderFromStat, decorateBuilderSourceUrls, decorateBuilderWithPathAndHash, discardResourceOnDisk, getBuilderFromResource, getCurseforgeUrl, getResourceFromBuilder, parseResource, Resource, ResourceBuilder, ResourceRegistryEntry, RESOURCE_ENTRY_FABRIC, RESOURCE_ENTRY_FORGE, RESOURCE_ENTRY_LITELOADER, RESOURCE_ENTRY_MODPACK, RESOURCE_ENTRY_RESOURCE_PACK, RESOURCE_ENTRY_SAVE, SourceInfomation, UNKNOWN_RESOURCE } from '@main/util/resource';
import { commitResourceOnDisk, createResourceBuilder, decorateBuilderFromMetadata, decorateBuilderFromStat, decorateBuilderSourceUrls, decorateBuilderWithPathAndHash, discardResourceOnDisk, getBuilderFromResource, getCurseforgeUrl, getResourceFromBuilder, parseResource, Resource, ResourceBuilder, ResourceRegistryEntry, RESOURCE_ENTRY_FABRIC, RESOURCE_ENTRY_FORGE, RESOURCE_ENTRY_LITELOADER, RESOURCE_ENTRY_MODPACK, RESOURCE_ENTRY_RESOURCE_PACK, RESOURCE_ENTRY_SAVE, SourceInfomation, UNKNOWN_RESOURCE, RESOURCE_ENTRY_COMMON_MODPACK } from '@main/util/resource';
import { CurseforgeSource, ResourceSchema } from '@universal/store/modules/resource.schema';
import { requireString } from '@universal/util/assert';
import { Task, task } from '@xmcl/task';
import { readFile, stat, writeFile } from 'fs-extra';
import { extname, join } from 'path';
import { extname, join, basename } from 'path';
import fileType, { FileTypeResult, FileType } from 'file-type';
import Service from './Service';

export type BuiltinType = 'forge' | 'fabric' | 'resourcepack' | 'save' | 'curseforge-modpack';
export type ImportTypeHint = string | '*' | 'mods' | 'forge' | 'fabric' | 'resourcepack' | 'liteloader' | 'curseforge-modpack' | 'save';
export type ImportOption = {
/**
Expand All @@ -26,6 +28,16 @@ export type ImportOption = {

background?: boolean;
}
export interface ParseFilesOptions {
files: { path: string; hint?: ImportTypeHint; size?: number }[];
}
export interface ParseFileResult {
path: string;
type: BuiltinType | 'modpack' | 'unknown' | 'directory';
fileType: FileType | 'unknown' | 'directory';
resource: Resource;
existed: boolean;
}

export interface Query {
hash?: string;
Expand All @@ -40,6 +52,7 @@ export default class ResourceService extends Service {

constructor() {
super();
this.registerResourceType(RESOURCE_ENTRY_COMMON_MODPACK);
this.registerResourceType(RESOURCE_ENTRY_FORGE);
this.registerResourceType(RESOURCE_ENTRY_LITELOADER);
this.registerResourceType(RESOURCE_ENTRY_FABRIC);
Expand Down Expand Up @@ -239,6 +252,62 @@ export default class ResourceService extends Service {
await Promise.all(promises);
}

async parseFileAsResource(options: ParseFilesOptions): Promise<ParseFileResult[]> {
const { files } = options;
return Promise.all(files.map(async (file) => {
const { path, hint } = file;
let data: Buffer | undefined;
let hash: string | undefined;
let fileStat = await stat(path);
if (fileStat.isDirectory()) {
return { path, resource: UNKNOWN_RESOURCE, type: 'directory', existed: false } as ParseFileResult;
}
let resource: Resource | undefined;
let ino = fileStat.ino;
resource = this.getResourceByKey(ino);
if (!resource) {
data = await readFile(path);
hash = sha1(data);
resource = this.getResourceByKey(hash);
}
// resource existed
if (resource) {
return { type: resource.type, resource, path, fileType: resource.ext, existed: true } as ParseFileResult;
}

if (!data) {
data = await readFile(path);
}
if (!hash) {
hash = sha1(data);
}
const type: FileType | 'unknown' = fileType(data)?.ext ?? 'unknown';

if (type === 'zip') {
let builder = createResourceBuilder({});
decorateBuilderWithPathAndHash(builder, path, hash);
decorateBuilderFromStat(builder, fileStat);
await this.updateBuilderMetadata(builder, data, hint);
resource = getResourceFromBuilder(builder);
return {
path,
type: resource.type,
fileType: type,
resource,
existed: false,
} as ParseFileResult;
}

return {
path,
type: 'unknown',
existed: false,
fileType: type ?? extname(path),
resource: UNKNOWN_RESOURCE,
} as ParseFileResult;
}));
}

// bridge from dry function to `this` context

/**
Expand Down
Binary file added src/renderer/assets/fabric.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 7 additions & 5 deletions src/renderer/assets/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@
},
"download": "Download",
"downloadUpdate": "Downloading Update",
"dropToImport": "Drop File(s) Here to Import as",
"edit": "Edit",
"error": {
"empty": "No error yet",
Expand Down Expand Up @@ -524,7 +525,8 @@
"backToAllMods": "Back to All Mods",
"compatible": "Compatible Mod.",
"deletion": "Deleting Mod",
"deletionHint": "You will lose this mod & its metadata forever. Are you sure you want to delete it?",
"deletionHint": "You will lose this mod & its metadata forever. Are you sure you want to delete it? | You will lose these mod & these metadata forever. Are you sure you want to do that?",
"deletionRestHint": "And {rest} more Mods...",
"export": "Export Mod",
"hideIncompatible": "Hide Incompatible Mods",
"hint": "Drop mod's .jar/.litemod here to import.",
Expand Down Expand Up @@ -578,6 +580,7 @@
},
"forceLocalVersion": "Launch by Selected Local Version",
"forgeSetting": "Forge Settings",
"gameVersion": "Game Version",
"import": {
"description": "Import Minecraft to Launcher",
"start": "Import Started",
Expand Down Expand Up @@ -615,12 +618,12 @@
"export": "Export as Modpack",
"exportCurseforge": "Export Curseforge Modpack",
"general": "General Information",
"name": "Modpack | Modpacks",
"includeLibraries": "Include Libraries",
"includeAssets": "Include Assets",
"includeLibraries": "Include Libraries",
"includeVersion": "Include Version | Include Versions",
"overrides": "overrides",
"includes": "Files to includes",
"name": "Modpack | Modpacks",
"overrides": "overrides",
"profile": "Profile Name"
},
"name": "Profile Name",
Expand Down Expand Up @@ -680,7 +683,6 @@
"today": "Today",
"url": "URL",
"version": "Selected Version",
"gameVersion": "Game Version",
"versionHint": "The Minecraft version of this game",
"versionSetting": "Version Setting",
"vmOptions": "JVM Options",
Expand Down
9 changes: 6 additions & 3 deletions src/renderer/assets/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@
}
},
"downloadUpdate": "下载更新",
"dropToImport": "将文件拖到这并导入为",
"edit": "编辑",
"fabric": {
"disable": "不启用 Fabric",
Expand Down Expand Up @@ -505,7 +506,8 @@
"backToAllMods": "返回所有 Mods",
"compatible": "可用于当前版本。",
"deletion": "删除 Mod",
"deletionHint": "你将失去这个 Mod 的文件和信息。你确定吗?",
"deletionHint": "你将移除这个 Mod 的文件和信息。你确定吗?| 你将移除这些 Mod 的文件和信息。你确定吗?",
"deletionRestHint": "等 {rest} 个模组……",
"export": "导出 Mod",
"hideIncompatible": "隐藏不兼容 Mods",
"hint": "将Mod的jar文件拖入此处来导入",
Expand All @@ -526,6 +528,7 @@
"nocompatible": "无法解析兼容性。",
"openLink": "打开 Mod 链接 {url}",
"searchOnCurseforge": "在 Curseforge 上搜索该 Mod",
"searchOnMcWiki": "在 MC 百科中查找 {name}",
"selected": "已选 Mods",
"showFile": "打开 Mod 所在位置 {file}",
"showInCurseforge": "在 Curseforge 上显示该 Mod",
Expand Down Expand Up @@ -601,9 +604,9 @@
"includeAssets": "是否包含游戏资源 (assets) 文件",
"includeLibraries": "是否包含库文件",
"includeVersion": "包含游戏版本",
"name": "Mod包",
"overrides": "整合包打包覆盖 (overrides)",
"includes": "打包文件",
"name": "整合包",
"overrides": "整合包打包覆盖 (overrides)",
"profile": "文件名"
},
"name": "名称",
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/hooks/useResource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useStore } from './useStore';

export function useResourceOperation() {
return {
...useServiceOnly('ResourceService', 'importResource', 'removeResource'),
...useServiceOnly('ResourceService', 'importResource', 'removeResource', 'parseFileAsResource'),
};
}

Expand Down
3 changes: 2 additions & 1 deletion src/renderer/windows/main/MainWindow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
dark
style="background: transparent;"
>
<universal-drop-view />
<v-container
v-if="loading"
color="primary"
Expand Down Expand Up @@ -46,7 +47,6 @@
<router-view />
<!-- </keep-alive> -->
</transition>
<!-- </v-card> -->
</div>
</v-layout>
<context-menu />
Expand Down Expand Up @@ -116,6 +116,7 @@ export default defineComponent({
const data = reactive({
loading: true,
over: false,
});
function refreshImage() {
Expand Down
4 changes: 2 additions & 2 deletions src/renderer/windows/main/components/CurseforgeIcon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default {
</script>

<style>
#curseforge-icon {
fill: currentColor;
#curseforge-icon .st0 {
fill: white;
}
</style>
12 changes: 12 additions & 0 deletions src/renderer/windows/main/components/FabricIcon.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<template>
<img :src="fabric" width="24">
</template>

<script lang="ts">
import { defineComponent, ref, onMounted } from '@vue/composition-api';
import fabric from '@/assets/fabric.png';
export default defineComponent({
setup() { return { fabric }; },
});
</script>
70 changes: 70 additions & 0 deletions src/renderer/windows/main/components/ForgeIcon.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<template>
<svg
id="Ebene_1"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px"
y="0px"
viewBox="0 0 316 66.7"
style="enable-background:new 0 0 316 66.7;"
xml:space="preserve"
>
<g>
<g>
<polygon
class="st0"
points="114.1,55.6 125,55.6 125,38.7 143,38.7 143,28.4 125,28.4 125,21.4 144.1,21.4 144.1,11.1
114.1,11.1 "
/>
<path
class="st0"
d="M185.3,16.3c-2.1-2.1-4.6-3.6-7.5-4.7c-2.7-1-5.8-1.5-9-1.5l-0.4,0c-3.4,0-6.5,0.6-9.3,1.7
c-2.9,1.1-5.4,2.7-7.4,4.8c-2.1,2.1-3.7,4.6-4.9,7.5c-1.2,2.9-1.7,6.1-1.7,9.6c0,3.4,0.6,6.6,1.8,9.4c1.2,2.8,2.8,5.3,4.9,7.3
c2.1,2,4.6,3.6,7.4,4.7c2.8,1.1,6,1.7,9.3,1.7h0h0c3.4,0,6.6-0.6,9.4-1.8c2.9-1.1,5.4-2.8,7.5-4.8c2.1-2,3.7-4.5,4.9-7.4
c1.2-2.8,1.8-6,1.8-9.4c0-3.5-0.6-6.7-1.7-9.6C189,20.9,187.3,18.4,185.3,16.3z M180.6,33.1c0,2-0.3,3.8-0.9,5.4
c-0.6,1.6-1.4,3-2.5,4.2c-1,1.1-2.3,2.1-3.8,2.7c-1.5,0.7-3.2,1-5,1c-1.8,0-3.5-0.3-5-1c-1.5-0.7-2.7-1.6-3.8-2.7
c-1.1-1.2-1.9-2.6-2.5-4.2c-0.6-1.6-0.9-3.5-0.9-5.4c0-1.8,0.3-3.5,0.9-5c0.6-1.5,1.4-2.9,2.5-4c1-1.1,2.3-2,3.8-2.7
c1.5-0.6,3.1-1,5-1c1.8,0,3.5,0.3,5,1c1.5,0.6,2.8,1.5,3.8,2.7c1.1,1.1,1.9,2.5,2.5,4C180.3,29.6,180.6,31.3,180.6,33.1z"
/>
<path
class="st0"
d="M224.2,33.3c1.9-2.3,2.9-5.2,2.9-8.6c0-2.6-0.5-4.8-1.5-6.6c-1-1.8-2.4-3.2-4-4.2c-1.6-1-3.4-1.7-5.5-2.1
c-1.9-0.4-4-0.6-6-0.6h-16v44.5h11V38.3h2.3l9.4,17.3h13.1l-11.2-18.6C220.9,36.2,222.8,35,224.2,33.3z M204.9,21h4.4
c0.8,0,1.7,0.1,2.6,0.2c0.8,0.1,1.5,0.3,2.1,0.6c0.5,0.2,0.9,0.6,1.2,1c0.3,0.4,0.4,1,0.4,1.8c0,0.9-0.2,1.6-0.5,2.1
c-0.3,0.5-0.8,0.8-1.3,1c-0.7,0.3-1.5,0.5-2.3,0.6c-1,0.1-2,0.1-2.9,0.1h-3.8V21z"
/>
<path
class="st0"
d="M242.7,24c1-1.1,2.3-2,3.8-2.7c1.5-0.6,3.1-1,5-1c1.8,0,3.6,0.3,5.3,0.9c1.6,0.6,3,1.4,4.1,2.5l1.3,1.3l8-8.1
l-1.5-1.3c-2.4-2.1-5.1-3.6-8.1-4.4c-2.9-0.8-6-1.2-9.2-1.2c-3.4,0-6.5,0.6-9.3,1.7c-2.9,1.1-5.4,2.7-7.4,4.8
c-2.1,2.1-3.7,4.6-4.9,7.5c-1.2,2.9-1.7,6.1-1.7,9.6c0,3.4,0.6,6.6,1.8,9.4c1.2,2.8,2.8,5.3,4.9,7.3c2.1,2,4.6,3.6,7.4,4.7
c2.8,1.1,6,1.7,9.3,1.7c6.5,0,12.5-1.4,17.8-4.3l1-0.5V28h-19.3v10.3h8.4V45c-0.9,0.4-1.8,0.7-2.9,0.9c-1.5,0.3-3.1,0.5-4.8,0.5
c-1.8,0-3.5-0.3-5-1c-1.5-0.7-2.7-1.6-3.8-2.7c-1.1-1.2-1.9-2.6-2.5-4.2c-0.6-1.6-0.9-3.5-0.9-5.4c0-1.8,0.3-3.5,0.9-5
C240.9,26.5,241.7,25.1,242.7,24z"
/>
<polygon
class="st0"
points="285.6,45.3 285.6,38 304.3,38 304.3,27.7 285.6,27.7 285.6,21.4 305.4,21.4 305.4,11.1 274.6,11.1
274.6,55.6 306.4,55.6 306.4,45.3 "
/>
</g>
<path
class="st1"
d="M91.6,16.7l-37.8-1.9l46.2,0v-3.7H47.8l0,7.8v6.2c0,0.1-1.5-9.1-1.9-11.7h-4.1v6.8v6.2
c0,0.1-1.8-10.9-1.9-12.3c-10.4,0-27.9,0-27.9,0c1.9,1.6,12.4,10.6,19.9,14.3c3.7,1.8,8.3,1.9,12.4,2c2.1,0.1,4.2,0.2,5.8,1.8
c2.3,2.2,2.8,5.7,0.8,8.3c-1.9,2.6-7.3,3.2-7.3,3.2L39,49.1v6.4h10.3l0.3-6.3l8.9-6.3c-0.9,0.8-3.1,2.8-6.2,7.7
c-0.7,1.1-1.3,2.3-1.7,3.5c2.2-1.9,6.8-3.2,12.2-3.2c5.3,0,9.9,1.3,12.1,3.2c-0.4-1.2-1-2.4-1.7-3.5c-3.2-4.9-5.3-6.9-6.2-7.7
l8.9,6.3l0.3,6.3h9.6v-6.4l-4.5-5.5c0,0-6.7-0.4-8.4-3.2C67.7,32.6,74.8,20.4,91.6,16.7z"
/>
</g>
</svg>
</template>
<style type="text/css">
.st0 {
fill: #dfa86a;
}
.st1 {
fill: #faf4f3;
}
</style>
40 changes: 40 additions & 0 deletions src/renderer/windows/main/components/JarFileIcon.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 32 32"
>
<title>file_type_jar</title>
<path
d="M12.7,23.56s-1.07.622.761.833a16.023,16.023,0,0,0,5.8-.246A10.088,10.088,0,0,0,20.8,24.9c-5.481,2.349-12.405-.136-8.1-1.339"
style="fill:#5382a1"
/>
<path
d="M12.026,20.494s-1.2.888.633,1.078a22.618,22.618,0,0,0,7.481-.359,3.32,3.32,0,0,0,1.152.7c-6.627,1.938-14.009.153-9.266-1.421"
style="fill:#5382a1"
/>
<path
d="M17.673,15.294a2.051,2.051,0,0,1-.355,2.954s3.429-1.77,1.854-3.987c-1.471-2.067-2.6-3.095,3.508-6.636,0,0-9.586,2.394-5.007,7.669"
style="fill:#e76f00"
/>
<path
d="M24.922,25.827s.792.652-.872,1.157c-3.164.958-13.168,1.248-15.948.038-1-.435.874-1.038,1.464-1.164a3.8,3.8,0,0,1,.966-.108c-1.111-.783-7.181,1.537-3.083,2.2,11.176,1.812,20.372-.816,17.473-2.124"
style="fill:#5382a1"
/>
<path
d="M13.211,17.318s-5.089,1.209-1.8,1.648a38.225,38.225,0,0,0,6.731-.072c2.106-.178,4.221-.555,4.221-.555a8.934,8.934,0,0,0-1.28.685C15.913,20.382,5.93,19.75,8.8,18.359a9.629,9.629,0,0,1,4.407-1.042"
style="fill:#5382a1"
/>
<path
d="M22.34,22.421c5.253-2.73,2.824-5.353,1.129-5a3.932,3.932,0,0,0-.6.161.957.957,0,0,1,.449-.346c3.354-1.179,5.933,3.478-1.083,5.322a.458.458,0,0,0,.106-.138"
style="fill:#5382a1"
/>
<path
d="M19.172,1.906s2.909,2.91-2.759,7.386c-4.546,3.59-1.037,5.637,0,7.975-2.653-2.394-4.6-4.5-3.294-6.463,1.917-2.879,7.229-4.275,6.056-8.9"
style="fill:#e76f00"
/>
<path
d="M13.727,29.818c5.042.323,12.786-.179,12.969-2.565,0,0-.353.9-4.167,1.623a41.458,41.458,0,0,1-12.76.2s.645.533,3.959.746"
style="fill:#5382a1"
/>
</svg>
</template>
35 changes: 35 additions & 0 deletions src/renderer/windows/main/components/PackageFileIcon.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 32 32"
>
<title>file_type_package</title>
<path
d="M7.61,3.093c2.078-.019,4.159,0,6.238-.008-.493,2.123-.966,4.252-1.457,6.376q-4.745,0-9.491,0c-.3,0-.6.01-.9-.012C3.864,7.325,5.749,5.219,7.61,3.093Z"
style="fill:#f2e6c9"
/>
<path
d="M18.163,3.086q3.109,0,6.22,0C26.251,5.212,28.137,7.32,30,9.449c-1.2.025-2.4,0-3.6.011q-3.4,0-6.795,0C19.133,7.333,18.629,5.214,18.163,3.086Z"
style="fill:#f2e6c9"
/>
<path
d="M13.848,3.086q2.158,0,4.315,0c.466,2.128.969,4.247,1.444,6.373-2.405,0-4.811,0-7.216,0C12.882,7.337,13.355,5.209,13.848,3.086Z"
style="fill:#efc75e"
/>
<path
d="M2,9.448c.3.022.6.011.9.012q4.745,0,9.491,0c0,2.245,0,4.49.007,6.735a2.44,2.44,0,0,0,.256.018q3.372,0,6.743,0c.067,0,.134-.007.2-.014.019-2.247,0-4.494.009-6.741q3.4,0,6.795,0c1.2-.006,2.4.014,3.6-.011q0,9.732,0,19.466-14,0-28,0Q2,19.181,2,9.448Z"
style="fill:#e7bf55"
/>
<path
d="M12.391,9.462c2.405,0,4.811,0,7.216,0-.008,2.247.011,4.494-.009,6.741-.067.007-.134.012-.2.014q-3.372,0-6.743,0A2.44,2.44,0,0,1,12.4,16.2C12.386,13.952,12.4,11.706,12.391,9.462Z"
style="fill:#dbb551"
/>
<rect
x="4.044"
y="22.581"
width="9.37"
height="3.608"
style="fill:#f2f2f2"
/>
</svg>
</template>
Loading

0 comments on commit 5b2b8b4

Please sign in to comment.